📄 console.c
字号:
*/ g_display.shadow_width = shadow_width( cfg->cols, vid.points, cfg->rows ); bright_background( );}/* * Name: bright_background * Purpose: use bright background colors instead of blinking foreground * Author: Jason Hood * Date: September 23, 2002 * Notes: no other program I know turns it off, so I won't bother, either. */static void bright_background( void ){union REGS r; r.w.ax = 0x1003; r.w.bx = 0; int86( VIDEO_INT, &r, &r );}/* * Name: shadow_width * Purpose: determine the dimension of the shadow * Author: Jason Hood * Date: October 23, 1999 * Passed: width: width of screen * height: character height * lines: last line on screen * Returns: number of characters to use for right edge of shadow * Notes: compensate for the difference between character height and width, * but use no more than two characters. * Is there a better way to do this? */static int shadow_width( int width, int height, int lines ){ if (width < 80 || height == 0) width = 1; else if (width > 90) width = 2; else { lines = height * lines; if (lines <= 200) lines = 6; else if (lines <= 350) lines = 10; else if (lines <= 400) lines = 12; else /* lines <= 480 */ lines = 14; width = (height > lines) + 1; } return( width );}/* * Name: kbd_int * Purpose: keyboard hardware interrupt handler * Author: Jason Hood * Date: August 17, 2002 * Notes: the normal BIOS function only allows the standard control * characters (Ctrl+@,A-Z,[\]^_). It also does not allow * Alt+Keypad0 as NUL (0 is used to indicate no input). Finally, * it has its own idea about what a scan code is. This function * overcomes all those problems, except for the alternate scan * codes for F11/12 & Ctrl+PrtSc. It fools the BIOS into thinking * the shift keys have been released. So now instead of Ctrl+1 being * ignored, it generates '1', but with my Ctrl flag set. * I'm not sure about other keyboards, but mine generates a prefixed * shift code for the grey keys. It also generates the prefixed * shift break code for Shift+Grey/ before the Grey/ code, then the * prefixed shift make code after (ie: instead of 2A E035 E0B5 AA, * it is 2A E0AA E035 E0B5 E02A AA). Let's ignore the prefixed * shifts altogether. * Unlike BIOS, I treat the shifts as one key. This will lead to * Shift being unrecognised if you press both keys, then release * one. It turns out BIOS has this trouble, anyway, with Ctrl & Alt. * 020903: After playing around with KEYB.COM, may as well only disable * control (both of them), to let the AltGr characters go through. * 020923: Test for the Menu key specially. * 021023: Use kbd_active to avoid potential shell problems. */static void kbd_int( void ){ if (!kbd_active) return; /* * Ask the keyboard for the scancode. */ kbd_scancode = inportb( 0x60 ); /* * Test for the prefix code. */ if (kbd_scancode == 0xE0) { kbd_prefix = 1; return; } if ((kbd_scancode == 0x2a || kbd_scancode == 0x36) && !kbd_prefix) kbd_shift |= _SHIFT; /* Unprefixed Left- or RightShift pressed */ else if (kbd_scancode == 0x1d) /* either Ctrl */ kbd_shift |= _CTRL; else if (kbd_scancode == 0x38) /* either Alt */ kbd_shift |= _ALT; else if ((kbd_scancode == 0xaa || kbd_scancode == 0xb6) && !kbd_prefix) kbd_shift &= ~_SHIFT; /* Unprefixed Left- or RightShift released */ else if (kbd_scancode == 0x9d) /* either Ctrl */ kbd_shift &= ~_CTRL; else if (kbd_scancode == 0xb8) /* either Alt */ kbd_shift &= ~_ALT; else if (kbd_scancode == 0x5d) {/* Menu */ kbd_menu = TRUE; kbd_prefix = 0; return; } /* * Read the BIOS shift states and turn off the controls. */ kbd_bios_shift = _farpeekw( _dos_ds, 0x417 ) & ~0x0104; /* * Leave BIOS Ctrl on to allow for Shift+ and/or Ctrl+PrtSc. * (Ctrl+Break is unaffected.) */ if (kbd_scancode == 0x37 && kbd_shift && kbd_prefix) kbd_bios_shift |= 4; /* * Turn BIOS Alt off to allow Alt+KP0 as NUL, but only if no other * number has been entered yet. */ else if ((kbd_shift & _ALT) && kbd_scancode == 0x52 && !kbd_prefix && _farnspeekb( 0x419 ) == 0) kbd_bios_shift &= ~0x0208; _farnspokew( 0x417, kbd_bios_shift ); kbd_prefix = 0;}/* * Translate the BIOS scancode back to the hardware scancode. * These are from 0x54 to 0xA6. */static int bios_to_scan[] = { _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _F10, /* Shift */ _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _F10, /* Ctrl (unused) */ _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _F10, /* Alt */ _PRTSC, /* Ctrl */ _LEFT, _RIGHT, _END, _PGDN, _HOME, /* Ctrl (unused) */ _1, _2, _3, _4, _5, _6, _7, _8, _9, _0, _MINUS, _EQUALS, /* Alt */ _PGUP, /* Ctrl */ _F11, _F12, _F11, _F12, _F11, _F12, _F11, _F12, /* plain Shift Ctrl Alt */ _UP, _GREY_MINUS, _CENTER, _GREY_PLUS, _DOWN, /* Ctrl (unused) */ _INS, _DEL, _TAB, _GREY_SLASH, _GREY_STAR, /* Ctrl (unused) */ _HOME, _UP, _PGUP, 0, _LEFT, 0, _RIGHT, 0, _END, /* Alt */ _DOWN, _PGDN, _INS, _DEL, _GREY_SLASH, _TAB, _GREY_ENTER /* Alt */};/* * Name: getkey * Purpose: get keyboard input * Author: Jason Hood * Date: August 17, 2002 * Passed: None * Notes: Uses the BIOS to read the next keyboard character. Service 0x00 * is the XT keyboard read. Service 0x10 is the extended keyboard * read. Test for a bunch of special cases. Allow the user to enter * any ASCII or Extended ASCII code as a normal text character. * * 020903: updated to reflect the new translate_key(). * 020923: recognise the Menu key as the PullDown function. */long getkey( void ){unsigned key;register int scan, ch;long kee;go_again: kbd_shift &= ~_FUNCTION; /* turn off any previous extended key */ /* * lets spin on waitkey until the user presses a key. waitkey polls * the keyboard and returns 0 when a key is waiting. */ while (waitkey( mode.enh_kbd )) { if (kbd_menu) { kbd_menu = FALSE; return( PullDown | _FUNCTION ); } __dpmi_yield( ); } /* * _bios_keybrd == int 16. It returns the scan code in ah, hi part of key, * and the ascii key code in al, lo part of key. If the character was * entered via ALT-xxx, the scan code, hi part of key, is 0. */ if (mode.enh_kbd) { key = _bios_keybrd( 0x10 ); /* * couple of special cases: * on the numeric keypad, some keys return 0xe0 in the lo byte. * 1) if user enters Alt-224, then the hi byte == 0 and lo byte == 0xe0. * we need to let this get thru as an Extended ASCII char. 2) although * we could make the cursor pad keys do different functions than the * numeric pad cursor keys, let's set the 0xe0 in the lo byte to zero * and forget about support for those keys. */ if ((key & 0x00ff) == 0x00e0 && (key & 0xff00) != 0) { key &= 0xff00; kbd_shift |= _FUNCTION; } } else key = _bios_keybrd( 0 ); /* * With the new interrupt routine, Ctrl-Break returns 0 in both * character and scan code. */ if (key == 0 && (kbd_shift & _CTRL)) return( _CONTROL_BREAK ); scan = (key & 0xff00) >> 8; ch = key & 0x00ff; /* * At the bottom of page 195 in MASM 6.0 ref manual, "..when the keypad * ENTER and / keys are read through the BIOS interrupt 16h, only E0h * is seen since the interrupt only gives one-byte scan codes." */ if (scan == 0xe0) { if (ch == 13) { scan = _GREY_ENTER; ch = 0; } else if (ch == '/') scan = _GREY_SLASH; /* * Remap the BIOS scan code to the hardware. */ } else if (scan >= 0x54 && scan <= 0xA6) scan = bios_to_scan[scan - 0x54]; /* * My machine at home is sorta weird. On every machine that I've * tested at the awffice, the ALT-xxx combination returns 0 for the * scan byte and xxx for the ASCII code. My machine returns 184 (decimal) * as the scan code?!?!? I added the next two lines for my machine at * home. I wonder if someone forgot to zero out ah for Alt keypad entry * when they wrote my bios? */ else if (scan == 0 || scan >= 0x80) return( ch ); /* * Convert the scan code to the function key. */ else { scan += 255; /* * Special case for Alt+KP0 to enter the NUL character, and to * test for AltGr characters. */ if (kbd_shift & _ALT) { if (scan == _INS && !(kbd_shift & _FUNCTION)) return( 0 ); if (ch != 0) return( ch ); } } kee = translate_key( scan, kbd_shift, ch ); if (kee == ERROR) goto go_again; return( kee );}/* * Name: waitkey * Purpose: call the BIOS keyboard status subfunction * Date: October 31, 1992 * Passed: enh_keyboard: boolean - TRUE if 101 keyboard, FALSE otherwise * Returns: 1 if no key ready, 0 if key is waiting * Notes: lets get the keyboard status so we can spin on this function until * the user presses a key. some OS replacements for DOS want * application programs to poll the keyboard instead of rudely * sitting on the BIOS read key function. */int waitkey( int enh_keyboard ){ return( _bios_keybrd( enh_keyboard ? 0x11 : 0x01 ) == 0 ? 1 : 0 );}/* * Name: capslock_active * Purpose: To find out if Caps Lock is active * Date: September 1, 1993 * Returns: Non zero if Caps Lock is active, * Zero if Caps Lock is not active. * Note: The function reads directly the BIOS variable * at address 0040h:0017h bit 6 * jmh 020903: Make use of the kbd_bios_shift variable. */int capslock_active( void ){ return( kbd_bios_shift & 0x40 );}/* * Name: numlock_active * Purpose: To find out if Num Lock is active * Date: September 3, 2002 * Returns: Non zero if Num Lock is active, * Zero if Num Lock is not active. * Note: Same as Caps Lock, but using bit 5. */int numlock_active( void ){ return( kbd_bios_shift & 0x20 );}/* * Name: flush_keyboard * Purpose: flush keys from the keyboard buffer * Date: June 5, 1993 * Passed: enh_keyboard: boolean - TRUE if 101 keyboard, FALSE otherwise * Returns: 1 if no key ready, 0 if key is waiting * Notes: lets get the keyboard status so we can spin on this function until * the user presses a key. some OS replacements for DOS want * application programs to poll the keyboard instead of rudely * sitting on the BIOS read key function. */void flush_keyboard( void ){ if (mode.enh_kbd) { while (!waitkey( mode.enh_kbd )) (void)_bios_keybrd( 0x10 ); } else { while (!waitkey( mode.enh_kbd )) (void)_bios_keybrd( 0 ); }}/* Name: page * Purpose: Change the text screen page * Author: Jason Hood * Date: December 28, 1996 * Passed: payg: desired page number * Notes: use standard BIOS video interrupt 0x10 to set the set. */void page( unsigned char payg )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -