1 /*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #include <stdint.h>
33 #include <string.h>
34 #include <unistd.h>
35 #ifdef HAVE_SYS_SELECT_H
36 #include <sys/select.h>
37 #endif
38
39 #include <drm_fourcc.h>
40
41 #include "util/pattern.h"
42 #include "libkms-test.h"
43
signal_handler(int signum)44 static void signal_handler(int signum)
45 {
46 }
47
main(int argc,char * argv[])48 int main(int argc, char *argv[])
49 {
50 struct kms_framebuffer *fb;
51 struct kms_screen *screen;
52 struct kms_device *device;
53 unsigned int index = 0;
54 struct sigaction sa;
55 int fd, err;
56 void *ptr;
57
58 if (argc < 2) {
59 fprintf(stderr, "usage: %s DEVICE\n", argv[0]);
60 return 1;
61 }
62
63 memset(&sa, 0, sizeof(sa));
64 sa.sa_handler = signal_handler;
65
66 err = sigaction(SIGINT, &sa, NULL);
67 if (err < 0) {
68 fprintf(stderr, "sigaction() failed: %m\n");
69 return 1;
70 }
71
72 fd = open(argv[1], O_RDWR);
73 if (fd < 0) {
74 fprintf(stderr, "open() failed: %m\n");
75 return 1;
76 }
77
78 device = kms_device_open(fd);
79 if (!device) {
80 fprintf(stderr, "kms_device_open() failed: %m\n");
81 return 1;
82 }
83
84 if (device->num_screens < 1) {
85 fprintf(stderr, "no screens found\n");
86 kms_device_close(device);
87 close(fd);
88 return 1;
89 }
90
91 /* TODO: allow command-line to override */
92 screen = device->screens[0];
93
94 printf("Using screen %s, resolution %ux%u\n", screen->name,
95 screen->width, screen->height);
96
97 fb = kms_framebuffer_create(device, screen->width, screen->height,
98 DRM_FORMAT_XRGB8888);
99 if (!fb) {
100 fprintf(stderr, "kms_framebuffer_create() failed\n");
101 return 1;
102 }
103
104 err = kms_framebuffer_map(fb, &ptr);
105 if (err < 0) {
106 fprintf(stderr, "kms_framebuffer_map() failed: %d\n", err);
107 return 1;
108 }
109
110 util_fill_pattern(fb->format, UTIL_PATTERN_SMPTE, &ptr, fb->width,
111 fb->height, fb->pitch);
112
113 kms_framebuffer_unmap(fb);
114
115 err = kms_screen_set(screen, device->crtcs[index++], fb);
116 if (err < 0) {
117 fprintf(stderr, "kms_screen_set() failed: %d\n", err);
118 return 1;
119 }
120
121 while (true) {
122 int nfds = STDIN_FILENO + 1;
123 struct timeval timeout;
124 fd_set fds;
125
126 memset(&timeout, 0, sizeof(timeout));
127 timeout.tv_sec = 5;
128 timeout.tv_usec = 0;
129
130 FD_ZERO(&fds);
131 FD_SET(STDIN_FILENO, &fds);
132
133 err = select(nfds, &fds, NULL, NULL, &timeout);
134 if (err < 0) {
135 if (errno == EINTR)
136 break;
137
138 fprintf(stderr, "select() failed: %d\n", errno);
139 break;
140 }
141
142 if (err > 0) {
143 if (FD_ISSET(STDIN_FILENO, &fds))
144 break;
145 }
146
147 /* switch CRTC */
148 if (index >= device->num_crtcs)
149 index = 0;
150
151 err = kms_screen_set(screen, device->crtcs[index], fb);
152 if (err < 0) {
153 fprintf(stderr, "kms_screen_set() failed: %d\n", err);
154 break;
155 }
156
157 index++;
158 }
159
160 kms_framebuffer_free(fb);
161 kms_device_close(device);
162 close(fd);
163
164 return 0;
165 }
166