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