xref: /openbsd-src/sbin/wsconsctl/display.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: display.c,v 1.11 2008/06/26 05:42:06 ray Exp $	*/
2 /*	$NetBSD: display.c,v 1.1 1998/12/28 14:01:16 hannken Exp $ */
3 
4 /*-
5  * Copyright (c) 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Juergen Hannken-Illjes.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/ioctl.h>
34 #include <sys/time.h>
35 #include <dev/wscons/wsconsio.h>
36 #include <errno.h>
37 #include <err.h>
38 #include <string.h>
39 #include "wsconsctl.h"
40 
41 int dpytype;
42 int focus;
43 struct field_pc brightness, contrast, backlight;
44 int burnon, burnoff, vblank, kbdact, msact, outact;
45 
46 struct field display_field_tab[] = {
47     { "type",		&dpytype,	FMT_DPYTYPE,	FLG_RDONLY },
48     { "focus",		&focus,		FMT_INT,	FLG_MODIFY },
49     { "brightness",	&brightness,	FMT_PC,		FLG_MODIFY|FLG_INIT },
50     { "contrast",	&contrast,	FMT_PC,		FLG_MODIFY|FLG_INIT },
51     { "backlight",	&backlight,	FMT_PC,		FLG_MODIFY|FLG_INIT },
52     /* screen burner section, outact MUST BE THE LAST, see the set_values */
53     { "screen_on",	&burnon,	FMT_UINT,	FLG_MODIFY|FLG_INIT },
54     { "screen_off",	&burnoff,	FMT_UINT,	FLG_MODIFY|FLG_INIT },
55     { "vblank",		&vblank,	FMT_BOOL,	FLG_MODIFY|FLG_INIT },
56     { "kbdact",		&kbdact,	FMT_BOOL,	FLG_MODIFY|FLG_INIT },
57     { "msact",		&msact,		FMT_BOOL,	FLG_MODIFY|FLG_INIT },
58     { "outact",		&outact,	FMT_BOOL,	FLG_MODIFY|FLG_INIT },
59     { NULL }
60 };
61 
62 #define	fillioctl(n)	{ cmd = n; cmd_str = #n; }
63 
64 void
65 display_get_values(const char *pre, int fd)
66 {
67 	struct wsdisplay_addscreendata gscr;
68 	struct wsdisplay_param param;
69 	struct wsdisplay_burner burners;
70 	struct field *pf;
71 	const char *cmd_str;
72 	void *ptr;
73 	unsigned long cmd;
74 	int bon = 0;
75 
76 	focus = gscr.idx = -1;
77 	for (pf = display_field_tab; pf->name; pf++) {
78 
79 		if (!(pf->flags & FLG_GET) || pf->flags & FLG_DEAD)
80 			continue;
81 
82 		ptr = pf->valp;
83 
84 		if (ptr == &dpytype) {
85 			fillioctl(WSDISPLAYIO_GTYPE);
86 		} else if (ptr == &focus) {
87 			fillioctl(WSDISPLAYIO_GETSCREEN);
88 			ptr = &gscr;
89 		} else if (ptr == &brightness) {
90 			ptr = &param;
91 			param.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
92 		} else if (ptr == &contrast) {
93 			ptr = &param;
94 			param.param = WSDISPLAYIO_PARAM_CONTRAST;
95 		} else if (ptr == &backlight) {
96 			ptr = &param;
97 			param.param = WSDISPLAYIO_PARAM_BACKLIGHT;
98 		} else if (ptr == &burnon || ptr == &burnoff ||
99 			   ptr == &vblank || ptr == &kbdact ||
100 			   ptr == &outact || ptr == &msact) {
101 			fillioctl(WSDISPLAYIO_GBURNER);
102 			ptr = &burners;
103 			if (!bon)
104 				bzero(&burners, sizeof(burners));
105 		} else
106 			cmd = 0;
107 
108 		if (ptr == &param) {
109 			fillioctl(WSDISPLAYIO_GETPARAM);
110 		}
111 
112 		if (!bon || cmd != WSDISPLAYIO_GBURNER) {
113 			errno = ENOTTY;
114 			if (!cmd || ioctl(fd, cmd, ptr) < 0) {
115 				if (errno == ENOTTY) {
116 					pf->flags |= FLG_DEAD;
117 					continue;
118 				} else
119 					warn(cmd_str);
120 			}
121 		}
122 
123 		if (ptr == &burners) {
124 			if (!bon) {
125 				burnon = burners.on;
126 				burnoff = burners.off;
127 				vblank = burners.flags & WSDISPLAY_BURN_VBLANK;
128 				kbdact = burners.flags & WSDISPLAY_BURN_KBD;
129 				msact = burners.flags & WSDISPLAY_BURN_MOUSE;
130 				outact = burners.flags & WSDISPLAY_BURN_OUTPUT;
131 			}
132 			bon++;
133 		} else if (ptr == &param) {
134 			struct field_pc *pc = pf->valp;
135 
136 			pc->min = param.min;
137 			pc->cur = param.curval;
138 			pc->max = param.max;
139 		} else if (ptr == &gscr)
140 			focus = gscr.idx;
141 	}
142 }
143 
144 void
145 display_put_values(const char *pre, int fd)
146 {
147 	struct wsdisplay_param param;
148 	struct wsdisplay_burner burners;
149 	struct field *pf;
150 	const char *cmd_str;
151 	void *ptr;
152 	unsigned long cmd;
153 	int id;
154 
155 	for (pf = display_field_tab; pf->name; pf++) {
156 
157 		if (!(pf->flags & FLG_SET) || pf->flags & FLG_DEAD)
158 			continue;
159 
160 		ptr = pf->valp;
161 
162 		if (ptr == &focus) {
163 			fillioctl(WSDISPLAYIO_SETSCREEN);
164 		} else if (ptr == &brightness) {
165 			ptr = &param;
166 			id = WSDISPLAYIO_PARAM_BRIGHTNESS;
167 		} else if (ptr == &contrast) {
168 			ptr = &param;
169 			id = WSDISPLAYIO_PARAM_CONTRAST;
170 		} else if (ptr == &backlight) {
171 			ptr = &param;
172 			id = WSDISPLAYIO_PARAM_BACKLIGHT;
173 		} else if (ptr == &burnon || ptr == &burnoff ||
174 			   ptr == &vblank || ptr == &kbdact ||
175 			   ptr == &outact || ptr == &msact) {
176 
177 			bzero(&burners, sizeof(burners));
178 			burners.on = burnon;
179 			burners.off = burnoff;
180 			if (vblank)
181 				burners.flags |= WSDISPLAY_BURN_VBLANK;
182 			else
183 				burners.flags &= ~WSDISPLAY_BURN_VBLANK;
184 			if (kbdact)
185 				burners.flags |= WSDISPLAY_BURN_KBD;
186 			else
187 				burners.flags &= ~WSDISPLAY_BURN_KBD;
188 			if (msact)
189 				burners.flags |= WSDISPLAY_BURN_MOUSE;
190 			else
191 				burners.flags &= ~WSDISPLAY_BURN_MOUSE;
192 			if (outact)
193 				burners.flags |= WSDISPLAY_BURN_OUTPUT;
194 			else
195 				burners.flags &= ~WSDISPLAY_BURN_OUTPUT;
196 
197 			fillioctl(WSDISPLAYIO_SBURNER);
198 			ptr = &burners;
199 		} else
200 			cmd = 0;
201 
202 		if (ptr == &param) {
203 			struct field_pc *pc = pf->valp;
204 
205 			bzero(&param, sizeof(param));
206 			param.param = id;
207 			param.min = pc->min;
208 			param.curval = pc->cur;
209 			param.max = pc->max;
210 			fillioctl(WSDISPLAYIO_SETPARAM);
211 		}
212 
213 		errno = ENOTTY;
214 		if (!cmd || ioctl(fd, cmd, ptr) < 0) {
215 			if (errno == ENOTTY) {
216 				pf->flags |= FLG_DEAD;
217 				continue;
218 			} else
219 				warn(cmd_str);
220 		}
221 
222 		pr_field(pre, pf, " -> ");
223 	}
224 }
225