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 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 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 * 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