1 /* $OpenBSD: display.c,v 1.22 2019/06/28 13:32:46 deraadt 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 <fcntl.h>
38 #include <err.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include "wsconsctl.h"
42
43 u_int dpytype;
44 u_int width, height, depth, fontwidth, fontheight;
45 int focus;
46 struct field_pc brightness, contrast, backlight;
47 int burnon, burnoff, vblank, kbdact, msact, outact;
48 char fontname[WSFONT_NAME_SIZE];
49 struct wsdisplay_emultype emuls;
50 struct wsdisplay_screentype screens;
51
52 struct field display_field_tab[] = {
53 { "type", &dpytype, FMT_DPYTYPE, FLG_RDONLY },
54 { "width", &width, FMT_UINT, FLG_RDONLY },
55 { "height", &height, FMT_UINT, FLG_RDONLY },
56 { "depth", &depth, FMT_UINT, FLG_RDONLY },
57 { "fontwidth", &fontwidth, FMT_UINT, FLG_RDONLY },
58 { "fontheight", &fontheight, FMT_UINT, FLG_RDONLY },
59 { "emulations", &emuls, FMT_EMUL, FLG_RDONLY },
60 { "screentypes", &screens, FMT_SCREEN, FLG_RDONLY },
61 { "focus", &focus, FMT_INT, FLG_NORDBACK },
62 { "brightness", &brightness, FMT_PC, FLG_MODIFY|FLG_INIT },
63 { "contrast", &contrast, FMT_PC, FLG_MODIFY|FLG_INIT },
64 { "backlight", &backlight, FMT_PC, FLG_MODIFY|FLG_INIT },
65 /* screen burner section, outact MUST BE THE LAST, see the set_values */
66 { "screen_on", &burnon, FMT_UINT, FLG_MODIFY|FLG_INIT },
67 { "screen_off", &burnoff, FMT_UINT, FLG_MODIFY|FLG_INIT },
68 { "vblank", &vblank, FMT_BOOL, FLG_MODIFY|FLG_INIT },
69 { "kbdact", &kbdact, FMT_BOOL, FLG_MODIFY|FLG_INIT },
70 { "msact", &msact, FMT_BOOL, FLG_MODIFY|FLG_INIT },
71 { "outact", &outact, FMT_BOOL, FLG_MODIFY|FLG_INIT },
72 { "font", fontname, FMT_STRING, FLG_WRONLY },
73 { NULL }
74 };
75
76 #define fillioctl(n) { cmd = n; cmd_str = #n; }
77
78 void
display_get_values(int fd)79 display_get_values(int fd)
80 {
81 struct wsdisplay_addscreendata gscr;
82 struct wsdisplay_param param;
83 struct wsdisplay_burner burners;
84 struct wsdisplay_fbinfo fbinfo;
85 struct field *pf;
86 const char *cmd_str;
87 void *ptr;
88 unsigned long cmd;
89 int bon = 0, fbon = 0, son = 0;
90
91 focus = gscr.idx = -1;
92 for (pf = display_field_tab; pf->name; pf++) {
93
94 if (!(pf->flags & FLG_GET) || pf->flags & FLG_DEAD)
95 continue;
96
97 ptr = pf->valp;
98
99 if (ptr == &dpytype) {
100 fillioctl(WSDISPLAYIO_GTYPE);
101 } else if (ptr == &focus) {
102 fillioctl(WSDISPLAYIO_GETSCREEN);
103 ptr = ℊ
104 } else if (ptr == &emuls) {
105 fillioctl(WSDISPLAYIO_GETEMULTYPE);
106 emuls.idx=0;
107 } else if (ptr == &fontwidth || ptr == &fontheight) {
108 fillioctl(WSDISPLAYIO_GETSCREENTYPE);
109 ptr = &screens;
110 screens.idx = 0;
111 } else if (ptr == &screens) {
112 fillioctl(WSDISPLAYIO_GETSCREENTYPE);
113 screens.idx=0;
114 } else if (ptr == &brightness) {
115 ptr = ¶m;
116 param.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
117 } else if (ptr == &contrast) {
118 ptr = ¶m;
119 param.param = WSDISPLAYIO_PARAM_CONTRAST;
120 } else if (ptr == &backlight) {
121 ptr = ¶m;
122 param.param = WSDISPLAYIO_PARAM_BACKLIGHT;
123 } else if (ptr == &burnon || ptr == &burnoff ||
124 ptr == &vblank || ptr == &kbdact ||
125 ptr == &outact || ptr == &msact) {
126 fillioctl(WSDISPLAYIO_GBURNER);
127 ptr = &burners;
128 if (!bon)
129 bzero(&burners, sizeof(burners));
130 } else if (ptr == &height || ptr == &width ||
131 ptr == &depth) {
132 fillioctl(WSDISPLAYIO_GINFO);
133 ptr = &fbinfo;
134 if (!fbon)
135 bzero(&fbinfo, sizeof(fbinfo));
136 } else
137 cmd = 0;
138
139 if (ptr == ¶m) {
140 fillioctl(WSDISPLAYIO_GETPARAM);
141 }
142
143 if ((cmd != WSDISPLAYIO_GBURNER && cmd != WSDISPLAYIO_GINFO) ||
144 (cmd == WSDISPLAYIO_GBURNER && !bon) ||
145 (cmd == WSDISPLAYIO_GINFO && !fbon)) {
146 errno = ENOTTY;
147 if (!cmd || ioctl(fd, cmd, ptr) == -1) {
148 if (errno == ENOTTY) {
149 pf->flags |= FLG_DEAD;
150 continue;
151 } else
152 warn("%s", cmd_str);
153 }
154 }
155
156 if (ptr == &burners) {
157 if (!bon) {
158 burnon = burners.on;
159 burnoff = burners.off;
160 vblank = burners.flags & WSDISPLAY_BURN_VBLANK;
161 kbdact = burners.flags & WSDISPLAY_BURN_KBD;
162 msact = burners.flags & WSDISPLAY_BURN_MOUSE;
163 outact = burners.flags & WSDISPLAY_BURN_OUTPUT;
164 }
165 bon++;
166 } else if (ptr == &fbinfo) {
167 if (!fbon) {
168 width = fbinfo.width;
169 height = fbinfo.height;
170 depth = fbinfo.depth;
171 }
172 fbon++;
173 } else if (ptr == &emuls) {
174 emuls.idx=fd;
175 } else if (ptr == &screens) {
176 screens.idx=fd;
177 if (!son) {
178 fontwidth = screens.fontwidth;
179 fontheight = screens.fontheight;
180 }
181 son++;
182 } else if (ptr == ¶m) {
183 struct field_pc *pc = pf->valp;
184
185 pc->min = param.min;
186 pc->cur = param.curval;
187 pc->max = param.max;
188 } else if (ptr == &gscr)
189 focus = gscr.idx;
190 }
191 }
192
193 int
display_put_values(int fd)194 display_put_values(int fd)
195 {
196 struct wsdisplay_param param;
197 struct wsdisplay_burner burners;
198 struct wsdisplay_font font;
199 struct field *pf;
200 const char *cmd_str;
201 void *ptr;
202 unsigned long cmd;
203 int id;
204
205 for (pf = display_field_tab; pf->name; pf++) {
206
207 if (!(pf->flags & FLG_SET) || pf->flags & FLG_DEAD)
208 continue;
209
210 ptr = pf->valp;
211
212 if (ptr == &focus) {
213 fillioctl(WSDISPLAYIO_SETSCREEN);
214 } else if (ptr == &brightness) {
215 ptr = ¶m;
216 id = WSDISPLAYIO_PARAM_BRIGHTNESS;
217 } else if (ptr == &contrast) {
218 ptr = ¶m;
219 id = WSDISPLAYIO_PARAM_CONTRAST;
220 } else if (ptr == &backlight) {
221 ptr = ¶m;
222 id = WSDISPLAYIO_PARAM_BACKLIGHT;
223 } else if (ptr == &burnon || ptr == &burnoff ||
224 ptr == &vblank || ptr == &kbdact ||
225 ptr == &outact || ptr == &msact) {
226
227 bzero(&burners, sizeof(burners));
228 burners.on = burnon;
229 burners.off = burnoff;
230 if (vblank)
231 burners.flags |= WSDISPLAY_BURN_VBLANK;
232 else
233 burners.flags &= ~WSDISPLAY_BURN_VBLANK;
234 if (kbdact)
235 burners.flags |= WSDISPLAY_BURN_KBD;
236 else
237 burners.flags &= ~WSDISPLAY_BURN_KBD;
238 if (msact)
239 burners.flags |= WSDISPLAY_BURN_MOUSE;
240 else
241 burners.flags &= ~WSDISPLAY_BURN_MOUSE;
242 if (outact)
243 burners.flags |= WSDISPLAY_BURN_OUTPUT;
244 else
245 burners.flags &= ~WSDISPLAY_BURN_OUTPUT;
246
247 fillioctl(WSDISPLAYIO_SBURNER);
248 ptr = &burners;
249 } else if (ptr == fontname) {
250 bzero(&font, sizeof(font));
251 strlcpy(font.name, ptr, sizeof font.name);
252 fillioctl(WSDISPLAYIO_USEFONT);
253 } else
254 cmd = 0;
255
256 if (ptr == ¶m) {
257 struct field_pc *pc = pf->valp;
258
259 bzero(¶m, sizeof(param));
260 param.param = id;
261 param.min = pc->min;
262 param.curval = pc->cur;
263 param.max = pc->max;
264 fillioctl(WSDISPLAYIO_SETPARAM);
265 }
266
267 errno = ENOTTY;
268 if (!cmd || ioctl(fd, cmd, ptr) == -1) {
269 if (errno == ENOTTY) {
270 pf->flags |= FLG_DEAD;
271 continue;
272 } else {
273 warn("%s", cmd_str);
274 return 1;
275 }
276 }
277 }
278
279 return 0;
280 }
281
282 char *
display_next_device(int index)283 display_next_device(int index)
284 {
285 static char devname[20];
286
287 if (index > 7)
288 return (NULL);
289
290 snprintf(devname, sizeof(devname), "/dev/tty%c0", index + 'C');
291 return (devname);
292 }
293