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