📄 fhandler_console.cc
字号:
dev_state->nModifiers |= 0x10; } b |= dev_state->nModifiers; /* We can now create the code. */ sprintf (tmp, "\033[M%c%c%c", b + ' ', x + ' ' + 1, y + ' ' + 1); syscall_printf ("mouse: %s at (%d,%d)", sz, x, y); toadd = tmp; nread = 6; } break; case FOCUS_EVENT: case WINDOW_BUFFER_SIZE_EVENT: send_winch_maybe (); /* fall through */ default: continue; } if (toadd) { int res = line_edit (toadd, nread); if (res < 0) goto sig_exit; else if (res) break; }#undef ich } while (buflen) if ((ch = get_readahead ()) < 0) break; else { buf[copied_chars++] = (unsigned char)(ch & 0xff); buflen--; }#undef buf return copied_chars; sig_exit: set_sig_errno (EINTR); return -1;}voidfhandler_console::set_input_state (){ if (TTYISSETF (RSTCONS)) input_tcsetattr (0, &tc->ti);}BOOLfhandler_console::fillin_info (void){ BOOL ret; CONSOLE_SCREEN_BUFFER_INFO linfo; if ((ret = GetConsoleScreenBufferInfo (get_output_handle (), &linfo))) { dev_state->info.winTop = linfo.srWindow.Top; dev_state->info.winBottom = linfo.srWindow.Bottom; dev_state->info.dwWinSize.Y = 1 + linfo.srWindow.Bottom - linfo.srWindow.Top; dev_state->info.dwWinSize.X = 1 + linfo.srWindow.Right - linfo.srWindow.Left; dev_state->info.dwBufferSize = linfo.dwSize; dev_state->info.dwCursorPosition = linfo.dwCursorPosition; dev_state->info.wAttributes = linfo.wAttributes; } else { memset (&dev_state->info, 0, sizeof dev_state->info); dev_state->info.dwWinSize.Y = 25; dev_state->info.dwWinSize.X = 80; dev_state->info.winBottom = 24; } return ret;}voidfhandler_console::scroll_screen (int x1, int y1, int x2, int y2, int xn, int yn){ SMALL_RECT sr1, sr2; CHAR_INFO fill; COORD dest; (void) fillin_info (); sr1.Left = x1 >= 0 ? x1 : dev_state->info.dwWinSize.X - 1; if (y1 == 0) sr1.Top = dev_state->info.winTop; else sr1.Top = y1 > 0 ? y1 : dev_state->info.winBottom; sr1.Right = x2 >= 0 ? x2 : dev_state->info.dwWinSize.X - 1; if (y2 == 0) sr1.Bottom = dev_state->info.winTop; else sr1.Bottom = y2 > 0 ? y2 : dev_state->info.winBottom; sr2.Top = srTop; sr2.Left = 0; sr2.Bottom = srBottom; sr2.Right = dev_state->info.dwWinSize.X - 1; if (sr1.Bottom > sr2.Bottom && sr1.Top <= sr2.Bottom) sr1.Bottom = sr2.Bottom; dest.X = xn >= 0 ? xn : dev_state->info.dwWinSize.X - 1; if (yn == 0) dest.Y = dev_state->info.winTop; else dest.Y = yn > 0 ? yn : dev_state->info.winBottom; fill.Char.AsciiChar = ' '; fill.Attributes = dev_state->current_win32_attr; ScrollConsoleScreenBuffer (get_output_handle (), &sr1, &sr2, dest, &fill); /* ScrollConsoleScreenBuffer on Windows 95 is buggy - when scroll distance * is more than half of screen, filling doesn't work as expected */ if (sr1.Top != sr1.Bottom) if (dest.Y <= sr1.Top) /* forward scroll */ clear_screen (0, 1 + dest.Y + sr1.Bottom - sr1.Top, sr2.Right, sr2.Bottom); else /* reverse scroll */ clear_screen (0, sr1.Top, sr2.Right, dest.Y - 1);}intfhandler_console::open (path_conv *, int flags, mode_t){ HANDLE h; tcinit (get_tty_stuff (flags)); set_io_handle (NULL); set_output_handle (NULL); set_flags ((flags & ~O_TEXT) | O_BINARY); /* Open the input handle as handle_ */ h = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none, OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE) { __seterrno (); return 0; } set_io_handle (h); set_r_no_interrupt (1); // Handled explicitly in read code h = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none, OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE) { __seterrno (); return 0; } set_output_handle (h); if (fillin_info ()) dev_state->default_color = dev_state->info.wAttributes; set_default_attr (); DWORD cflags; if (GetConsoleMode (get_io_handle (), &cflags)) { cflags |= ENABLE_PROCESSED_INPUT; SetConsoleMode (get_io_handle (), ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | cflags); } TTYCLEARF (RSTCONS); set_open_status (); debug_printf ("opened conin$ %p, conout$ %p", get_io_handle (), get_output_handle ()); return 1;}intfhandler_console::close (void){ CloseHandle (get_io_handle ()); CloseHandle (get_output_handle ()); set_io_handle (NULL); set_output_handle (NULL); return 0;}/* * Special console dup to duplicate input and output * handles. */intfhandler_console::dup (fhandler_base *child){ fhandler_console *fhc = (fhandler_console *) child; if (!fhc->open (NULL, get_flags () & ~O_NOCTTY, 0)) system_printf ("error opening console, %E"); return 0;}intfhandler_console::ioctl (unsigned int cmd, void *buf){ switch (cmd) { case TIOCGWINSZ: int st; st = fillin_info (); if (st) { /* *not* the buffer size, the actual screen size... */ /* based on Left Top Right Bottom of srWindow */ ((struct winsize *) buf)->ws_row = dev_state->info.dwWinSize.Y; ((struct winsize *) buf)->ws_col = dev_state->info.dwWinSize.X; syscall_printf ("WINSZ: (row=%d,col=%d)", ((struct winsize *) buf)->ws_row, ((struct winsize *) buf)->ws_col); return 0; } else { syscall_printf ("WINSZ failed"); __seterrno (); return -1; } return 0; case TIOCSWINSZ: (void) bg_check (SIGTTOU); return 0; } return fhandler_base::ioctl (cmd, buf);}intfhandler_console::tcflush (int queue){ int res = 0; if (queue == TCIFLUSH || queue == TCIOFLUSH) { if (!FlushConsoleInputBuffer (get_io_handle ())) { __seterrno (); res = -1; } } return res;}intfhandler_console::output_tcsetattr (int, struct termios const *t){ /* All the output bits we can ignore */ DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1; syscall_printf ("%d = tcsetattr (,%x) (ENABLE FLAGS %x) (lflag %x oflag %x)", res, t, flags, t->c_lflag, t->c_oflag); return res;}intfhandler_console::input_tcsetattr (int, struct termios const *t){ /* Ignore the optional_actions stuff, since all output is emitted instantly */ DWORD oflags; if (!GetConsoleMode (get_io_handle (), &oflags)) oflags = 0; DWORD flags = 0;#if 0 /* Enable/disable LF -> CRLF conversions */ set_r_binary ((t->c_iflag & INLCR) ? 0 : 1);#endif /* There's some disparity between what we need and what's available. We've got ECHO and ICANON, they've got ENABLE_ECHO_INPUT and ENABLE_LINE_INPUT. */ tc->ti = *t; if (t->c_lflag & ECHO) { flags |= ENABLE_ECHO_INPUT; } if (t->c_lflag & ICANON) { flags |= ENABLE_LINE_INPUT; } if (flags & ENABLE_ECHO_INPUT && !(flags & ENABLE_LINE_INPUT)) { /* This is illegal, so turn off the echo here, and fake it when we read the characters */ flags &= ~ENABLE_ECHO_INPUT; } if (t->c_lflag & ISIG) { flags |= ENABLE_PROCESSED_INPUT; } if (use_tty) { flags = 0; // ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; tc->ti.c_iflag = 0; tc->ti.c_lflag = 0; } flags |= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT; int res; if (flags == oflags) res = 0; else { res = SetConsoleMode (get_io_handle (), flags) ? 0 : -1; if (res < 0) __seterrno (); syscall_printf ("%d = tcsetattr (,%x) enable flags %p, c_lflag %p iflag %p", res, t, flags, t->c_lflag, t->c_iflag); } TTYCLEARF (RSTCONS); return res;}intfhandler_console::tcsetattr (int a, struct termios const *t){ int res = output_tcsetattr (a, t); if (res != 0) return res; return input_tcsetattr (a, t);}intfhandler_console::tcgetattr (struct termios *t){ int res; *t = tc->ti; t->c_cflag |= CS8; DWORD flags; if (!GetConsoleMode (get_io_handle (), &flags)) { __seterrno (); res = -1; } else { if (flags & ENABLE_ECHO_INPUT) t->c_lflag |= ECHO; if (flags & ENABLE_LINE_INPUT) t->c_lflag |= ICANON; if (flags & ENABLE_PROCESSED_INPUT) t->c_lflag |= ISIG; /* What about ENABLE_WINDOW_INPUT and ENABLE_MOUSE_INPUT ? */ /* All the output bits we can ignore */ res = 0; } syscall_printf ("%d = tcgetattr (%p) enable flags %p, t->lflag %p, t->iflag %p", res, t, flags, t->c_lflag, t->c_iflag); return res;}fhandler_console::fhandler_console () : fhandler_termios (FH_CONSOLE, -1){}#define FOREGROUND_ATTR_MASK (FOREGROUND_RED | FOREGROUND_GREEN | \ FOREGROUND_BLUE | FOREGROUND_INTENSITY)#define BACKGROUND_ATTR_MASK (BACKGROUND_RED | BACKGROUND_GREEN | \ BACKGROUND_BLUE | BACKGROUND_INTENSITY)voidfhandler_console::set_default_attr (){ dev_state->blink = dev_state->underline = dev_state->reverse = FALSE; dev_state->intensity = INTENSITY_NORMAL; dev_state->fg = dev_state->default_color & FOREGROUND_ATTR_MASK; dev_state->bg = dev_state->default_color & BACKGROUND_ATTR_MASK; dev_state->current_win32_attr = get_win32_attr (); SetConsoleTextAttribute (get_output_handle (), dev_state->current_win32_attr);}WORDfhandler_console::get_win32_attr (){ WORD win_fg = dev_state->fg; WORD win_bg = dev_state->bg; if (dev_state->reverse) { WORD save_fg = win_fg; win_fg = (win_bg & BACKGROUND_RED ? FOREGROUND_RED : 0) | (win_bg & BACKGROUND_GREEN ? FOREGROUND_GREEN : 0) | (win_bg & BACKGROUND_BLUE ? FOREGROUND_BLUE : 0) | (win_fg & FOREGROUND_INTENSITY); win_bg = (save_fg & FOREGROUND_RED ? BACKGROUND_RED : 0) | (save_fg & FOREGROUND_GREEN ? BACKGROUND_GREEN : 0) | (save_fg & FOREGROUND_BLUE ? BACKGROUND_BLUE : 0) | (win_bg & BACKGROUND_INTENSITY); } if (dev_state->underline) win_fg = dev_state->underline_color; /* emulate blink with bright background */ if (dev_state->blink) win_bg |= BACKGROUND_INTENSITY; if (dev_state->intensity == INTENSITY_INVISIBLE) win_fg = win_bg; else if (dev_state->intensity == INTENSITY_BOLD)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -