選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

console.c 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "stddef.h"
  2. #include <ipxe/console.h>
  3. #include <ipxe/process.h>
  4. #include <ipxe/nap.h>
  5. /** @file */
  6. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  7. /** Current console usage */
  8. int console_usage = CONSOLE_USAGE_STDOUT;
  9. /** Console width */
  10. unsigned int console_width = CONSOLE_DEFAULT_WIDTH;
  11. /** Console height */
  12. unsigned int console_height = CONSOLE_DEFAULT_HEIGHT;
  13. /**
  14. * Write a single character to each console device
  15. *
  16. * @v character Character to be written
  17. *
  18. * The character is written out to all enabled console devices, using
  19. * each device's console_driver::putchar() method.
  20. */
  21. void putchar ( int character ) {
  22. struct console_driver *console;
  23. /* Automatic LF -> CR,LF translation */
  24. if ( character == '\n' )
  25. putchar ( '\r' );
  26. for_each_table_entry ( console, CONSOLES ) {
  27. if ( ( ! ( console->disabled & CONSOLE_DISABLED_OUTPUT ) ) &&
  28. ( console_usage & console->usage ) &&
  29. console->putchar )
  30. console->putchar ( character );
  31. }
  32. }
  33. /**
  34. * Check to see if any input is available on any console
  35. *
  36. * @ret console Console device that has input available, or NULL
  37. *
  38. * All enabled console devices are checked once for available input
  39. * using each device's console_driver::iskey() method. The first
  40. * console device that has available input will be returned, if any.
  41. */
  42. static struct console_driver * has_input ( void ) {
  43. struct console_driver *console;
  44. for_each_table_entry ( console, CONSOLES ) {
  45. if ( ( ! ( console->disabled & CONSOLE_DISABLED_INPUT ) ) &&
  46. console->iskey ) {
  47. if ( console->iskey () )
  48. return console;
  49. }
  50. }
  51. return NULL;
  52. }
  53. /**
  54. * Read a single character from any console
  55. *
  56. * @ret character Character read from a console.
  57. *
  58. * A character will be read from the first enabled console device that
  59. * has input available using that console's console_driver::getchar()
  60. * method. If no console has input available to be read, this method
  61. * will block. To perform a non-blocking read, use something like
  62. *
  63. * @code
  64. *
  65. * int key = iskey() ? getchar() : -1;
  66. *
  67. * @endcode
  68. *
  69. * The character read will not be echoed back to any console.
  70. */
  71. int getchar ( void ) {
  72. struct console_driver *console;
  73. int character;
  74. while ( 1 ) {
  75. console = has_input();
  76. if ( console && console->getchar ) {
  77. character = console->getchar ();
  78. break;
  79. }
  80. /* Doze for a while (until the next interrupt). This works
  81. * fine, because the keyboard is interrupt-driven, and the
  82. * timer interrupt (approx. every 50msec) takes care of the
  83. * serial port, which is read by polling. This reduces the
  84. * power dissipation of a modern CPU considerably, and also
  85. * makes Etherboot waiting for user interaction waste a lot
  86. * less CPU time in a VMware session.
  87. */
  88. cpu_nap();
  89. /* Keep processing background tasks while we wait for
  90. * input.
  91. */
  92. step();
  93. }
  94. /* CR -> LF translation */
  95. if ( character == '\r' )
  96. character = '\n';
  97. return character;
  98. }
  99. /**
  100. * Check for available input on any console
  101. *
  102. * @ret is_available Input is available on a console
  103. *
  104. * All enabled console devices are checked once for available input
  105. * using each device's console_driver::iskey() method. If any console
  106. * device has input available, this call will return true. If this
  107. * call returns true, you can then safely call getchar() without
  108. * blocking.
  109. */
  110. int iskey ( void ) {
  111. return has_input() ? 1 : 0;
  112. }
  113. /**
  114. * Configure console
  115. *
  116. * @v config Console configuration
  117. * @ret rc Return status code
  118. *
  119. * The configuration is passed to all configurable consoles, including
  120. * those which are currently disabled. Consoles may choose to enable
  121. * or disable themselves depending upon the configuration.
  122. *
  123. * If configuration fails, then all consoles will be reset.
  124. */
  125. int console_configure ( struct console_configuration *config ) {
  126. struct console_driver *console;
  127. int rc;
  128. /* Reset console width and height */
  129. console_set_size ( CONSOLE_DEFAULT_WIDTH, CONSOLE_DEFAULT_HEIGHT );
  130. /* Try to configure each console */
  131. for_each_table_entry ( console, CONSOLES ) {
  132. if ( ( console->configure ) &&
  133. ( ( rc = console->configure ( config ) ) != 0 ) )
  134. goto err;
  135. }
  136. return 0;
  137. err:
  138. /* Reset all consoles, avoiding a potential infinite loop */
  139. if ( config )
  140. console_reset();
  141. return rc;
  142. }