⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fhandler_console.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* fhandler_console.cc   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. */#include "winsup.h"#include <sys/termios.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <wingdi.h>#include <winuser.h>#include <wincon.h>#include <winnls.h>#include <ctype.h>#include <sys/cygwin.h>#include "cygerrno.h"#include "security.h"#include "fhandler.h"#include "path.h"#include "dtable.h"#include "cygheap.h"#include "sigproc.h"#include "pinfo.h"#include "shared_info.h"#include "cygthread.h"#define CONVERT_LIMIT 4096static BOOLcp_convert (UINT destcp, char *dest, UINT srccp, const char *src, DWORD size){  if (!size)    /* no action */;  else if (destcp == srccp)    {      if (dest != src)	memcpy (dest, src, size);    }  else    {      WCHAR wbuffer[CONVERT_LIMIT]; /* same size as the maximum input, s.b. */      if (!MultiByteToWideChar (srccp, 0, src, size, wbuffer, sizeof (wbuffer)))	return FALSE;      if (!WideCharToMultiByte (destcp, 0, wbuffer, size, dest, size,				NULL, NULL))	return FALSE;    }  return TRUE;}/* The results of GetConsoleCP() and GetConsoleOutputCP() cannot be   cached, because a program or the user can change these values at   any time. */inline BOOLcon_to_str (char *d, const char *s, DWORD sz){  return cp_convert (get_cp (), d, GetConsoleCP (), s, sz);}inline BOOLstr_to_con (char *d, const char *s, DWORD sz){  return cp_convert (GetConsoleOutputCP (), d, get_cp (), s, sz);}/* * Scroll the screen context. * x1, y1 - ul corner * x2, y2 - dr corner * xn, yn - new ul corner * Negative values represents current screen dimensions */#define srTop (dev_state->info.winTop + dev_state->scroll_region.Top)#define srBottom ((dev_state->scroll_region.Bottom < 0) ? dev_state->info.winBottom : dev_state->info.winTop + dev_state->scroll_region.Bottom)#define use_tty ISSTATE (myself, PID_USETTY)const char * get_nonascii_key (INPUT_RECORD&, char *);static console_state NO_COPY *shared_console_info;dev_console NO_COPY *fhandler_console::dev_state;/* Allocate and initialize the shared record for the current console.   Returns a pointer to shared_console_info. */tty_min *fhandler_console::get_tty_stuff (int flags = 0){  if (dev_state)    return &shared_console_info->tty_min_state;  shared_console_info =    (console_state *) open_shared (NULL, 0, cygheap->console_h,				   sizeof (*shared_console_info),				   SH_SHARED_CONSOLE);  dev_state = &shared_console_info->dev_state;  ProtectHandleINH (cygheap->console_h);  if (!shared_console_info->tty_min_state.ntty)    {      shared_console_info->tty_min_state.setntty (TTY_CONSOLE);      shared_console_info->tty_min_state.setsid (myself->sid);      shared_console_info->tty_min_state.set_ctty (TTY_CONSOLE, flags);      dev_state->scroll_region.Bottom = -1;      dev_state->dwLastCursorPosition.X = -1;      dev_state->dwLastCursorPosition.Y = -1;      dev_state->default_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;      dev_state->underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE;      dev_state->dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;      dev_state->meta_mask = LEFT_ALT_PRESSED;      /* Set the mask that determines if an input keystroke is modified by	 META.  We set this based on the keyboard layout language loaded	 for the current thread.  The left <ALT> key always generates	 META, but the right <ALT> key only generates META if we are using	 an English keyboard because many "international" keyboards	 replace common shell symbols ('[', '{', etc.) with accented	 language-specific characters (umlaut, accent grave, etc.).  On	 these keyboards right <ALT> (called AltGr) is used to produce the	 shell symbols and should not be interpreted as META. */      if (PRIMARYLANGID (LOWORD (GetKeyboardLayout (0))) == LANG_ENGLISH)	dev_state->meta_mask |= RIGHT_ALT_PRESSED;    }  return &shared_console_info->tty_min_state;}voidset_console_ctty (){  (void) fhandler_console::get_tty_stuff ();}/* Return the tty structure associated with a given tty number.  If the   tty number is < 0, just return a dummy record. */tty_min *tty_list::get_tty (int n){  static tty_min nada;  if (n == TTY_CONSOLE)    return fhandler_console::get_tty_stuff ();  else if (n >= 0)    return &cygwin_shared->tty.ttys[n];  else    return &nada;}/* Determine if a console is associated with this process prior to a spawn.   If it is, then we'll return 1.  If the console has been initialized, then   set it into a more friendly state for non-cygwin apps. */int __stdcallset_console_state_for_spawn (){  HANDLE h = CreateFile ("CONIN$", GENERIC_READ, FILE_SHARE_WRITE,			 &sec_none_nih, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,			 NULL);  if (h == INVALID_HANDLE_VALUE)    return 0;  if (shared_console_info != NULL)    {      /* ACK.  Temporarily define for use in TTYSETF macro */#     define tc &shared_console_info->tty_min_state      SetConsoleMode (h, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);      TTYSETF (RSTCONS);#     undef tc    }  CloseHandle (h);  return 1;}BOOLfhandler_console::set_raw_win32_keyboard_mode (BOOL new_mode){  BOOL old_mode = dev_state->raw_win32_keyboard_mode;  dev_state->raw_win32_keyboard_mode = new_mode;  syscall_printf ("raw keyboard mode %sabled", dev_state->raw_win32_keyboard_mode ? "en" : "dis");  return old_mode;};voidfhandler_console::set_cursor_maybe (){  CONSOLE_SCREEN_BUFFER_INFO now;  if (!GetConsoleScreenBufferInfo (get_output_handle (), &now))    return;  if (dev_state->dwLastCursorPosition.X != now.dwCursorPosition.X ||      dev_state->dwLastCursorPosition.Y != now.dwCursorPosition.Y)    {      SetConsoleCursorPosition (get_output_handle (), now.dwCursorPosition);      dev_state->dwLastCursorPosition = now.dwCursorPosition;    }}voidfhandler_console::send_winch_maybe (){  SHORT y = dev_state->info.dwWinSize.Y;  SHORT x = dev_state->info.dwWinSize.X;  fillin_info ();  if (y != dev_state->info.dwWinSize.Y || x != dev_state->info.dwWinSize.X)    tc->kill_pgrp (SIGWINCH);}int __stdcallfhandler_console::read (void *pv, size_t buflen){  HANDLE h = get_io_handle ();#define buf ((char *) pv)  int ch;  set_input_state ();  int copied_chars = get_readahead_into_buffer (buf, buflen);  if (copied_chars)    return copied_chars;  HANDLE w4[2];  DWORD nwait;  char tmp[60];  w4[0] = h;  if (cygthread::is ())    nwait = 1;  else    {      w4[1] = signal_arrived;      nwait = 2;    }  for (;;)    {      int bgres;      if ((bgres = bg_check (SIGTTIN)) <= bg_eof)	return bgres;      set_cursor_maybe ();	/* to make cursor appear on the screen immediately */      switch (WaitForMultipleObjects (nwait, w4, FALSE, INFINITE))	{	case WAIT_OBJECT_0:	  break;	case WAIT_OBJECT_0 + 1:	  goto sig_exit;	default:	  __seterrno ();	  return -1;	}      DWORD nread;      INPUT_RECORD input_rec;      const char *toadd = NULL;      if (!ReadConsoleInput (h, &input_rec, 1, &nread))	{	  __seterrno ();	  syscall_printf ("ReadConsoleInput failed, %E");	  return -1;		/* seems to be failure */	}      /* check the event that occurred */      switch (input_rec.EventType)	{	case KEY_EVENT:#define virtual_key_code (input_rec.Event.KeyEvent.wVirtualKeyCode)#define control_key_state (input_rec.Event.KeyEvent.dwControlKeyState)#ifdef DEBUGGING	  /* allow manual switching to/from raw mode via ctrl-alt-scrolllock */	  if (input_rec.Event.KeyEvent.bKeyDown &&	      virtual_key_code == VK_SCROLL &&	      control_key_state & (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED) == LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED	    )	    {	      set_raw_win32_keyboard_mode (!dev_state->raw_win32_keyboard_mode);	      continue;	    }#endif	  if (dev_state->raw_win32_keyboard_mode)	    {	      __small_sprintf (tmp, "\033{%u;%u;%u;%u;%u;%luK",				    input_rec.Event.KeyEvent.bKeyDown,				    input_rec.Event.KeyEvent.wRepeatCount,				    input_rec.Event.KeyEvent.wVirtualKeyCode,				    input_rec.Event.KeyEvent.wVirtualScanCode,				    input_rec.Event.KeyEvent.uChar.UnicodeChar,				    input_rec.Event.KeyEvent.dwControlKeyState);	      toadd = tmp;	      nread = strlen (toadd);	      break;	    }	  if (!input_rec.Event.KeyEvent.bKeyDown)	    continue;#define ich (input_rec.Event.KeyEvent.uChar.AsciiChar)#define wch (input_rec.Event.KeyEvent.uChar.UnicodeChar)#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)	  if (wch == 0 ||	      /* arrow/function keys */	      (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))	    {	      toadd = get_nonascii_key (input_rec, tmp);	      if (!toadd)		continue;	      nread = strlen (toadd);	    }	  else	    {	      tmp[1] = ich;	      /* Need this check since US code page seems to have a bug when		 converting a CTRL-U. */	      if ((unsigned char) ich > 0x7f)		con_to_str (tmp + 1, tmp + 1, 1);	      /* Determine if the keystroke is modified by META.  The tricky		 part is to distinguish whether the right Alt key should be		 recognized as Alt, or as AltGr. */	      bool meta;	      if (wincap.altgr_is_ctrl_alt ())		/* WinNT: AltGr is reported as Ctrl+Alt, and Ctrl+Alt is		   treated just like AltGr.  However, if Ctrl+Alt+key generates		   an ASCII control character, interpret is as META. */		meta = (control_key_state & ALT_PRESSED) != 0		       && ((control_key_state & CTRL_PRESSED) == 0			   || (ich >= 0 && ich <= 0x1f || ich == 0x7f));	      else		/* Win9x: there's no way to distinguish Alt from AltGr, so rely		   on dev_state->meta_mask heuristic (see fhandler_console constructor). */		meta = (control_key_state & dev_state->meta_mask) != 0;	      if (!meta)		toadd = tmp + 1;	      else		{		  tmp[0] = '\033';		  tmp[1] = cyg_tolower (tmp[1]);		  toadd = tmp;		  nread++;		}	    }#undef ich#undef wch#undef ALT_PRESSED#undef CTRL_PRESSED	  break;	case MOUSE_EVENT:	  send_winch_maybe ();	  if (dev_state->use_mouse)	    {	      MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent;	      /* Treat the double-click event like a regular button press */	      if (mouse_event.dwEventFlags == DOUBLE_CLICK)		{		  syscall_printf ("mouse: double-click -> click");		  mouse_event.dwEventFlags = 0;		}	      /* Did something other than a click occur? */	      if (mouse_event.dwEventFlags)		continue;	      /* If the mouse event occurred out of the area we can handle,		 ignore it. */	      int x = mouse_event.dwMousePosition.X;	      int y = mouse_event.dwMousePosition.Y;	      if ((x + ' ' + 1 > 0xFF) || (y + ' ' + 1 > 0xFF))		{		  syscall_printf ("mouse: position out of range");		  continue;		}	      /* Ignore unimportant mouse buttons */	      mouse_event.dwButtonState &= 0x7;	      /* This code assumes Windows never reports multiple button		 events at the same time. */	      int b = 0;	      char sz[32];	      if (mouse_event.dwButtonState == dev_state->dwLastButtonState)		{		  syscall_printf ("mouse: button state unchanged");		  continue;		}	      else if (mouse_event.dwButtonState < dev_state->dwLastButtonState)		{		  b = 3;		  strcpy (sz, "btn up");		}	      else if ((mouse_event.dwButtonState & 1) != (dev_state->dwLastButtonState & 1))		{		  b = 0;		  strcpy (sz, "btn1 down");		}	      else if ((mouse_event.dwButtonState & 2) != (dev_state->dwLastButtonState & 2))		{		  b = 2;		  strcpy (sz, "btn2 down");		}	      else if ((mouse_event.dwButtonState & 4) != (dev_state->dwLastButtonState & 4))		{		  b = 1;		  strcpy (sz, "btn3 down");		}	      /* Remember the current button state */	      dev_state->dwLastButtonState = mouse_event.dwButtonState;	      /* If a button was pressed, remember the modifiers */	      if (b != 3)		{		  dev_state->nModifiers = 0;		  if (mouse_event.dwControlKeyState & SHIFT_PRESSED)		    dev_state->nModifiers |= 0x4;		  if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))		    dev_state->nModifiers |= 0x8;		  if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -