1*7d8ccb8eSmlelstv /* $NetBSD: display.c,v 1.19 2024/10/20 13:49:41 mlelstv Exp $ */ 204ee2eceShannken 304ee2eceShannken /*- 4ea287a80Sjmmv * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. 504ee2eceShannken * All rights reserved. 604ee2eceShannken * 704ee2eceShannken * This code is derived from software contributed to The NetBSD Foundation 804ee2eceShannken * by Juergen Hannken-Illjes. 904ee2eceShannken * 1004ee2eceShannken * Redistribution and use in source and binary forms, with or without 1104ee2eceShannken * modification, are permitted provided that the following conditions 1204ee2eceShannken * are met: 1304ee2eceShannken * 1. Redistributions of source code must retain the above copyright 1404ee2eceShannken * notice, this list of conditions and the following disclaimer. 1504ee2eceShannken * 2. Redistributions in binary form must reproduce the above copyright 1604ee2eceShannken * notice, this list of conditions and the following disclaimer in the 1704ee2eceShannken * documentation and/or other materials provided with the distribution. 1804ee2eceShannken * 1904ee2eceShannken * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2004ee2eceShannken * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2104ee2eceShannken * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2204ee2eceShannken * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2304ee2eceShannken * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2404ee2eceShannken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2504ee2eceShannken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2604ee2eceShannken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2704ee2eceShannken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2804ee2eceShannken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2904ee2eceShannken * POSSIBILITY OF SUCH DAMAGE. 3004ee2eceShannken */ 3104ee2eceShannken 3204ee2eceShannken #include <sys/ioctl.h> 3304ee2eceShannken #include <sys/time.h> 3467ec0248Schristos 3567ec0248Schristos #include <dev/wscons/wsconsio.h> 3667ec0248Schristos 37c799a9c4Sjmmv #include <err.h> 38c799a9c4Sjmmv #include <errno.h> 39c799a9c4Sjmmv #include <stdio.h> 40c799a9c4Sjmmv #include <stdlib.h> 41c799a9c4Sjmmv #include <string.h> 42c799a9c4Sjmmv 4304ee2eceShannken #include "wsconsctl.h" 4404ee2eceShannken 452a08d54aSjmmv static int border; 4604ee2eceShannken static int dpytype; 4701647c29Shannken static struct wsdisplay_usefontdata font; 48c29bb13dSmlelstv static struct wsdisplay_getfont gfont; 49c29bb13dSmlelstv static char fontname_buf[256]; 50410c49bfSuwe static struct wsdisplay_param backlight; 51410c49bfSuwe static struct wsdisplay_param brightness; 52410c49bfSuwe static struct wsdisplay_param contrast; 5379884742Schristos static struct wsdisplay_scroll_data scroll_l; 549e53e141Smlelstv static struct wsdisplayio_edid_info edid_info; 5592f81ea7Sjmmv static int msg_default_attrs, msg_default_bg, msg_default_fg; 5692f81ea7Sjmmv static int msg_kernel_attrs, msg_kernel_bg, msg_kernel_fg; 578e45f8abSjmcneill static int splash_enable, splash_progress; 5804ee2eceShannken 5904ee2eceShannken struct field display_field_tab[] = { 608bdb4872Sjmmv { "border", &border, FMT_COLOR, 0 }, 6104ee2eceShannken { "type", &dpytype, FMT_DPYTYPE, FLG_RDONLY }, 62c29bb13dSmlelstv { "font", &font.name, FMT_STRING, 0 }, 63410c49bfSuwe { "backlight", &backlight.curval, FMT_UINT, 0 }, 64410c49bfSuwe { "brightness", &brightness.curval, FMT_UINT, FLG_MODIFY }, 65410c49bfSuwe { "contrast", &contrast.curval, FMT_UINT, FLG_MODIFY }, 6679884742Schristos { "scroll.fastlines", &scroll_l.fastlines, FMT_UINT, FLG_MODIFY }, 6779884742Schristos { "scroll.slowlines", &scroll_l.slowlines, FMT_UINT, FLG_MODIFY }, 689e53e141Smlelstv { "edid", &edid_info, FMT_EDID, FLG_RDONLY|FLG_NOAUTO }, 698bdb4872Sjmmv { "msg.default.attrs", &msg_default_attrs, FMT_ATTRS, 0 }, 708bdb4872Sjmmv { "msg.default.bg", &msg_default_bg, FMT_COLOR, 0 }, 718bdb4872Sjmmv { "msg.default.fg", &msg_default_fg, FMT_COLOR, 0 }, 728bdb4872Sjmmv { "msg.kernel.attrs", &msg_kernel_attrs, FMT_ATTRS, 0 }, 738bdb4872Sjmmv { "msg.kernel.bg", &msg_kernel_bg, FMT_COLOR, 0 }, 748bdb4872Sjmmv { "msg.kernel.fg", &msg_kernel_fg, FMT_COLOR, 0 }, 75b87585ecSuwe { "splash.enable", &splash_enable, FMT_UINT, FLG_WRONLY }, 76b87585ecSuwe { "splash.progress", &splash_progress, FMT_UINT, FLG_WRONLY }, 7704ee2eceShannken }; 7804ee2eceShannken 7904ee2eceShannken int display_field_tab_len = sizeof(display_field_tab) / 8004ee2eceShannken sizeof(display_field_tab[0]); 8104ee2eceShannken 82*7d8ccb8eSmlelstv static int 83*7d8ccb8eSmlelstv display_get_edid(int fd, struct wsdisplayio_edid_info *ei) 84*7d8ccb8eSmlelstv { 85*7d8ccb8eSmlelstv size_t sz = 256; 86*7d8ccb8eSmlelstv int res; 87*7d8ccb8eSmlelstv 88*7d8ccb8eSmlelstv while (sz <= 65536) { 89*7d8ccb8eSmlelstv ei->buffer_size = sz; 90*7d8ccb8eSmlelstv ei->edid_data = malloc(sz); 91*7d8ccb8eSmlelstv if (ei->edid_data == NULL) { 92*7d8ccb8eSmlelstv res = -1; 93*7d8ccb8eSmlelstv break; 94*7d8ccb8eSmlelstv } 95*7d8ccb8eSmlelstv 96*7d8ccb8eSmlelstv res = ioctl(fd, WSDISPLAYIO_GET_EDID, ei); 97*7d8ccb8eSmlelstv if (res == 0 || errno != EAGAIN) 98*7d8ccb8eSmlelstv break; 99*7d8ccb8eSmlelstv 100*7d8ccb8eSmlelstv free(ei->edid_data); 101*7d8ccb8eSmlelstv ei->edid_data = NULL; 102*7d8ccb8eSmlelstv sz *= 2; 103*7d8ccb8eSmlelstv } 104*7d8ccb8eSmlelstv 105*7d8ccb8eSmlelstv return res; 106*7d8ccb8eSmlelstv } 107*7d8ccb8eSmlelstv 10804ee2eceShannken void 109844f4c52Sxtraeme display_get_values(int fd) 11004ee2eceShannken { 111c29bb13dSmlelstv if (field_by_value(&font.name)->flags & FLG_GET) { 112c29bb13dSmlelstv gfont.gf_name = fontname_buf; 113c29bb13dSmlelstv gfont.gf_size = sizeof(fontname_buf); 114c29bb13dSmlelstv font.name = gfont.gf_name; 115c29bb13dSmlelstv if (ioctl(fd, WSDISPLAYIO_GFONT, &gfont) < 0) 116c29bb13dSmlelstv field_disable_by_value(&font.name); 117c29bb13dSmlelstv } 118c799a9c4Sjmmv 11904ee2eceShannken if (field_by_value(&dpytype)->flags & FLG_GET) 12004ee2eceShannken if (ioctl(fd, WSDISPLAYIO_GTYPE, &dpytype) < 0) 121c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_GTYPE"); 12279884742Schristos 1232a08d54aSjmmv if (field_by_value(&border)->flags & FLG_GET) 1242a08d54aSjmmv if (ioctl(fd, WSDISPLAYIO_GBORDER, &border) < 0) 125fcc698e8Sjmmv field_disable_by_value(&border); 1262a08d54aSjmmv 127410c49bfSuwe if (field_by_value(&backlight.curval)->flags & FLG_GET) { 128410c49bfSuwe backlight.param = WSDISPLAYIO_PARAM_BACKLIGHT; 129410c49bfSuwe if (ioctl(fd, WSDISPLAYIO_GETPARAM, &backlight) < 0) 130410c49bfSuwe field_disable_by_value(&backlight.curval); 131410c49bfSuwe } 132410c49bfSuwe 133410c49bfSuwe if (field_by_value(&brightness.curval)->flags & FLG_GET) { 134410c49bfSuwe brightness.param = WSDISPLAYIO_PARAM_BRIGHTNESS; 135410c49bfSuwe if (ioctl(fd, WSDISPLAYIO_GETPARAM, &brightness)) 136410c49bfSuwe field_disable_by_value(&brightness.curval); 137410c49bfSuwe } 138410c49bfSuwe 139410c49bfSuwe if (field_by_value(&contrast.curval)->flags & FLG_GET) { 140410c49bfSuwe contrast.param = WSDISPLAYIO_PARAM_CONTRAST; 141410c49bfSuwe if (ioctl(fd, WSDISPLAYIO_GETPARAM, &contrast)) 142410c49bfSuwe field_disable_by_value(&contrast.curval); 143410c49bfSuwe } 144410c49bfSuwe 14592f81ea7Sjmmv if (field_by_value(&msg_default_attrs)->flags & FLG_GET || 14692f81ea7Sjmmv field_by_value(&msg_default_bg)->flags & FLG_GET || 14792f81ea7Sjmmv field_by_value(&msg_default_fg)->flags & FLG_GET || 14892f81ea7Sjmmv field_by_value(&msg_kernel_attrs)->flags & FLG_GET || 14992f81ea7Sjmmv field_by_value(&msg_kernel_bg)->flags & FLG_GET || 15092f81ea7Sjmmv field_by_value(&msg_kernel_fg)->flags & FLG_GET) { 15192f81ea7Sjmmv struct wsdisplay_msgattrs ma; 15292f81ea7Sjmmv 15392f81ea7Sjmmv if (ioctl(fd, WSDISPLAYIO_GMSGATTRS, &ma) < 0) { 154fcc698e8Sjmmv field_disable_by_value(&msg_default_attrs); 155fcc698e8Sjmmv field_disable_by_value(&msg_default_bg); 156fcc698e8Sjmmv field_disable_by_value(&msg_default_fg); 157fcc698e8Sjmmv field_disable_by_value(&msg_kernel_attrs); 158fcc698e8Sjmmv field_disable_by_value(&msg_kernel_bg); 159fcc698e8Sjmmv field_disable_by_value(&msg_kernel_fg); 160fcc698e8Sjmmv } else { 16192f81ea7Sjmmv msg_default_attrs = ma.default_attrs; 16292f81ea7Sjmmv if (ma.default_attrs & WSATTR_WSCOLORS) { 16392f81ea7Sjmmv msg_default_bg = ma.default_bg; 16492f81ea7Sjmmv msg_default_fg = ma.default_fg; 16592f81ea7Sjmmv } else 16692f81ea7Sjmmv msg_default_bg = msg_default_fg = -1; 16792f81ea7Sjmmv 16892f81ea7Sjmmv msg_kernel_attrs = ma.kernel_attrs; 16992f81ea7Sjmmv if (ma.kernel_attrs & WSATTR_WSCOLORS) { 17092f81ea7Sjmmv msg_kernel_bg = ma.kernel_bg; 17192f81ea7Sjmmv msg_kernel_fg = ma.kernel_fg; 17292f81ea7Sjmmv } else 17392f81ea7Sjmmv msg_kernel_bg = msg_kernel_fg = -1; 17492f81ea7Sjmmv } 175fcc698e8Sjmmv } 17692f81ea7Sjmmv 177fcc698e8Sjmmv if (field_by_value(&scroll_l.fastlines)->flags & FLG_GET || 178fcc698e8Sjmmv field_by_value(&scroll_l.slowlines)->flags & FLG_GET) { 17967ec0248Schristos if (ioctl(fd, WSDISPLAYIO_DGSCROLL, &scroll_l) < 0) { 180fcc698e8Sjmmv field_disable_by_value(&scroll_l.fastlines); 181fcc698e8Sjmmv field_disable_by_value(&scroll_l.slowlines); 182fcc698e8Sjmmv } 18367ec0248Schristos } 1849e53e141Smlelstv 1859e53e141Smlelstv if (field_by_value(&edid_info)->flags & FLG_GET) { 186*7d8ccb8eSmlelstv if (display_get_edid(fd, &edid_info) < 0) 1879e53e141Smlelstv field_disable_by_value(&edid_info); 1889e53e141Smlelstv } 1899e53e141Smlelstv } 19004ee2eceShannken 19104ee2eceShannken void 192cf7ed4c9Smatt display_put_values(int fd) 19304ee2eceShannken { 194c799a9c4Sjmmv 19501647c29Shannken if (field_by_value(&font.name)->flags & FLG_SET) { 19601647c29Shannken if (ioctl(fd, WSDISPLAYIO_SFONT, &font) < 0) 197c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_SFONT"); 19801647c29Shannken pr_field(field_by_value(&font.name), " -> "); 19901647c29Shannken } 20079884742Schristos 2012a08d54aSjmmv if (field_by_value(&border)->flags & FLG_SET) { 2022a08d54aSjmmv if (ioctl(fd, WSDISPLAYIO_SBORDER, &border) < 0) 203c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_SBORDER"); 2042a08d54aSjmmv pr_field(field_by_value(&border), " -> "); 2052a08d54aSjmmv } 2062a08d54aSjmmv 207410c49bfSuwe if (field_by_value(&backlight.curval)->flags & FLG_SET) { 208410c49bfSuwe backlight.param = WSDISPLAYIO_PARAM_BACKLIGHT; 209410c49bfSuwe if (ioctl(fd, WSDISPLAYIO_SETPARAM, &backlight) < 0) 210c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_BACKLIGHT"); 211410c49bfSuwe pr_field(field_by_value(&backlight.curval), " -> "); 212410c49bfSuwe } 213410c49bfSuwe 214410c49bfSuwe if (field_by_value(&brightness.curval)->flags & FLG_SET) { 215410c49bfSuwe brightness.param = WSDISPLAYIO_PARAM_BRIGHTNESS; 216410c49bfSuwe if (ioctl(fd, WSDISPLAYIO_SETPARAM, &brightness) < 0) 217c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_BRIGHTNESS"); 218410c49bfSuwe pr_field(field_by_value(&brightness.curval), " -> "); 219410c49bfSuwe } 220410c49bfSuwe 221410c49bfSuwe if (field_by_value(&contrast.curval)->flags & FLG_SET) { 222410c49bfSuwe contrast.param = WSDISPLAYIO_PARAM_CONTRAST; 223410c49bfSuwe if (ioctl(fd, WSDISPLAYIO_SETPARAM, &contrast) < 0) 224c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_PARAM_CONTRAST"); 225410c49bfSuwe pr_field(field_by_value(&contrast.curval), " -> "); 226410c49bfSuwe } 227410c49bfSuwe 2288e45f8abSjmcneill if (field_by_value(&splash_enable)->flags & FLG_SET) { 2298e45f8abSjmcneill if (ioctl(fd, WSDISPLAYIO_SSPLASH, &splash_enable) < 0) 2308e45f8abSjmcneill err(EXIT_FAILURE, "WSDISPLAYIO_SSPLASH"); 2318e45f8abSjmcneill pr_field(field_by_value(&splash_enable), " -> "); 2328e45f8abSjmcneill } 2338e45f8abSjmcneill 2348e45f8abSjmcneill if (field_by_value(&splash_progress)->flags & FLG_SET) { 2358e45f8abSjmcneill if (ioctl(fd, WSDISPLAYIO_SPROGRESS, &splash_progress) < 0) 2368e45f8abSjmcneill err(EXIT_FAILURE, "WSDISPLAYIO_SPROGRESS"); 2378e45f8abSjmcneill pr_field(field_by_value(&splash_progress), " -> "); 2388e45f8abSjmcneill } 2398e45f8abSjmcneill 24092f81ea7Sjmmv if (field_by_value(&msg_default_attrs)->flags & FLG_SET || 24192f81ea7Sjmmv field_by_value(&msg_default_bg)->flags & FLG_SET || 24292f81ea7Sjmmv field_by_value(&msg_default_fg)->flags & FLG_SET || 24392f81ea7Sjmmv field_by_value(&msg_kernel_attrs)->flags & FLG_SET || 24492f81ea7Sjmmv field_by_value(&msg_kernel_bg)->flags & FLG_SET || 24592f81ea7Sjmmv field_by_value(&msg_kernel_fg)->flags & FLG_SET) { 24692f81ea7Sjmmv struct wsdisplay_msgattrs ma; 24792f81ea7Sjmmv 24892f81ea7Sjmmv if (ioctl(fd, WSDISPLAYIO_GMSGATTRS, &ma) < 0) 249c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_GMSGATTRS"); 25092f81ea7Sjmmv 25192f81ea7Sjmmv if (field_by_value(&msg_default_attrs)->flags & FLG_SET) { 25292f81ea7Sjmmv ma.default_attrs = msg_default_attrs; 25392f81ea7Sjmmv pr_field(field_by_value(&msg_default_attrs), " -> "); 25492f81ea7Sjmmv } 25592f81ea7Sjmmv if (ma.default_attrs & WSATTR_WSCOLORS) { 25692f81ea7Sjmmv if (field_by_value(&msg_default_bg)->flags & FLG_SET) { 25792f81ea7Sjmmv ma.default_bg = msg_default_bg; 25892f81ea7Sjmmv pr_field(field_by_value(&msg_default_bg), 25992f81ea7Sjmmv " -> "); 26092f81ea7Sjmmv } 26192f81ea7Sjmmv if (field_by_value(&msg_default_fg)->flags & FLG_SET) { 26292f81ea7Sjmmv ma.default_fg = msg_default_fg; 26392f81ea7Sjmmv pr_field(field_by_value(&msg_default_fg), 26492f81ea7Sjmmv " -> "); 26592f81ea7Sjmmv } 26692f81ea7Sjmmv } 26792f81ea7Sjmmv 26892f81ea7Sjmmv if (field_by_value(&msg_kernel_attrs)->flags & FLG_SET) { 26992f81ea7Sjmmv ma.kernel_attrs = msg_kernel_attrs; 27092f81ea7Sjmmv pr_field(field_by_value(&msg_kernel_attrs), " -> "); 27192f81ea7Sjmmv } 27292f81ea7Sjmmv if (ma.default_attrs & WSATTR_WSCOLORS) { 27392f81ea7Sjmmv if (field_by_value(&msg_kernel_bg)->flags & FLG_SET) { 27492f81ea7Sjmmv ma.kernel_bg = msg_kernel_bg; 27592f81ea7Sjmmv pr_field(field_by_value(&msg_kernel_bg), 27692f81ea7Sjmmv " -> "); 27792f81ea7Sjmmv } 27892f81ea7Sjmmv if (field_by_value(&msg_kernel_fg)->flags & FLG_SET) { 27992f81ea7Sjmmv ma.kernel_fg = msg_kernel_fg; 28092f81ea7Sjmmv pr_field(field_by_value(&msg_kernel_fg), 28192f81ea7Sjmmv " -> "); 28292f81ea7Sjmmv } 28392f81ea7Sjmmv } 28492f81ea7Sjmmv 28592f81ea7Sjmmv if (ioctl(fd, WSDISPLAYIO_SMSGATTRS, &ma) < 0) 286c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_SMSGATTRS"); 28792f81ea7Sjmmv } 28892f81ea7Sjmmv 289fcc698e8Sjmmv scroll_l.which = 0; 290fcc698e8Sjmmv if (field_by_value(&scroll_l.fastlines)->flags & FLG_SET) 291fcc698e8Sjmmv scroll_l.which |= WSDISPLAY_SCROLL_DOFASTLINES; 292fcc698e8Sjmmv if (field_by_value(&scroll_l.slowlines)->flags & FLG_SET) 293fcc698e8Sjmmv scroll_l.which |= WSDISPLAY_SCROLL_DOSLOWLINES; 294fcc698e8Sjmmv if (scroll_l.which != 0 && 295fcc698e8Sjmmv ioctl(fd, WSDISPLAYIO_DSSCROLL, &scroll_l) < 0) 296c799a9c4Sjmmv err(EXIT_FAILURE, "WSDISPLAYIO_DSSCROLL"); 29779884742Schristos if (scroll_l.which & WSDISPLAY_SCROLL_DOFASTLINES) 29879884742Schristos pr_field(field_by_value(&scroll_l.fastlines), " -> "); 29979884742Schristos if (scroll_l.which & WSDISPLAY_SCROLL_DOSLOWLINES) 30079884742Schristos pr_field(field_by_value(&scroll_l.slowlines), " -> "); 30104ee2eceShannken } 302