Home | History | Annotate | Line # | Download | only in common
console.c revision 1.1
      1 /*	$NetBSD: console.c,v 1.1 2006/04/07 14:21:29 cherry Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998 Michael Smith <msmith (at) freebsd.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 
     31 #include <lib/libsa/stand.h>
     32 #include <lib/libkern/libkern.h>
     33 
     34 #include "bootstrap.h"
     35 /*
     36  * Core console support
     37  */
     38 
     39 static int	cons_set(struct env_var *ev, int flags, void *value);
     40 static int	cons_find(char *name);
     41 
     42 /*
     43  * Detect possible console(s) to use.  The first probed console
     44  * is marked active.  Also create the console variable.
     45  *
     46  * XXX Add logic for multiple console support.
     47  */
     48 void
     49 cons_probe(void)
     50 {
     51     int			cons;
     52     int			active;
     53     char		*prefconsole;
     54 
     55     /* Do all console probes */
     56     for (cons = 0; consoles[cons] != NULL; cons++) {
     57 	consoles[cons]->c_flags = 0;
     58  	consoles[cons]->c_probe(consoles[cons]);
     59     }
     60     /* Now find the first working one */
     61     active = -1;
     62     for (cons = 0; consoles[cons] != NULL && active == -1; cons++) {
     63 	consoles[cons]->c_flags = 0;
     64  	consoles[cons]->c_probe(consoles[cons]);
     65 	if (consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT))
     66 	    active = cons;
     67     }
     68 
     69     /* Check to see if a console preference has already been registered */
     70     prefconsole = getenv("console");
     71     if (prefconsole != NULL)
     72 	prefconsole = strdup(prefconsole);
     73     if (prefconsole != NULL) {
     74 	unsetenv("console");		/* we want to replace this */
     75 	for (cons = 0; consoles[cons] != NULL; cons++)
     76 	    /* look for the nominated console, use it if it's functional */
     77 	    if (!strcmp(prefconsole, consoles[cons]->c_name) &&
     78 		(consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT)))
     79 		active = cons;
     80 	free(prefconsole);
     81     }
     82     if (active == -1)
     83 	active = 0;
     84     consoles[active]->c_flags |= (C_ACTIVEIN | C_ACTIVEOUT);
     85     consoles[active]->c_init(0);
     86 
     87     printf("Console: %s\n", consoles[active]->c_desc);
     88     env_setenv("console", EV_VOLATILE, consoles[active]->c_name, (ev_sethook_t *) cons_set,
     89 	env_nounset);
     90 }
     91 
     92 int
     93 getchar(void)
     94 {
     95     int		cons;
     96     int		rv;
     97 
     98     /* Loop forever polling all active consoles */
     99     for(;;)
    100 	for (cons = 0; consoles[cons] != NULL; cons++)
    101 	    if ((consoles[cons]->c_flags & C_ACTIVEIN) &&
    102 		((rv = consoles[cons]->c_in()) != -1))
    103 		return(rv);
    104 }
    105 
    106 int
    107 ischar(void)
    108 {
    109     int		cons;
    110 
    111     for (cons = 0; consoles[cons] != NULL; cons++)
    112 	if ((consoles[cons]->c_flags & C_ACTIVEIN) &&
    113 	    (consoles[cons]->c_ready() != 0))
    114 		return(1);
    115     return(0);
    116 }
    117 
    118 void
    119 putchar(int c)
    120 {
    121     int		cons;
    122 
    123     /* Expand newlines */
    124     if (c == '\n')
    125 	putchar('\r');
    126 
    127     for (cons = 0; consoles[cons] != NULL; cons++)
    128 	if (consoles[cons]->c_flags & C_ACTIVEOUT)
    129 	    consoles[cons]->c_out(c);
    130 }
    131 
    132 static int
    133 cons_find(char *name)
    134 {
    135     int		cons;
    136 
    137     for (cons = 0; consoles[cons] != NULL; cons++)
    138 	if (!strcmp(consoles[cons]->c_name, name))
    139 	    return(cons);
    140     return(-1);
    141 }
    142 
    143 
    144 /*
    145  * Select a console.
    146  *
    147  * XXX Note that the console system design allows for some extension
    148  *     here (eg. multiple consoles, input/output only, etc.)
    149  */
    150 static int
    151 cons_set(struct env_var *ev, int flags, void *value)
    152 {
    153     int		cons, active;
    154 
    155     if ((value == NULL) || ((active = cons_find(value)) == -1)) {
    156 	if (value != NULL)
    157 	    printf("no such console '%s'\n", (char *)value);
    158 	printf("Available consoles:\n");
    159 	for (cons = 0; consoles[cons] != NULL; cons++)
    160 	    printf("    %s\n", consoles[cons]->c_name);
    161 	return(CMD_ERROR);
    162     }
    163 
    164     /* disable all current consoles */
    165     for (cons = 0; consoles[cons] != NULL; cons++)
    166 	consoles[cons]->c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT);
    167 
    168     /* enable selected console */
    169     consoles[active]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
    170     consoles[active]->c_init(0);
    171 
    172     env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
    173     return(CMD_OK);
    174 }
    175