1 /* $NetBSD: iteconfig.c,v 1.10 2018/01/23 21:06:25 sevan Exp $ */ 2 /* 3 * Copyright (c) 1994 Christian E. Hopps 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Christian E. Hopps 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 */ 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __RCSID("$NetBSD: iteconfig.c,v 1.10 2018/01/23 21:06:25 sevan Exp $"); 35 #endif 36 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 #include <sys/ioctl.h> 40 #include <sys/queue.h> 41 42 #if !defined(amiga) && !defined(atari) 43 #error "This source is not suitable for this architecture!" 44 #endif 45 46 #if defined(amiga) 47 #include <amiga/dev/grfabs_reg.h> 48 #include <amiga/dev/viewioctl.h> 49 #include <amiga/dev/iteioctl.h> 50 #endif /* defined(amiga) */ 51 52 #if defined(atari) 53 #include <atari/dev/grfabs_reg.h> 54 #include <atari/dev/viewioctl.h> 55 #include <atari/dev/iteioctl.h> 56 #endif /* defined(atari) */ 57 58 #include <err.h> 59 #include <errno.h> 60 #include <fcntl.h> 61 #include <limits.h> 62 #include <stdio.h> 63 #include <stdlib.h> 64 #include <string.h> 65 #include <termios.h> 66 #include <unistd.h> 67 68 #include "pathnames.h" 69 70 int initialize(const char *, struct itewinsize *, struct itebell *, 71 struct itewinsize *, struct itebell *); 72 void printcmap(colormap_t *, int); 73 void xioctl(int, int, void *); 74 colormap_t *xgetcmap(int, int); 75 long xstrtol(char *); 76 static void usage(void) __dead; 77 78 int 79 main(int argc, char *argv[]) 80 { 81 struct itewinsize is, newis; 82 struct itebell ib, newib; 83 struct winsize ws; 84 colormap_t *cm; 85 const char *file = _PATH_CONSOLE; 86 int ch, fd, i, iflag, max_colors, did_reset; 87 long val; 88 89 iflag = 0; 90 did_reset = 0; 91 92 fd = initialize(_PATH_CONSOLE, &is, &ib, &newis, &newib); 93 94 while ((ch = getopt(argc, argv, "D:H:P:T:V:W:X:Y:d:f:h:ip:t:v:w:x:y:")) 95 != -1) { 96 switch (ch) { 97 case 'D': /* undocumented backward compat */ 98 case 'd': 99 newis.depth = xstrtol(optarg); 100 break; 101 case 'f': 102 if (did_reset) 103 break; 104 if (fd != -1) 105 close(fd); 106 file = optarg; 107 fd = initialize(optarg, &is, &ib, &newis, &newib); 108 did_reset = optreset = optind = 1; 109 break; 110 case 'H': /* undocumented backward compat */ 111 case 'h': 112 newis.height = xstrtol(optarg); 113 break; 114 case 'i': 115 iflag = 1; 116 break; 117 case 'p': 118 newib.pitch = xstrtol(optarg); 119 break; 120 case 't': 121 newib.msec = xstrtol(optarg); 122 break; 123 case 'V': /* undocumented backward compat */ 124 case 'v': 125 newib.volume = xstrtol(optarg); 126 break; 127 case 'W': /* undocumented backward compat */ 128 case 'w': 129 newis.width = xstrtol(optarg); 130 break; 131 case 'X': /* undocumented backward compat */ 132 case 'x': 133 newis.x = xstrtol(optarg); 134 break; 135 case 'Y': /* undocumented backward compat */ 136 case 'y': 137 newis.y = xstrtol(optarg); 138 break; 139 case '?': 140 default: 141 usage(); 142 /* NOTREACHED */ 143 } 144 } 145 argc -= optind; 146 argv += optind; 147 if(fd == -1) 148 err(1, "open \"%s\"", file); 149 150 if (memcmp(&newis, &is, sizeof(is))) { 151 xioctl(fd, ITEIOCSWINSZ, &newis); 152 xioctl(fd, ITEIOCGWINSZ, &is); 153 } 154 if (memcmp(&newib, &ib, sizeof(ib))) { 155 xioctl(fd, ITEIOCSBELL, &newib); 156 xioctl(fd, ITEIOCGBELL, &ib); 157 } 158 159 /* 160 * get, set and get colors again 161 */ 162 i = 0; 163 max_colors = 1 << is.depth; 164 cm = xgetcmap(fd, max_colors); 165 while (argc--) { 166 val = xstrtol(*argv++); 167 if (i >= max_colors) { 168 warnx("warning: too many colors"); 169 break; 170 } 171 cm->entry[i] = val; 172 i++; 173 } 174 xioctl(fd, VIOCSCMAP, cm); 175 free(cm); 176 cm = xgetcmap(fd, max_colors); 177 178 /* do tty stuff to get it to register the changes. */ 179 xioctl(fd, TIOCGWINSZ, &ws); 180 181 if (iflag) { 182 printf("tty size: rows %d cols %d\n", ws.ws_row, ws.ws_col); 183 printf("ite size: w: %d h: %d d: %d [x: %d y: %d]\n", 184 is.width, is.height, is.depth, is.x, is.y); 185 printf("ite bell: vol: %d millisec: %d pitch: %d\n", 186 ib.volume, ib.msec, ib.pitch); 187 printcmap(cm, ws.ws_col); 188 } 189 close(fd); 190 exit(0); 191 } 192 193 void 194 xioctl(int fd, int cmd, void *addr) 195 { 196 if (ioctl(fd, cmd, addr) == -1) 197 err(1, "ioctl"); 198 } 199 200 long 201 xstrtol(char *s) 202 { 203 long rv; 204 205 errno = 0; 206 rv = strtol(s, NULL, 0); 207 if (errno == ERANGE && (rv == LONG_MIN || rv == LONG_MAX)) 208 err(1, "bad format: \"%s\"", s); 209 return(rv); 210 } 211 212 colormap_t * 213 xgetcmap(int fd, int ncolors) 214 { 215 colormap_t *cm; 216 217 cm = malloc(sizeof(colormap_t) + ncolors * sizeof(u_long)); 218 if (cm == NULL) 219 err(1, "malloc"); 220 cm->first = 0; 221 cm->size = ncolors; 222 cm->entry = (u_long *) & cm[1]; 223 xioctl(fd, VIOCGCMAP, cm); 224 return(cm); 225 } 226 227 void 228 printcmap(colormap_t *cm, int ncols) 229 { 230 int i, nel; 231 232 switch (cm->type) { 233 case CM_MONO: 234 printf("monochrome"); 235 return; 236 case CM_COLOR: 237 printf("color levels: red: %d green: %d blue: %d", 238 cm->red_mask + 1, cm->green_mask + 1, cm->blue_mask + 1); 239 break; 240 case CM_GREYSCALE: 241 printf("greyscale levels: %d", cm->grey_mask + 1); 242 break; 243 } 244 printf("\n"); 245 246 nel = ncols / 11 - 1; 247 for (i = 0; i < cm->size; i++) { 248 printf("0x%08lx ", cm->entry[i]); 249 if ((i + 1) % nel == 0) 250 printf("\n"); 251 } 252 if ((i + 1) % nel) 253 printf("\n"); 254 } 255 256 int 257 initialize(file, is, ib, newis, newib) 258 const char *file; 259 struct itewinsize *is, *newis; 260 struct itebell *ib, *newib; 261 { 262 int fd; 263 264 fd = open(file, O_RDONLY | O_NONBLOCK); 265 if (fd == -1) 266 return(-1); 267 268 xioctl(fd, ITEIOCGWINSZ, is); 269 xioctl(fd, ITEIOCGBELL, ib); 270 271 memcpy(newis, is, sizeof(*is)); 272 memcpy(newib, ib, sizeof(*ib)); 273 return(fd); 274 } 275 276 static void 277 usage(void) 278 { 279 fprintf(stderr, "%s\n\t\t%s\n\t\t%s\n", 280 "usage: iteconfig [-i] [-f file] [-v volume] [-p pitch] [-t msec]", 281 "[-w width] [-h height] [-d depth] [-x off] [-y off]", 282 "[color ...]"); 283 exit(1); 284 } 285