xref: /netbsd-src/sbin/wsconsctl/display.c (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1 /*	$NetBSD: display.c,v 1.17 2021/12/25 13:54:13 mlelstv Exp $ */
2 
3 /*-
4  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Juergen Hannken-Illjes.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/ioctl.h>
33 #include <sys/time.h>
34 
35 #include <dev/wscons/wsconsio.h>
36 
37 #include <err.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 #include "wsconsctl.h"
44 
45 static int border;
46 static int dpytype;
47 static struct wsdisplay_usefontdata font;
48 static struct wsdisplay_param backlight;
49 static struct wsdisplay_param brightness;
50 static struct wsdisplay_param contrast;
51 static struct wsdisplay_scroll_data scroll_l;
52 static struct wsdisplayio_edid_info edid_info;
53 static uint8_t edid_buf[256];
54 static int msg_default_attrs, msg_default_bg, msg_default_fg;
55 static int msg_kernel_attrs, msg_kernel_bg, msg_kernel_fg;
56 static int splash_enable, splash_progress;
57 
58 struct field display_field_tab[] = {
59     { "border",			&border,	FMT_COLOR,	0 },
60     { "type",			&dpytype,	FMT_DPYTYPE,	FLG_RDONLY },
61     { "font",			&font.name,	FMT_STRING,	FLG_WRONLY },
62     { "backlight",		&backlight.curval,  FMT_UINT,	0 },
63     { "brightness",		&brightness.curval, FMT_UINT,	FLG_MODIFY },
64     { "contrast",		&contrast.curval,   FMT_UINT,	FLG_MODIFY },
65     { "scroll.fastlines",	&scroll_l.fastlines, FMT_UINT,	FLG_MODIFY },
66     { "scroll.slowlines",	&scroll_l.slowlines, FMT_UINT,	FLG_MODIFY },
67     { "edid",			&edid_info, FMT_EDID,		FLG_RDONLY|FLG_NOAUTO },
68     { "msg.default.attrs",	&msg_default_attrs, FMT_ATTRS,	0 },
69     { "msg.default.bg",		&msg_default_bg, FMT_COLOR,	0 },
70     { "msg.default.fg",		&msg_default_fg, FMT_COLOR,	0 },
71     { "msg.kernel.attrs",	&msg_kernel_attrs, FMT_ATTRS,	0 },
72     { "msg.kernel.bg",		&msg_kernel_bg, FMT_COLOR,	0 },
73     { "msg.kernel.fg",		&msg_kernel_fg, FMT_COLOR,	0 },
74     { "splash.enable",		&splash_enable, FMT_UINT,	FLG_WRONLY },
75     { "splash.progress",	&splash_progress, FMT_UINT,	FLG_WRONLY },
76 };
77 
78 int display_field_tab_len = sizeof(display_field_tab) /
79 	sizeof(display_field_tab[0]);
80 
81 void
82 display_get_values(int fd)
83 {
84 
85 	if (field_by_value(&dpytype)->flags & FLG_GET)
86 		if (ioctl(fd, WSDISPLAYIO_GTYPE, &dpytype) < 0)
87 			err(EXIT_FAILURE, "WSDISPLAYIO_GTYPE");
88 
89 	if (field_by_value(&border)->flags & FLG_GET)
90 		if (ioctl(fd, WSDISPLAYIO_GBORDER, &border) < 0)
91 			field_disable_by_value(&border);
92 
93 	if (field_by_value(&backlight.curval)->flags & FLG_GET) {
94 		backlight.param = WSDISPLAYIO_PARAM_BACKLIGHT;
95 		if (ioctl(fd, WSDISPLAYIO_GETPARAM, &backlight) < 0)
96 			field_disable_by_value(&backlight.curval);
97 	}
98 
99 	if (field_by_value(&brightness.curval)->flags & FLG_GET) {
100 		brightness.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
101 		if (ioctl(fd, WSDISPLAYIO_GETPARAM, &brightness))
102 			field_disable_by_value(&brightness.curval);
103 	}
104 
105 	if (field_by_value(&contrast.curval)->flags & FLG_GET) {
106 		contrast.param = WSDISPLAYIO_PARAM_CONTRAST;
107 		if (ioctl(fd, WSDISPLAYIO_GETPARAM, &contrast))
108 			field_disable_by_value(&contrast.curval);
109 	}
110 
111 	if (field_by_value(&msg_default_attrs)->flags & FLG_GET ||
112 	    field_by_value(&msg_default_bg)->flags & FLG_GET ||
113 	    field_by_value(&msg_default_fg)->flags & FLG_GET ||
114 	    field_by_value(&msg_kernel_attrs)->flags & FLG_GET ||
115 	    field_by_value(&msg_kernel_bg)->flags & FLG_GET ||
116 	    field_by_value(&msg_kernel_fg)->flags & FLG_GET) {
117 		struct wsdisplay_msgattrs ma;
118 
119 		if (ioctl(fd, WSDISPLAYIO_GMSGATTRS, &ma) < 0) {
120 			field_disable_by_value(&msg_default_attrs);
121 			field_disable_by_value(&msg_default_bg);
122 			field_disable_by_value(&msg_default_fg);
123 			field_disable_by_value(&msg_kernel_attrs);
124 			field_disable_by_value(&msg_kernel_bg);
125 			field_disable_by_value(&msg_kernel_fg);
126 		} else {
127 			msg_default_attrs = ma.default_attrs;
128 			if (ma.default_attrs & WSATTR_WSCOLORS) {
129 				msg_default_bg = ma.default_bg;
130 				msg_default_fg = ma.default_fg;
131 			} else
132 				msg_default_bg = msg_default_fg = -1;
133 
134 			msg_kernel_attrs = ma.kernel_attrs;
135 			if (ma.kernel_attrs & WSATTR_WSCOLORS) {
136 				msg_kernel_bg = ma.kernel_bg;
137 				msg_kernel_fg = ma.kernel_fg;
138 			} else
139 				msg_kernel_bg = msg_kernel_fg = -1;
140 		}
141 	}
142 
143 	if (field_by_value(&scroll_l.fastlines)->flags & FLG_GET ||
144 	    field_by_value(&scroll_l.slowlines)->flags & FLG_GET) {
145 		if (ioctl(fd, WSDISPLAYIO_DGSCROLL, &scroll_l) < 0) {
146 			field_disable_by_value(&scroll_l.fastlines);
147 			field_disable_by_value(&scroll_l.slowlines);
148 		}
149 	}
150 
151 	if (field_by_value(&edid_info)->flags & FLG_GET) {
152 		edid_info.edid_data = edid_buf;
153 		edid_info.buffer_size = sizeof(edid_buf);
154 		if (ioctl(fd, WSDISPLAYIO_GET_EDID, &edid_info) < 0) {
155 			field_disable_by_value(&edid_info);
156 		}
157 	}
158 }
159 
160 void
161 display_put_values(int fd)
162 {
163 
164 	if (field_by_value(&font.name)->flags & FLG_SET) {
165 		if (ioctl(fd, WSDISPLAYIO_SFONT, &font) < 0)
166 			err(EXIT_FAILURE, "WSDISPLAYIO_SFONT");
167 		pr_field(field_by_value(&font.name), " -> ");
168 	}
169 
170 	if (field_by_value(&border)->flags & FLG_SET) {
171 		if (ioctl(fd, WSDISPLAYIO_SBORDER, &border) < 0)
172 			err(EXIT_FAILURE, "WSDISPLAYIO_SBORDER");
173 		pr_field(field_by_value(&border), " -> ");
174 	}
175 
176 	if (field_by_value(&backlight.curval)->flags & FLG_SET) {
177 		backlight.param = WSDISPLAYIO_PARAM_BACKLIGHT;
178 		if (ioctl(fd, WSDISPLAYIO_SETPARAM, &backlight) < 0)
179 			err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_BACKLIGHT");
180 		pr_field(field_by_value(&backlight.curval), " -> ");
181 	}
182 
183 	if (field_by_value(&brightness.curval)->flags & FLG_SET) {
184 		brightness.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
185 		if (ioctl(fd, WSDISPLAYIO_SETPARAM, &brightness) < 0)
186 			err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_BRIGHTNESS");
187 		pr_field(field_by_value(&brightness.curval), " -> ");
188 	}
189 
190 	if (field_by_value(&contrast.curval)->flags & FLG_SET) {
191 		contrast.param = WSDISPLAYIO_PARAM_CONTRAST;
192 		if (ioctl(fd, WSDISPLAYIO_SETPARAM, &contrast) < 0)
193 			err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_CONTRAST");
194 		pr_field(field_by_value(&contrast.curval), " -> ");
195 	}
196 
197 	if (field_by_value(&splash_enable)->flags & FLG_SET) {
198 		if (ioctl(fd, WSDISPLAYIO_SSPLASH, &splash_enable) < 0)
199 			err(EXIT_FAILURE, "WSDISPLAYIO_SSPLASH");
200 		pr_field(field_by_value(&splash_enable), " -> ");
201 	}
202 
203 	if (field_by_value(&splash_progress)->flags & FLG_SET) {
204 		if (ioctl(fd, WSDISPLAYIO_SPROGRESS, &splash_progress) < 0)
205 			err(EXIT_FAILURE, "WSDISPLAYIO_SPROGRESS");
206 		pr_field(field_by_value(&splash_progress), " -> ");
207 	}
208 
209 	if (field_by_value(&msg_default_attrs)->flags & FLG_SET ||
210 	    field_by_value(&msg_default_bg)->flags & FLG_SET ||
211 	    field_by_value(&msg_default_fg)->flags & FLG_SET ||
212 	    field_by_value(&msg_kernel_attrs)->flags & FLG_SET ||
213 	    field_by_value(&msg_kernel_bg)->flags & FLG_SET ||
214 	    field_by_value(&msg_kernel_fg)->flags & FLG_SET) {
215 		struct wsdisplay_msgattrs ma;
216 
217 		if (ioctl(fd, WSDISPLAYIO_GMSGATTRS, &ma) < 0)
218 			err(EXIT_FAILURE, "WSDISPLAYIO_GMSGATTRS");
219 
220 		if (field_by_value(&msg_default_attrs)->flags & FLG_SET) {
221 			ma.default_attrs = msg_default_attrs;
222 			pr_field(field_by_value(&msg_default_attrs), " -> ");
223 		}
224 		if (ma.default_attrs & WSATTR_WSCOLORS) {
225 			if (field_by_value(&msg_default_bg)->flags & FLG_SET) {
226 				ma.default_bg = msg_default_bg;
227 				pr_field(field_by_value(&msg_default_bg),
228 				    " -> ");
229 			}
230 			if (field_by_value(&msg_default_fg)->flags & FLG_SET) {
231 				ma.default_fg = msg_default_fg;
232 				pr_field(field_by_value(&msg_default_fg),
233 				    " -> ");
234 			}
235 		}
236 
237 		if (field_by_value(&msg_kernel_attrs)->flags & FLG_SET) {
238 			ma.kernel_attrs = msg_kernel_attrs;
239 			pr_field(field_by_value(&msg_kernel_attrs), " -> ");
240 		}
241 		if (ma.default_attrs & WSATTR_WSCOLORS) {
242 			if (field_by_value(&msg_kernel_bg)->flags & FLG_SET) {
243 				ma.kernel_bg = msg_kernel_bg;
244 				pr_field(field_by_value(&msg_kernel_bg),
245 				    " -> ");
246 			}
247 			if (field_by_value(&msg_kernel_fg)->flags & FLG_SET) {
248 				ma.kernel_fg = msg_kernel_fg;
249 				pr_field(field_by_value(&msg_kernel_fg),
250 				    " -> ");
251 			}
252 		}
253 
254 		if (ioctl(fd, WSDISPLAYIO_SMSGATTRS, &ma) < 0)
255 			err(EXIT_FAILURE, "WSDISPLAYIO_SMSGATTRS");
256 	}
257 
258 	scroll_l.which = 0;
259 	if (field_by_value(&scroll_l.fastlines)->flags & FLG_SET)
260 		scroll_l.which |= WSDISPLAY_SCROLL_DOFASTLINES;
261 	if (field_by_value(&scroll_l.slowlines)->flags & FLG_SET)
262 		scroll_l.which |= WSDISPLAY_SCROLL_DOSLOWLINES;
263 	if (scroll_l.which != 0 &&
264 	    ioctl(fd, WSDISPLAYIO_DSSCROLL, &scroll_l) < 0)
265 		err(EXIT_FAILURE, "WSDISPLAYIO_DSSCROLL");
266 	if (scroll_l.which & WSDISPLAY_SCROLL_DOFASTLINES)
267 		pr_field(field_by_value(&scroll_l.fastlines), " -> ");
268 	if (scroll_l.which & WSDISPLAY_SCROLL_DOSLOWLINES)
269 		pr_field(field_by_value(&scroll_l.slowlines), " -> ");
270 }
271