console.c

Go to the documentation of this file.
00001 #include "stddef.h"
00002 #include "console.h"
00003 #include <gpxe/process.h>
00004 #include <gpxe/nap.h>
00005 
00006 /** @file */
00007 
00008 FILE_LICENCE ( GPL2_OR_LATER );
00009 
00010 /**
00011  * Write a single character to each console device.
00012  *
00013  * @v character         Character to be written
00014  * @ret None            -
00015  * @err None            -
00016  *
00017  * The character is written out to all enabled console devices, using
00018  * each device's console_driver::putchar() method.
00019  *
00020  */
00021 void putchar ( int character ) {
00022         struct console_driver *console;
00023 
00024         /* Automatic LF -> CR,LF translation */
00025         if ( character == '\n' )
00026                 putchar ( '\r' );
00027 
00028         for_each_table_entry ( console, CONSOLES ) {
00029                 if ( ( ! console->disabled ) && console->putchar )
00030                         console->putchar ( character );
00031         }
00032 }
00033 
00034 /**
00035  * Check to see if any input is available on any console.
00036  *
00037  * @v None              -
00038  * @ret console         Console device that has input available, if any.
00039  * @ret NULL            No console device has input available.
00040  * @err None            -
00041  *
00042  * All enabled console devices are checked once for available input
00043  * using each device's console_driver::iskey() method.  The first
00044  * console device that has available input will be returned, if any.
00045  *
00046  */
00047 static struct console_driver * has_input ( void ) {
00048         struct console_driver *console;
00049 
00050         for_each_table_entry ( console, CONSOLES ) {
00051                 if ( ( ! console->disabled ) && console->iskey ) {
00052                         if ( console->iskey () )
00053                                 return console;
00054                 }
00055         }
00056         return NULL;
00057 }
00058 
00059 /**
00060  * Read a single character from any console.
00061  *
00062  * @v None              -
00063  * @ret character       Character read from a console.
00064  * @err None            -
00065  *
00066  * A character will be read from the first enabled console device that
00067  * has input available using that console's console_driver::getchar()
00068  * method.  If no console has input available to be read, this method
00069  * will block.  To perform a non-blocking read, use something like
00070  *
00071  * @code
00072  *
00073  *   int key = iskey() ? getchar() : -1;
00074  *
00075  * @endcode
00076  *
00077  * The character read will not be echoed back to any console.
00078  *
00079  */
00080 int getchar ( void ) {
00081         struct console_driver *console;
00082         int character;
00083 
00084         while ( 1 ) {
00085                 console = has_input();
00086                 if ( console && console->getchar ) {
00087                         character = console->getchar ();
00088                         break;
00089                 }
00090 
00091                 /* Doze for a while (until the next interrupt).  This works
00092                  * fine, because the keyboard is interrupt-driven, and the
00093                  * timer interrupt (approx. every 50msec) takes care of the
00094                  * serial port, which is read by polling.  This reduces the
00095                  * power dissipation of a modern CPU considerably, and also
00096                  * makes Etherboot waiting for user interaction waste a lot
00097                  * less CPU time in a VMware session.
00098                  */
00099                 cpu_nap();
00100 
00101                 /* Keep processing background tasks while we wait for
00102                  * input.
00103                  */
00104                 step();
00105         }
00106 
00107         /* CR -> LF translation */
00108         if ( character == '\r' )
00109                 character = '\n';
00110 
00111         return character;
00112 }
00113 
00114 /** Check for available input on any console.
00115  *
00116  * @v None              -
00117  * @ret True            Input is available on a console
00118  * @ret False           Input is not available on any console
00119  * @err None            -
00120  *
00121  * All enabled console devices are checked once for available input
00122  * using each device's console_driver::iskey() method.  If any console
00123  * device has input available, this call will return True.  If this
00124  * call returns True, you can then safely call getchar() without
00125  * blocking.
00126  *
00127  */
00128 int iskey ( void ) {
00129         return has_input() ? 1 : 0;
00130 }

Generated on Tue Apr 6 20:00:51 2010 for gPXE by  doxygen 1.5.7.1