Add packaging
[platform/upstream/kmscon.git] / tests / test_output.c
1 /*
2  * test_output - Test KMS/DRI output
3  *
4  * Copyright (c) 2011-2012 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 any argument it will enable all outputs for 5seconds.
32  *
33  * This lists all outputs:
34  * $ ./test_output
35  *
36  * This would show a test screen:
37  * $ ./test_output something
38  */
39
40 static void print_help();
41
42 #include <errno.h>
43 #include <inttypes.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48
49 #include "eloop.h"
50 #include "shl_log.h"
51 #include "uterm_video.h"
52 #include "test_include.h"
53
54 /* eloop object */
55 static struct ev_eloop *eloop;
56
57 struct {
58         bool fbdev;
59         bool test;
60         char *dev;
61 } output_conf;
62
63 static int blit_outputs(struct uterm_video *video)
64 {
65         struct uterm_display *iter;
66         int j, ret;
67         struct uterm_mode *mode;
68
69         j = 0;
70         iter = uterm_video_get_displays(video);
71         for ( ; iter; iter = uterm_display_next(iter)) {
72                 log_notice("Activating display %d %p...", j, iter);
73                 ret = uterm_display_activate(iter, NULL);
74                 if (ret)
75                         log_err("Cannot activate display %d: %d", j, ret);
76                 else
77                         log_notice("Successfully activated display %d", j);
78
79                 ret = uterm_display_set_dpms(iter, UTERM_DPMS_ON);
80                 if (ret)
81                         log_err("Cannot set DPMS to ON: %d", ret);
82
83                 ++j;
84         }
85
86         iter = uterm_video_get_displays(video);
87         for ( ; iter; iter = uterm_display_next(iter)) {
88                 if (uterm_display_get_state(iter) != UTERM_DISPLAY_ACTIVE)
89                         continue;
90
91                 mode = uterm_display_get_current(iter);
92                 ret = uterm_display_fill(iter, 0xff, 0xff, 0xff, 0, 0,
93                                          uterm_mode_get_width(mode),
94                                          uterm_mode_get_height(mode));
95                 if (ret) {
96                         log_err("cannot fill framebuffer");
97                         continue;
98                 }
99
100                 ret = uterm_display_swap(iter, true);
101                 if (ret) {
102                         log_err("Cannot swap screen: %d", ret);
103                         continue;
104                 }
105
106                 log_notice("Successfully set screen on display %p", iter);
107         }
108
109         log_notice("Waiting 5 seconds...");
110         ev_eloop_run(eloop, 5000);
111         log_notice("Exiting...");
112
113         return 0;
114 }
115
116 static int list_outputs(struct uterm_video *video)
117 {
118         struct uterm_display *iter;
119         struct uterm_mode *cur, *mode;
120         int i;
121
122         log_notice("List of Outputs:");
123
124         i = 0;
125         iter = uterm_video_get_displays(video);
126         for ( ; iter; iter = uterm_display_next(iter)) {
127                 cur = uterm_display_get_current(iter);
128
129                 log_notice("Output %d:", i++);
130                 log_notice("  active: %d", uterm_display_get_state(iter));
131                 log_notice("  has current: %s", cur ? "yes" : "no");
132
133                 mode = uterm_display_get_modes(iter);
134                 for ( ; mode; mode = uterm_mode_next(mode)) {
135                         log_notice("  Mode '%s':", uterm_mode_get_name(mode));
136                         log_notice("    x: %u", uterm_mode_get_width(mode));
137                         log_notice("    y: %u", uterm_mode_get_height(mode));
138                 }
139         }
140
141         log_notice("End of Output list");
142
143         return 0;
144 }
145
146 static void print_help()
147 {
148         /*
149          * Usage/Help information
150          * This should be scaled to a maximum of 80 characters per line:
151          *
152          * 80 char line:
153          *       |   10   |    20   |    30   |    40   |    50   |    60   |    70   |    80   |
154          *      "12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
155          * 80 char line starting with tab:
156          *       |10|    20   |    30   |    40   |    50   |    60   |    70   |    80   |
157          *      "\t901234567890123456789012345678901234567890123456789012345678901234567890\n"
158          */
159         fprintf(stderr,
160                 "Usage:\n"
161                 "\t%1$s [options]\n"
162                 "\t%1$s -h [options]\n"
163                 "\n"
164                 "You can prefix boolean options with \"no-\" to negate it. If an argument is\n"
165                 "given multiple times, only the last argument matters if not otherwise stated.\n"
166                 "\n"
167                 "General Options:\n"
168                 TEST_HELP
169                 "\n"
170                 "Video Options:\n"
171                 "\t    --fbdev                 [off]   Use fbdev instead of DRM\n"
172                 "\t    --test                  [off]   Try displaying content instead of listing devices\n"
173                 "\t    --dev                   [/dev/dri/card0 | /dev/fb0] Use the given device\n",
174                 "test_input");
175         /*
176          * 80 char line:
177          *       |   10   |    20   |    30   |    40   |    50   |    60   |    70   |    80   |
178          *      "12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
179          * 80 char line starting with tab:
180          *       |10|    20   |    30   |    40   |    50   |    60   |    70   |    80   |
181          *      "\t901234567890123456789012345678901234567890123456789012345678901234567890\n"
182          */
183 }
184
185 struct conf_option options[] = {
186         TEST_OPTIONS,
187         CONF_OPTION_BOOL(0, "fbdev", &output_conf.fbdev, false),
188         CONF_OPTION_BOOL(0, "test", &output_conf.test, false),
189         CONF_OPTION_STRING(0, "dev",  &output_conf.dev, NULL),
190 };
191
192 int main(int argc, char **argv)
193 {
194         struct uterm_video *video;
195         int ret;
196         const char *node;
197         const struct uterm_video_module *mode;
198         size_t onum;
199
200         onum = sizeof(options) / sizeof(*options);
201         ret = test_prepare(options, onum, argc, argv, &eloop);
202         if (ret)
203                 goto err_fail;
204
205         if (output_conf.fbdev) {
206                 mode = UTERM_VIDEO_FBDEV;
207                 node = "/dev/fb0";
208         } else {
209                 mode = UTERM_VIDEO_DRM3D;
210                 node = "/dev/dri/card0";
211         }
212
213         if (output_conf.dev)
214                 node = output_conf.dev;
215
216         log_notice("Creating video object using %s...", node);
217
218         ret = uterm_video_new(&video, eloop, node, mode);
219         if (ret) {
220                 if (mode == UTERM_VIDEO_DRM3D) {
221                         log_notice("cannot create drm device; trying drm2d mode");
222                         ret = uterm_video_new(&video, eloop, node,
223                                               UTERM_VIDEO_DRM2D);
224                         if (ret)
225                                 goto err_exit;
226                 } else {
227                         goto err_exit;
228                 }
229         }
230
231         log_notice("Wakeing up video object...");
232         ret = uterm_video_wake_up(video);
233         if (ret < 0)
234                 goto err_unref;
235
236         if (!output_conf.test) {
237                 ret = list_outputs(video);
238                 if (ret) {
239                         log_err("Cannot list outputs: %d", ret);
240                         goto err_unref;
241                 }
242         } else {
243                 ret = blit_outputs(video);
244                 if (ret) {
245                         log_err("Cannot set outputs: %d", ret);
246                         goto err_unref;
247                 }
248         }
249
250 err_unref:
251         uterm_video_unref(video);
252 err_exit:
253         test_exit(options, onum, eloop);
254 err_fail:
255         if (ret != -ECANCELED)
256                 test_fail(ret);
257         return abs(ret);
258 }