xref: /netbsd-src/sbin/wsconsctl/display.c (revision 7d8ccb8ed09fff77ff0a670e8a7472737206e9e9)
1*7d8ccb8eSmlelstv /*	$NetBSD: display.c,v 1.19 2024/10/20 13:49:41 mlelstv Exp $ */
204ee2eceShannken 
304ee2eceShannken /*-
4ea287a80Sjmmv  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
504ee2eceShannken  * All rights reserved.
604ee2eceShannken  *
704ee2eceShannken  * This code is derived from software contributed to The NetBSD Foundation
804ee2eceShannken  * by Juergen Hannken-Illjes.
904ee2eceShannken  *
1004ee2eceShannken  * Redistribution and use in source and binary forms, with or without
1104ee2eceShannken  * modification, are permitted provided that the following conditions
1204ee2eceShannken  * are met:
1304ee2eceShannken  * 1. Redistributions of source code must retain the above copyright
1404ee2eceShannken  *    notice, this list of conditions and the following disclaimer.
1504ee2eceShannken  * 2. Redistributions in binary form must reproduce the above copyright
1604ee2eceShannken  *    notice, this list of conditions and the following disclaimer in the
1704ee2eceShannken  *    documentation and/or other materials provided with the distribution.
1804ee2eceShannken  *
1904ee2eceShannken  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2004ee2eceShannken  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2104ee2eceShannken  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2204ee2eceShannken  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2304ee2eceShannken  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2404ee2eceShannken  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2504ee2eceShannken  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2604ee2eceShannken  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2704ee2eceShannken  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2804ee2eceShannken  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2904ee2eceShannken  * POSSIBILITY OF SUCH DAMAGE.
3004ee2eceShannken  */
3104ee2eceShannken 
3204ee2eceShannken #include <sys/ioctl.h>
3304ee2eceShannken #include <sys/time.h>
3467ec0248Schristos 
3567ec0248Schristos #include <dev/wscons/wsconsio.h>
3667ec0248Schristos 
37c799a9c4Sjmmv #include <err.h>
38c799a9c4Sjmmv #include <errno.h>
39c799a9c4Sjmmv #include <stdio.h>
40c799a9c4Sjmmv #include <stdlib.h>
41c799a9c4Sjmmv #include <string.h>
42c799a9c4Sjmmv 
4304ee2eceShannken #include "wsconsctl.h"
4404ee2eceShannken 
452a08d54aSjmmv static int border;
4604ee2eceShannken static int dpytype;
4701647c29Shannken static struct wsdisplay_usefontdata font;
48c29bb13dSmlelstv static struct wsdisplay_getfont gfont;
49c29bb13dSmlelstv static char fontname_buf[256];
50410c49bfSuwe static struct wsdisplay_param backlight;
51410c49bfSuwe static struct wsdisplay_param brightness;
52410c49bfSuwe static struct wsdisplay_param contrast;
5379884742Schristos static struct wsdisplay_scroll_data scroll_l;
549e53e141Smlelstv static struct wsdisplayio_edid_info edid_info;
5592f81ea7Sjmmv static int msg_default_attrs, msg_default_bg, msg_default_fg;
5692f81ea7Sjmmv static int msg_kernel_attrs, msg_kernel_bg, msg_kernel_fg;
578e45f8abSjmcneill static int splash_enable, splash_progress;
5804ee2eceShannken 
5904ee2eceShannken struct field display_field_tab[] = {
608bdb4872Sjmmv     { "border",			&border,	FMT_COLOR,	0 },
6104ee2eceShannken     { "type",			&dpytype,	FMT_DPYTYPE,	FLG_RDONLY },
62c29bb13dSmlelstv     { "font",			&font.name,	FMT_STRING,	0 },
63410c49bfSuwe     { "backlight",		&backlight.curval,  FMT_UINT,	0 },
64410c49bfSuwe     { "brightness",		&brightness.curval, FMT_UINT,	FLG_MODIFY },
65410c49bfSuwe     { "contrast",		&contrast.curval,   FMT_UINT,	FLG_MODIFY },
6679884742Schristos     { "scroll.fastlines",	&scroll_l.fastlines, FMT_UINT,	FLG_MODIFY },
6779884742Schristos     { "scroll.slowlines",	&scroll_l.slowlines, FMT_UINT,	FLG_MODIFY },
689e53e141Smlelstv     { "edid",			&edid_info, FMT_EDID,		FLG_RDONLY|FLG_NOAUTO },
698bdb4872Sjmmv     { "msg.default.attrs",	&msg_default_attrs, FMT_ATTRS,	0 },
708bdb4872Sjmmv     { "msg.default.bg",		&msg_default_bg, FMT_COLOR,	0 },
718bdb4872Sjmmv     { "msg.default.fg",		&msg_default_fg, FMT_COLOR,	0 },
728bdb4872Sjmmv     { "msg.kernel.attrs",	&msg_kernel_attrs, FMT_ATTRS,	0 },
738bdb4872Sjmmv     { "msg.kernel.bg",		&msg_kernel_bg, FMT_COLOR,	0 },
748bdb4872Sjmmv     { "msg.kernel.fg",		&msg_kernel_fg, FMT_COLOR,	0 },
75b87585ecSuwe     { "splash.enable",		&splash_enable, FMT_UINT,	FLG_WRONLY },
76b87585ecSuwe     { "splash.progress",	&splash_progress, FMT_UINT,	FLG_WRONLY },
7704ee2eceShannken };
7804ee2eceShannken 
7904ee2eceShannken int display_field_tab_len = sizeof(display_field_tab) /
8004ee2eceShannken 	sizeof(display_field_tab[0]);
8104ee2eceShannken 
82*7d8ccb8eSmlelstv static int
83*7d8ccb8eSmlelstv display_get_edid(int fd, struct wsdisplayio_edid_info *ei)
84*7d8ccb8eSmlelstv {
85*7d8ccb8eSmlelstv 	size_t sz = 256;
86*7d8ccb8eSmlelstv 	int res;
87*7d8ccb8eSmlelstv 
88*7d8ccb8eSmlelstv 	while (sz <= 65536) {
89*7d8ccb8eSmlelstv 		ei->buffer_size = sz;
90*7d8ccb8eSmlelstv 		ei->edid_data = malloc(sz);
91*7d8ccb8eSmlelstv 		if (ei->edid_data == NULL) {
92*7d8ccb8eSmlelstv 			res = -1;
93*7d8ccb8eSmlelstv 			break;
94*7d8ccb8eSmlelstv 		}
95*7d8ccb8eSmlelstv 
96*7d8ccb8eSmlelstv 		res = ioctl(fd, WSDISPLAYIO_GET_EDID, ei);
97*7d8ccb8eSmlelstv 		if (res == 0 || errno != EAGAIN)
98*7d8ccb8eSmlelstv 			break;
99*7d8ccb8eSmlelstv 
100*7d8ccb8eSmlelstv 		free(ei->edid_data);
101*7d8ccb8eSmlelstv 		ei->edid_data = NULL;
102*7d8ccb8eSmlelstv 		sz *= 2;
103*7d8ccb8eSmlelstv 	}
104*7d8ccb8eSmlelstv 
105*7d8ccb8eSmlelstv 	return res;
106*7d8ccb8eSmlelstv }
107*7d8ccb8eSmlelstv 
10804ee2eceShannken void
109844f4c52Sxtraeme display_get_values(int fd)
11004ee2eceShannken {
111c29bb13dSmlelstv 	if (field_by_value(&font.name)->flags & FLG_GET) {
112c29bb13dSmlelstv 		gfont.gf_name = fontname_buf;
113c29bb13dSmlelstv 		gfont.gf_size = sizeof(fontname_buf);
114c29bb13dSmlelstv 		font.name = gfont.gf_name;
115c29bb13dSmlelstv 		if (ioctl(fd, WSDISPLAYIO_GFONT, &gfont) < 0)
116c29bb13dSmlelstv 			field_disable_by_value(&font.name);
117c29bb13dSmlelstv 	}
118c799a9c4Sjmmv 
11904ee2eceShannken 	if (field_by_value(&dpytype)->flags & FLG_GET)
12004ee2eceShannken 		if (ioctl(fd, WSDISPLAYIO_GTYPE, &dpytype) < 0)
121c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_GTYPE");
12279884742Schristos 
1232a08d54aSjmmv 	if (field_by_value(&border)->flags & FLG_GET)
1242a08d54aSjmmv 		if (ioctl(fd, WSDISPLAYIO_GBORDER, &border) < 0)
125fcc698e8Sjmmv 			field_disable_by_value(&border);
1262a08d54aSjmmv 
127410c49bfSuwe 	if (field_by_value(&backlight.curval)->flags & FLG_GET) {
128410c49bfSuwe 		backlight.param = WSDISPLAYIO_PARAM_BACKLIGHT;
129410c49bfSuwe 		if (ioctl(fd, WSDISPLAYIO_GETPARAM, &backlight) < 0)
130410c49bfSuwe 			field_disable_by_value(&backlight.curval);
131410c49bfSuwe 	}
132410c49bfSuwe 
133410c49bfSuwe 	if (field_by_value(&brightness.curval)->flags & FLG_GET) {
134410c49bfSuwe 		brightness.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
135410c49bfSuwe 		if (ioctl(fd, WSDISPLAYIO_GETPARAM, &brightness))
136410c49bfSuwe 			field_disable_by_value(&brightness.curval);
137410c49bfSuwe 	}
138410c49bfSuwe 
139410c49bfSuwe 	if (field_by_value(&contrast.curval)->flags & FLG_GET) {
140410c49bfSuwe 		contrast.param = WSDISPLAYIO_PARAM_CONTRAST;
141410c49bfSuwe 		if (ioctl(fd, WSDISPLAYIO_GETPARAM, &contrast))
142410c49bfSuwe 			field_disable_by_value(&contrast.curval);
143410c49bfSuwe 	}
144410c49bfSuwe 
14592f81ea7Sjmmv 	if (field_by_value(&msg_default_attrs)->flags & FLG_GET ||
14692f81ea7Sjmmv 	    field_by_value(&msg_default_bg)->flags & FLG_GET ||
14792f81ea7Sjmmv 	    field_by_value(&msg_default_fg)->flags & FLG_GET ||
14892f81ea7Sjmmv 	    field_by_value(&msg_kernel_attrs)->flags & FLG_GET ||
14992f81ea7Sjmmv 	    field_by_value(&msg_kernel_bg)->flags & FLG_GET ||
15092f81ea7Sjmmv 	    field_by_value(&msg_kernel_fg)->flags & FLG_GET) {
15192f81ea7Sjmmv 		struct wsdisplay_msgattrs ma;
15292f81ea7Sjmmv 
15392f81ea7Sjmmv 		if (ioctl(fd, WSDISPLAYIO_GMSGATTRS, &ma) < 0) {
154fcc698e8Sjmmv 			field_disable_by_value(&msg_default_attrs);
155fcc698e8Sjmmv 			field_disable_by_value(&msg_default_bg);
156fcc698e8Sjmmv 			field_disable_by_value(&msg_default_fg);
157fcc698e8Sjmmv 			field_disable_by_value(&msg_kernel_attrs);
158fcc698e8Sjmmv 			field_disable_by_value(&msg_kernel_bg);
159fcc698e8Sjmmv 			field_disable_by_value(&msg_kernel_fg);
160fcc698e8Sjmmv 		} else {
16192f81ea7Sjmmv 			msg_default_attrs = ma.default_attrs;
16292f81ea7Sjmmv 			if (ma.default_attrs & WSATTR_WSCOLORS) {
16392f81ea7Sjmmv 				msg_default_bg = ma.default_bg;
16492f81ea7Sjmmv 				msg_default_fg = ma.default_fg;
16592f81ea7Sjmmv 			} else
16692f81ea7Sjmmv 				msg_default_bg = msg_default_fg = -1;
16792f81ea7Sjmmv 
16892f81ea7Sjmmv 			msg_kernel_attrs = ma.kernel_attrs;
16992f81ea7Sjmmv 			if (ma.kernel_attrs & WSATTR_WSCOLORS) {
17092f81ea7Sjmmv 				msg_kernel_bg = ma.kernel_bg;
17192f81ea7Sjmmv 				msg_kernel_fg = ma.kernel_fg;
17292f81ea7Sjmmv 			} else
17392f81ea7Sjmmv 				msg_kernel_bg = msg_kernel_fg = -1;
17492f81ea7Sjmmv 		}
175fcc698e8Sjmmv 	}
17692f81ea7Sjmmv 
177fcc698e8Sjmmv 	if (field_by_value(&scroll_l.fastlines)->flags & FLG_GET ||
178fcc698e8Sjmmv 	    field_by_value(&scroll_l.slowlines)->flags & FLG_GET) {
17967ec0248Schristos 		if (ioctl(fd, WSDISPLAYIO_DGSCROLL, &scroll_l) < 0) {
180fcc698e8Sjmmv 			field_disable_by_value(&scroll_l.fastlines);
181fcc698e8Sjmmv 			field_disable_by_value(&scroll_l.slowlines);
182fcc698e8Sjmmv 		}
18367ec0248Schristos 	}
1849e53e141Smlelstv 
1859e53e141Smlelstv 	if (field_by_value(&edid_info)->flags & FLG_GET) {
186*7d8ccb8eSmlelstv 		if (display_get_edid(fd, &edid_info) < 0)
1879e53e141Smlelstv 			field_disable_by_value(&edid_info);
1889e53e141Smlelstv 	}
1899e53e141Smlelstv }
19004ee2eceShannken 
19104ee2eceShannken void
192cf7ed4c9Smatt display_put_values(int fd)
19304ee2eceShannken {
194c799a9c4Sjmmv 
19501647c29Shannken 	if (field_by_value(&font.name)->flags & FLG_SET) {
19601647c29Shannken 		if (ioctl(fd, WSDISPLAYIO_SFONT, &font) < 0)
197c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_SFONT");
19801647c29Shannken 		pr_field(field_by_value(&font.name), " -> ");
19901647c29Shannken 	}
20079884742Schristos 
2012a08d54aSjmmv 	if (field_by_value(&border)->flags & FLG_SET) {
2022a08d54aSjmmv 		if (ioctl(fd, WSDISPLAYIO_SBORDER, &border) < 0)
203c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_SBORDER");
2042a08d54aSjmmv 		pr_field(field_by_value(&border), " -> ");
2052a08d54aSjmmv 	}
2062a08d54aSjmmv 
207410c49bfSuwe 	if (field_by_value(&backlight.curval)->flags & FLG_SET) {
208410c49bfSuwe 		backlight.param = WSDISPLAYIO_PARAM_BACKLIGHT;
209410c49bfSuwe 		if (ioctl(fd, WSDISPLAYIO_SETPARAM, &backlight) < 0)
210c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_BACKLIGHT");
211410c49bfSuwe 		pr_field(field_by_value(&backlight.curval), " -> ");
212410c49bfSuwe 	}
213410c49bfSuwe 
214410c49bfSuwe 	if (field_by_value(&brightness.curval)->flags & FLG_SET) {
215410c49bfSuwe 		brightness.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
216410c49bfSuwe 		if (ioctl(fd, WSDISPLAYIO_SETPARAM, &brightness) < 0)
217c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_BRIGHTNESS");
218410c49bfSuwe 		pr_field(field_by_value(&brightness.curval), " -> ");
219410c49bfSuwe 	}
220410c49bfSuwe 
221410c49bfSuwe 	if (field_by_value(&contrast.curval)->flags & FLG_SET) {
222410c49bfSuwe 		contrast.param = WSDISPLAYIO_PARAM_CONTRAST;
223410c49bfSuwe 		if (ioctl(fd, WSDISPLAYIO_SETPARAM, &contrast) < 0)
224c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_CONTRAST");
225410c49bfSuwe 		pr_field(field_by_value(&contrast.curval), " -> ");
226410c49bfSuwe 	}
227410c49bfSuwe 
2288e45f8abSjmcneill 	if (field_by_value(&splash_enable)->flags & FLG_SET) {
2298e45f8abSjmcneill 		if (ioctl(fd, WSDISPLAYIO_SSPLASH, &splash_enable) < 0)
2308e45f8abSjmcneill 			err(EXIT_FAILURE, "WSDISPLAYIO_SSPLASH");
2318e45f8abSjmcneill 		pr_field(field_by_value(&splash_enable), " -> ");
2328e45f8abSjmcneill 	}
2338e45f8abSjmcneill 
2348e45f8abSjmcneill 	if (field_by_value(&splash_progress)->flags & FLG_SET) {
2358e45f8abSjmcneill 		if (ioctl(fd, WSDISPLAYIO_SPROGRESS, &splash_progress) < 0)
2368e45f8abSjmcneill 			err(EXIT_FAILURE, "WSDISPLAYIO_SPROGRESS");
2378e45f8abSjmcneill 		pr_field(field_by_value(&splash_progress), " -> ");
2388e45f8abSjmcneill 	}
2398e45f8abSjmcneill 
24092f81ea7Sjmmv 	if (field_by_value(&msg_default_attrs)->flags & FLG_SET ||
24192f81ea7Sjmmv 	    field_by_value(&msg_default_bg)->flags & FLG_SET ||
24292f81ea7Sjmmv 	    field_by_value(&msg_default_fg)->flags & FLG_SET ||
24392f81ea7Sjmmv 	    field_by_value(&msg_kernel_attrs)->flags & FLG_SET ||
24492f81ea7Sjmmv 	    field_by_value(&msg_kernel_bg)->flags & FLG_SET ||
24592f81ea7Sjmmv 	    field_by_value(&msg_kernel_fg)->flags & FLG_SET) {
24692f81ea7Sjmmv 		struct wsdisplay_msgattrs ma;
24792f81ea7Sjmmv 
24892f81ea7Sjmmv 		if (ioctl(fd, WSDISPLAYIO_GMSGATTRS, &ma) < 0)
249c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_GMSGATTRS");
25092f81ea7Sjmmv 
25192f81ea7Sjmmv 		if (field_by_value(&msg_default_attrs)->flags & FLG_SET) {
25292f81ea7Sjmmv 			ma.default_attrs = msg_default_attrs;
25392f81ea7Sjmmv 			pr_field(field_by_value(&msg_default_attrs), " -> ");
25492f81ea7Sjmmv 		}
25592f81ea7Sjmmv 		if (ma.default_attrs & WSATTR_WSCOLORS) {
25692f81ea7Sjmmv 			if (field_by_value(&msg_default_bg)->flags & FLG_SET) {
25792f81ea7Sjmmv 				ma.default_bg = msg_default_bg;
25892f81ea7Sjmmv 				pr_field(field_by_value(&msg_default_bg),
25992f81ea7Sjmmv 				    " -> ");
26092f81ea7Sjmmv 			}
26192f81ea7Sjmmv 			if (field_by_value(&msg_default_fg)->flags & FLG_SET) {
26292f81ea7Sjmmv 				ma.default_fg = msg_default_fg;
26392f81ea7Sjmmv 				pr_field(field_by_value(&msg_default_fg),
26492f81ea7Sjmmv 				    " -> ");
26592f81ea7Sjmmv 			}
26692f81ea7Sjmmv 		}
26792f81ea7Sjmmv 
26892f81ea7Sjmmv 		if (field_by_value(&msg_kernel_attrs)->flags & FLG_SET) {
26992f81ea7Sjmmv 			ma.kernel_attrs = msg_kernel_attrs;
27092f81ea7Sjmmv 			pr_field(field_by_value(&msg_kernel_attrs), " -> ");
27192f81ea7Sjmmv 		}
27292f81ea7Sjmmv 		if (ma.default_attrs & WSATTR_WSCOLORS) {
27392f81ea7Sjmmv 			if (field_by_value(&msg_kernel_bg)->flags & FLG_SET) {
27492f81ea7Sjmmv 				ma.kernel_bg = msg_kernel_bg;
27592f81ea7Sjmmv 				pr_field(field_by_value(&msg_kernel_bg),
27692f81ea7Sjmmv 				    " -> ");
27792f81ea7Sjmmv 			}
27892f81ea7Sjmmv 			if (field_by_value(&msg_kernel_fg)->flags & FLG_SET) {
27992f81ea7Sjmmv 				ma.kernel_fg = msg_kernel_fg;
28092f81ea7Sjmmv 				pr_field(field_by_value(&msg_kernel_fg),
28192f81ea7Sjmmv 				    " -> ");
28292f81ea7Sjmmv 			}
28392f81ea7Sjmmv 		}
28492f81ea7Sjmmv 
28592f81ea7Sjmmv 		if (ioctl(fd, WSDISPLAYIO_SMSGATTRS, &ma) < 0)
286c799a9c4Sjmmv 			err(EXIT_FAILURE, "WSDISPLAYIO_SMSGATTRS");
28792f81ea7Sjmmv 	}
28892f81ea7Sjmmv 
289fcc698e8Sjmmv 	scroll_l.which = 0;
290fcc698e8Sjmmv 	if (field_by_value(&scroll_l.fastlines)->flags & FLG_SET)
291fcc698e8Sjmmv 		scroll_l.which |= WSDISPLAY_SCROLL_DOFASTLINES;
292fcc698e8Sjmmv 	if (field_by_value(&scroll_l.slowlines)->flags & FLG_SET)
293fcc698e8Sjmmv 		scroll_l.which |= WSDISPLAY_SCROLL_DOSLOWLINES;
294fcc698e8Sjmmv 	if (scroll_l.which != 0 &&
295fcc698e8Sjmmv 	    ioctl(fd, WSDISPLAYIO_DSSCROLL, &scroll_l) < 0)
296c799a9c4Sjmmv 		err(EXIT_FAILURE, "WSDISPLAYIO_DSSCROLL");
29779884742Schristos 	if (scroll_l.which & WSDISPLAY_SCROLL_DOFASTLINES)
29879884742Schristos 		pr_field(field_by_value(&scroll_l.fastlines), " -> ");
29979884742Schristos 	if (scroll_l.which & WSDISPLAY_SCROLL_DOSLOWLINES)
30079884742Schristos 		pr_field(field_by_value(&scroll_l.slowlines), " -> ");
30104ee2eceShannken }
302