xref: /openbsd-src/sbin/wsconsctl/display.c (revision df69c215c7c66baf660f3f65414fd34796c96152)
1*df69c215Sderaadt /*	$OpenBSD: display.c,v 1.22 2019/06/28 13:32:46 deraadt Exp $	*/
2e0b2c52dSmickey /*	$NetBSD: display.c,v 1.1 1998/12/28 14:01:16 hannken Exp $ */
3e0b2c52dSmickey 
4e0b2c52dSmickey /*-
5e0b2c52dSmickey  * Copyright (c) 1998 The NetBSD Foundation, Inc.
6e0b2c52dSmickey  * All rights reserved.
7e0b2c52dSmickey  *
8e0b2c52dSmickey  * This code is derived from software contributed to The NetBSD Foundation
9e0b2c52dSmickey  * by Juergen Hannken-Illjes.
10e0b2c52dSmickey  *
11e0b2c52dSmickey  * Redistribution and use in source and binary forms, with or without
12e0b2c52dSmickey  * modification, are permitted provided that the following conditions
13e0b2c52dSmickey  * are met:
14e0b2c52dSmickey  * 1. Redistributions of source code must retain the above copyright
15e0b2c52dSmickey  *    notice, this list of conditions and the following disclaimer.
16e0b2c52dSmickey  * 2. Redistributions in binary form must reproduce the above copyright
17e0b2c52dSmickey  *    notice, this list of conditions and the following disclaimer in the
18e0b2c52dSmickey  *    documentation and/or other materials provided with the distribution.
19e0b2c52dSmickey  *
20e0b2c52dSmickey  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21e0b2c52dSmickey  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22e0b2c52dSmickey  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23e0b2c52dSmickey  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24e0b2c52dSmickey  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25e0b2c52dSmickey  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26e0b2c52dSmickey  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27e0b2c52dSmickey  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28e0b2c52dSmickey  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29e0b2c52dSmickey  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30e0b2c52dSmickey  * POSSIBILITY OF SUCH DAMAGE.
31e0b2c52dSmickey  */
32e0b2c52dSmickey 
33e0b2c52dSmickey #include <sys/ioctl.h>
34e0b2c52dSmickey #include <sys/time.h>
35e0b2c52dSmickey #include <dev/wscons/wsconsio.h>
36b8557c36Smickey #include <errno.h>
371222b15bSmaja #include <fcntl.h>
38e0b2c52dSmickey #include <err.h>
391222b15bSmaja #include <stdio.h>
40b1b7cd8fSdavid #include <string.h>
41e0b2c52dSmickey #include "wsconsctl.h"
42e0b2c52dSmickey 
43f7ed5097Sshadchin u_int dpytype;
4407d22f6dSfcambus u_int width, height, depth, fontwidth, fontheight;
4582bc7287Smickey int focus;
46b8557c36Smickey struct field_pc brightness, contrast, backlight;
47c2cb52c7Smickey int burnon, burnoff, vblank, kbdact, msact, outact;
485fa7004dSmiod char fontname[WSFONT_NAME_SIZE];
496242560aSmaja struct wsdisplay_emultype emuls;
506242560aSmaja struct wsdisplay_screentype screens;
51e0b2c52dSmickey 
52e0b2c52dSmickey struct field display_field_tab[] = {
53e0b2c52dSmickey     { "type",		&dpytype,	FMT_DPYTYPE,	FLG_RDONLY },
5489c7847eSmaja     { "width",		&width,		FMT_UINT,	FLG_RDONLY },
5589c7847eSmaja     { "height",		&height,	FMT_UINT,	FLG_RDONLY },
5689c7847eSmaja     { "depth",		&depth,		FMT_UINT,	FLG_RDONLY },
5707d22f6dSfcambus     { "fontwidth",	&fontwidth,	FMT_UINT,	FLG_RDONLY },
5807d22f6dSfcambus     { "fontheight",	&fontheight,	FMT_UINT,	FLG_RDONLY },
596242560aSmaja     { "emulations",	&emuls,		FMT_EMUL,	FLG_RDONLY },
606242560aSmaja     { "screentypes",	&screens,	FMT_SCREEN,	FLG_RDONLY },
6135d84bc0Smiod     { "focus",		&focus,		FMT_INT,	FLG_NORDBACK },
62b8557c36Smickey     { "brightness",	&brightness,	FMT_PC,		FLG_MODIFY|FLG_INIT },
63b8557c36Smickey     { "contrast",	&contrast,	FMT_PC,		FLG_MODIFY|FLG_INIT },
64b8557c36Smickey     { "backlight",	&backlight,	FMT_PC,		FLG_MODIFY|FLG_INIT },
65b8557c36Smickey     /* screen burner section, outact MUST BE THE LAST, see the set_values */
66b8557c36Smickey     { "screen_on",	&burnon,	FMT_UINT,	FLG_MODIFY|FLG_INIT },
67b8557c36Smickey     { "screen_off",	&burnoff,	FMT_UINT,	FLG_MODIFY|FLG_INIT },
68b8557c36Smickey     { "vblank",		&vblank,	FMT_BOOL,	FLG_MODIFY|FLG_INIT },
69b8557c36Smickey     { "kbdact",		&kbdact,	FMT_BOOL,	FLG_MODIFY|FLG_INIT },
70b8557c36Smickey     { "msact",		&msact,		FMT_BOOL,	FLG_MODIFY|FLG_INIT },
71b8557c36Smickey     { "outact",		&outact,	FMT_BOOL,	FLG_MODIFY|FLG_INIT },
725fa7004dSmiod     { "font",		fontname,	FMT_STRING,	FLG_WRONLY },
7382bc7287Smickey     { NULL }
74e0b2c52dSmickey };
75e0b2c52dSmickey 
76b8557c36Smickey #define	fillioctl(n)	{ cmd = n; cmd_str = #n; }
77b8557c36Smickey 
78e0b2c52dSmickey void
display_get_values(int fd)7954e3cb1dSfgsch display_get_values(int fd)
80e0b2c52dSmickey {
8182bc7287Smickey 	struct wsdisplay_addscreendata gscr;
82b8557c36Smickey 	struct wsdisplay_param param;
83b8557c36Smickey 	struct wsdisplay_burner burners;
8489c7847eSmaja 	struct wsdisplay_fbinfo fbinfo;
85b8557c36Smickey 	struct field *pf;
86b8557c36Smickey 	const char *cmd_str;
87b8557c36Smickey 	void *ptr;
88b8557c36Smickey 	unsigned long cmd;
8907d22f6dSfcambus 	int bon = 0, fbon = 0, son = 0;
9082bc7287Smickey 
91b0520bc4Smiod 	focus = gscr.idx = -1;
92b8557c36Smickey 	for (pf = display_field_tab; pf->name; pf++) {
93b8557c36Smickey 
94b8557c36Smickey 		if (!(pf->flags & FLG_GET) || pf->flags & FLG_DEAD)
95b8557c36Smickey 			continue;
96b8557c36Smickey 
97b8557c36Smickey 		ptr = pf->valp;
98b8557c36Smickey 
99b8557c36Smickey 		if (ptr == &dpytype) {
100b8557c36Smickey 			fillioctl(WSDISPLAYIO_GTYPE);
101b8557c36Smickey 		} else if (ptr == &focus) {
102b8557c36Smickey 			fillioctl(WSDISPLAYIO_GETSCREEN);
103b8557c36Smickey 			ptr = &gscr;
1046242560aSmaja 		} else if (ptr == &emuls) {
1056242560aSmaja 			fillioctl(WSDISPLAYIO_GETEMULTYPE);
1066242560aSmaja 			emuls.idx=0;
10707d22f6dSfcambus 		} else if (ptr == &fontwidth || ptr == &fontheight) {
10807d22f6dSfcambus 			fillioctl(WSDISPLAYIO_GETSCREENTYPE);
10907d22f6dSfcambus 			ptr = &screens;
11007d22f6dSfcambus 			screens.idx = 0;
1116242560aSmaja 		} else if (ptr == &screens) {
1126242560aSmaja 			fillioctl(WSDISPLAYIO_GETSCREENTYPE);
1136242560aSmaja 			screens.idx=0;
114b8557c36Smickey 		} else if (ptr == &brightness) {
115b8557c36Smickey 			ptr = &param;
116b8557c36Smickey 			param.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
117b8557c36Smickey 		} else if (ptr == &contrast) {
118b8557c36Smickey 			ptr = &param;
119b8557c36Smickey 			param.param = WSDISPLAYIO_PARAM_CONTRAST;
120b8557c36Smickey 		} else if (ptr == &backlight) {
121b8557c36Smickey 			ptr = &param;
122b8557c36Smickey 			param.param = WSDISPLAYIO_PARAM_BACKLIGHT;
123b8557c36Smickey 		} else if (ptr == &burnon || ptr == &burnoff ||
124b8557c36Smickey 			   ptr == &vblank || ptr == &kbdact ||
125b8557c36Smickey 			   ptr == &outact || ptr == &msact) {
126b8557c36Smickey 			fillioctl(WSDISPLAYIO_GBURNER);
127b8557c36Smickey 			ptr = &burners;
128b8557c36Smickey 			if (!bon)
129b8557c36Smickey 				bzero(&burners, sizeof(burners));
13089c7847eSmaja 		} else if (ptr == &height || ptr == &width ||
13189c7847eSmaja 			   ptr == &depth) {
13289c7847eSmaja 			fillioctl(WSDISPLAYIO_GINFO);
13389c7847eSmaja 			ptr = &fbinfo;
13489c7847eSmaja 			if (!fbon)
13589c7847eSmaja 				bzero(&fbinfo, sizeof(fbinfo));
136b8557c36Smickey 		} else
137b8557c36Smickey 			cmd = 0;
138b8557c36Smickey 
139b8557c36Smickey 		if (ptr == &param) {
140b8557c36Smickey 			fillioctl(WSDISPLAYIO_GETPARAM);
14175870d8bSpvalchev 		}
14282bc7287Smickey 
14389c7847eSmaja 		if ((cmd != WSDISPLAYIO_GBURNER && cmd != WSDISPLAYIO_GINFO) ||
14489c7847eSmaja 		    (cmd == WSDISPLAYIO_GBURNER && !bon) ||
14589c7847eSmaja 		    (cmd == WSDISPLAYIO_GINFO && !fbon)) {
146b8557c36Smickey 			errno = ENOTTY;
147*df69c215Sderaadt 			if (!cmd || ioctl(fd, cmd, ptr) == -1) {
148b8557c36Smickey 				if (errno == ENOTTY) {
149b8557c36Smickey 					pf->flags |= FLG_DEAD;
150b8557c36Smickey 					continue;
151b8557c36Smickey 				} else
1528aac6f43Sguenther 					warn("%s", cmd_str);
153b8557c36Smickey 			}
154b8557c36Smickey 		}
155c2cb52c7Smickey 
156b8557c36Smickey 		if (ptr == &burners) {
157b8557c36Smickey 			if (!bon) {
158c2cb52c7Smickey 				burnon = burners.on;
159c2cb52c7Smickey 				burnoff = burners.off;
160c2cb52c7Smickey 				vblank = burners.flags & WSDISPLAY_BURN_VBLANK;
161c2cb52c7Smickey 				kbdact = burners.flags & WSDISPLAY_BURN_KBD;
162c2cb52c7Smickey 				msact = burners.flags & WSDISPLAY_BURN_MOUSE;
163c2cb52c7Smickey 				outact = burners.flags & WSDISPLAY_BURN_OUTPUT;
164c2cb52c7Smickey 			}
165b8557c36Smickey 			bon++;
16689c7847eSmaja 		} else if (ptr == &fbinfo) {
16789c7847eSmaja 			if (!fbon) {
16889c7847eSmaja 				width = fbinfo.width;
16989c7847eSmaja 				height = fbinfo.height;
17089c7847eSmaja 				depth = fbinfo.depth;
17189c7847eSmaja 			}
17289c7847eSmaja 			fbon++;
1736242560aSmaja 		} else if (ptr == &emuls) {
1746242560aSmaja 			emuls.idx=fd;
1756242560aSmaja 		} else if (ptr == &screens) {
1766242560aSmaja 			screens.idx=fd;
17707d22f6dSfcambus 			if (!son) {
17807d22f6dSfcambus 				fontwidth = screens.fontwidth;
17907d22f6dSfcambus 				fontheight = screens.fontheight;
18007d22f6dSfcambus 			}
18107d22f6dSfcambus 			son++;
182b8557c36Smickey 		} else if (ptr == &param) {
183b8557c36Smickey 			struct field_pc *pc = pf->valp;
184b8557c36Smickey 
185b8557c36Smickey 			pc->min = param.min;
186b8557c36Smickey 			pc->cur = param.curval;
187b8557c36Smickey 			pc->max = param.max;
1888e547bc1Smickey 		} else if (ptr == &gscr)
1898e547bc1Smickey 			focus = gscr.idx;
190e0b2c52dSmickey 	}
191b0520bc4Smiod }
192e0b2c52dSmickey 
193f0cd74dfSmartynas int
display_put_values(int fd)19454e3cb1dSfgsch display_put_values(int fd)
195e0b2c52dSmickey {
196b8557c36Smickey 	struct wsdisplay_param param;
197c2cb52c7Smickey 	struct wsdisplay_burner burners;
1985fa7004dSmiod 	struct wsdisplay_font font;
199b8557c36Smickey 	struct field *pf;
200b8557c36Smickey 	const char *cmd_str;
201b8557c36Smickey 	void *ptr;
202b8557c36Smickey 	unsigned long cmd;
203b8557c36Smickey 	int id;
204c2cb52c7Smickey 
205b8557c36Smickey 	for (pf = display_field_tab; pf->name; pf++) {
206b8557c36Smickey 
207b8557c36Smickey 		if (!(pf->flags & FLG_SET) || pf->flags & FLG_DEAD)
208b8557c36Smickey 			continue;
209b8557c36Smickey 
210b8557c36Smickey 		ptr = pf->valp;
211b8557c36Smickey 
212b8557c36Smickey 		if (ptr == &focus) {
213b8557c36Smickey 			fillioctl(WSDISPLAYIO_SETSCREEN);
214b8557c36Smickey 		} else if (ptr == &brightness) {
215b8557c36Smickey 			ptr = &param;
216b8557c36Smickey 			id = WSDISPLAYIO_PARAM_BRIGHTNESS;
217b8557c36Smickey 		} else if (ptr == &contrast) {
218b8557c36Smickey 			ptr = &param;
219b8557c36Smickey 			id = WSDISPLAYIO_PARAM_CONTRAST;
220b8557c36Smickey 		} else if (ptr == &backlight) {
221b8557c36Smickey 			ptr = &param;
222b8557c36Smickey 			id = WSDISPLAYIO_PARAM_BACKLIGHT;
223b8557c36Smickey 		} else if (ptr == &burnon || ptr == &burnoff ||
224b8557c36Smickey 			   ptr == &vblank || ptr == &kbdact ||
225b8557c36Smickey 			   ptr == &outact || ptr == &msact) {
226b8557c36Smickey 
227b8557c36Smickey 			bzero(&burners, sizeof(burners));
228c2cb52c7Smickey 			burners.on = burnon;
229c2cb52c7Smickey 			burners.off = burnoff;
230c2cb52c7Smickey 			if (vblank)
231c2cb52c7Smickey 				burners.flags |= WSDISPLAY_BURN_VBLANK;
232c2cb52c7Smickey 			else
233c2cb52c7Smickey 				burners.flags &= ~WSDISPLAY_BURN_VBLANK;
234c2cb52c7Smickey 			if (kbdact)
235c2cb52c7Smickey 				burners.flags |= WSDISPLAY_BURN_KBD;
236c2cb52c7Smickey 			else
237c2cb52c7Smickey 				burners.flags &= ~WSDISPLAY_BURN_KBD;
238c2cb52c7Smickey 			if (msact)
239c2cb52c7Smickey 				burners.flags |= WSDISPLAY_BURN_MOUSE;
240c2cb52c7Smickey 			else
241c2cb52c7Smickey 				burners.flags &= ~WSDISPLAY_BURN_MOUSE;
242c2cb52c7Smickey 			if (outact)
243c2cb52c7Smickey 				burners.flags |= WSDISPLAY_BURN_OUTPUT;
244c2cb52c7Smickey 			else
245c2cb52c7Smickey 				burners.flags &= ~WSDISPLAY_BURN_OUTPUT;
246b8557c36Smickey 
247b8557c36Smickey 			fillioctl(WSDISPLAYIO_SBURNER);
248b8557c36Smickey 			ptr = &burners;
2495fa7004dSmiod 		} else if (ptr == fontname) {
2505fa7004dSmiod 			bzero(&font, sizeof(font));
2515fa7004dSmiod 			strlcpy(font.name, ptr, sizeof font.name);
2525fa7004dSmiod 			fillioctl(WSDISPLAYIO_USEFONT);
253b8557c36Smickey 		} else
254b8557c36Smickey 			cmd = 0;
255b8557c36Smickey 
256b8557c36Smickey 		if (ptr == &param) {
257b8557c36Smickey 			struct field_pc *pc = pf->valp;
258b8557c36Smickey 
259b8557c36Smickey 			bzero(&param, sizeof(param));
260b8557c36Smickey 			param.param = id;
261b8557c36Smickey 			param.min = pc->min;
262b8557c36Smickey 			param.curval = pc->cur;
263b8557c36Smickey 			param.max = pc->max;
264b8557c36Smickey 			fillioctl(WSDISPLAYIO_SETPARAM);
265c2cb52c7Smickey 		}
266c2cb52c7Smickey 
267b8557c36Smickey 		errno = ENOTTY;
268*df69c215Sderaadt 		if (!cmd || ioctl(fd, cmd, ptr) == -1) {
269b8557c36Smickey 			if (errno == ENOTTY) {
270b8557c36Smickey 				pf->flags |= FLG_DEAD;
271b8557c36Smickey 				continue;
272f0cd74dfSmartynas 			} else {
2738aac6f43Sguenther 				warn("%s", cmd_str);
274f0cd74dfSmartynas 				return 1;
275f0cd74dfSmartynas 			}
276f0cd74dfSmartynas 		}
277b0520bc4Smiod 	}
278b8557c36Smickey 
279f0cd74dfSmartynas 	return 0;
280e0b2c52dSmickey }
2811222b15bSmaja 
28254e3cb1dSfgsch char *
display_next_device(int index)28354e3cb1dSfgsch display_next_device(int index)
2841222b15bSmaja {
28554e3cb1dSfgsch 	static char devname[20];
2861222b15bSmaja 
28754e3cb1dSfgsch 	if (index > 7)
28854e3cb1dSfgsch 		return (NULL);
2891222b15bSmaja 
29054e3cb1dSfgsch 	snprintf(devname, sizeof(devname), "/dev/tty%c0", index + 'C');
29154e3cb1dSfgsch 	return (devname);
2921222b15bSmaja }
293