· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Virtual Terminal Keyboard

Virtual terminal ÀÔ·Â

  • VT(tty)·ÎºÎÅÍ ±ÛÀÚ¸¦ ÀԷ¹޴ ¿¹Á¦ ÀÔ´Ï´Ù. ÀÌ°ÍÀº ¸¹Àº ºÐµéÀÌ ±Ã±ÀÇØ ÇÏ´Â ºÎºÐÀ¸·Î ¾Ë°í ÀÖ½À´Ï´Ù. ÁÁÀº Âü°íÀÚ·á µÇ±â¸¦ ¹Ù¶ø´Ï´Ù.
  • ´ëºÎºÐÀÇ ±¸Çö¼³¸íÀº termios»ç¿ë¹ý¿¡ ´ëÇÑ ¹®¼­¸¦ ã¾Æº¸½Ã¸é ±×¸® ¾î·ÆÁö ¾Ê°Ô ±¸Çö °¡´ÉÇÕ´Ï´Ù. ÇÊÀÚ´Â "man termios"¿¡¼­ ÀÌ·¯ÇÑ ¹æ¹ýÀ» ã¾Ò½À´Ï´Ù.
  • ÇØ´ç Âü°í ÀÚ·á·Î´Â "/usr/include/linux/vt.h" ¹× "/usr/include/linux/kd.h" ¸¦ ÂüÁ¶ÇÏ½Ã¸é ¿©·¯°¡Áö ´Ù¾çÇÑ ±â´ÉÀ» »ç¿ëÇÒ¼ö ÀÖ½À´Ï´Ù.
  • ¾Æ·¡ÀÇ ¿¹Á¦´Â ´ÜÁ¡ÀÌ ÇÑ°¡Áö Àִµ¥ ÀϺΠ۸¦ ÀԷ¹ÞÁö ¸øÇÕ´Ï´Ù. ¿¹¸¦ µé¸é "ÇÑ/¿µ" Å°¸¦ ¿¹·Î µé¼ö ÀÖ½À´Ï´Ù. ÀÌ°ÍÀ» ÀԷ¹޵µ·Ï ÇÏ·Á¸é VT mode¸¦ »ç¿ëÇÏ¸é ¹æ¹ýÀÌ ¾ø´Âµí Çϸç K_RAW mode¸¦ »ç¿ëÇØ¾ß ÇÕ´Ï´Ù. ¶ÇÇÑ À̸¦ »ç¿ëÇÏ°Ô µÇ¸é Å°º¸µå Äڵ尡 Scan code·Î ÀÔ·ÂÀÌ µé¾î¿É´Ï´Ù. ¶ÇÇÑ struct vt_mode¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ¾Æ´Ï°í ioctl cmd KDGKBMODE¸¦ »ç¿ëÇÏ¿© ÀüȯÇÏ°Ô ÇÕ´Ï´Ù. Áï, ¾Æ·¡ÀÇ ¿¹Á¦¿¡¼­ ioctl ºÎºÐÀ» ÀüºÎ KDGKBMODE, KDSKBMODE ·Î ¹Ù²ãÁà¾ß ÇÕ´Ï´Ù. ÀÌ¿¡ ´ëÇÑ ¸ðµå·Î´Â /usr/include/linux/kd.h ¿¡ ±× ³»¿ëÀÌ ÀÖÀ¸´Ï ÂüÁ¶ ÇϽñ⠹ٶø´Ï´Ù.
  • °æ¿ì¿¡ µû¶ó¼­´Â Serial console»ó¿¡¼­ ÀÔ·Â ¹Þ´Â Å°º¸µå ¹× º°µµÀÇ psaux¸¦ ÅëÇÑ Å°º¸µå 2°¡Áö¸¦ µ¿½Ã¿¡ ó¸®ÇÒ °æ¿ì°¡ ÀÖ½À´Ï´Ù. ÇÊÀÚ°¡ ¸¸µç ÇÁ·Î±×·¥ÀÌ ±×·±ÀûÀÌ ÀÖ¾ú´Âµ¥ À̶§´Â /dev/tty, /dev/console 2°³¸¦ ¸ÅÇÎÇÏ¿© ÀÛ¿ëÇϵµ·Ï ÇÑÀûÀÌ ÀÖ½À´Ï´Ù. »ç½Ç ´ëºÎºÐÀº ÀÌ 2°¡ÁöÀÇ µð¹ÙÀ̽º¸¦ ´Ù·ç¸é °ÅÀÇ ¸ðµç Å°º¸µå ÀÔ·ÂÀÌ ÀÌ·ïÁöÁö¸¸ °æ¿ì¿¡ µû¶ó¼­´Â ´Ù¸¥ °æ¿ìµµ ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ °á±¹ termios ÀÇ »ç¿ë¿¡ ´ëÇؼ­´Â ¾Æ·¡ÀÇ ¿¹Á¦¿Í ¸Æ¶ôÀÌ °ÅÀÇ µ¿ÀÏÇÕ´Ï´Ù. Áß¿äÇÑ°ÍÀº Å°º¸µå µð¹ÙÀ̽º À̸§ÀÌ ¾î¶²°ÍÀÌ³Ä¿Í Å°º¸µå¸¦ ´Ù·ê¶§ ¾î¶² MODE¸¦ »ç¿ëÇϴ°¡¸¦ °áÁ¤ÇÏ¸é µÈ´Ù´Â ¿¹±â°¡ µÇ°Ú½À´Ï´Ù.
  • ÇÁ·Î±×·¥ Á¾·áÅ°´Â Escape ¸¦ 2¹ø ¿¬¼Ó ´©¸£¸é ºüÁ®³ª¿É´Ï´Ù.
  • ÁÖÀÇ! : ÀÌ°ÍÀ» ¹é±×¶ó¿îµå ¸ðµå·Î ½ÇÇàÇϽøé ÇÁ·Î±×·¥ÀÌ ºñ Á¤»ó Á¾·á°¡ µÉ°Ì´Ï´Ù. Ç¥ÁØÀÔ·Â ¼ÒÀ¯±Ç °Ë»ç(¹é±×¶ó¿îµå °Ë»ç)¸¦ ÂüÁ¶ÇÏ½Ã°í ¾îµð°¡ ¾î¶² ÀÌÀ¯¿¡¼­ ±×·± °á°ú¸¦ ¹ß»ýÇÏ´ÂÁö¸¦ È®ÀÎÇϽðí ÀÚ½ÅÀÇ °ÍÀ¸·Î ¸¸µé¾î º¸¼¼¿ä.

/*
 Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> Made in KOREA
 http://minzkn.pe.ky
*/

#ifndef DEF_SOURCE_mzplugin_vt_c
#define DEF_SOURCE_mzplugin_vt_c "mzplugin_vt.c"

#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <malloc.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <sys/vt.h>

#ifndef t_MZ_VT
typedef struct ts_VT
{
 int Handle, InitLevel;
 struct termios NewTermios, OldTermios;
 struct vt_mode NewMode, OldMode;
}t_VT;
#define t_VT t_VT
#endif

t_VT *MZ_OpenVT(void);
t_VT *MZ_CloseVT(t_VT *s_Handle);
int MZ_ReadVT(t_VT *s_Handle, int s_TimeOut /* mSec */);

static void __MZ_CopyMemory__(void *s_To, const void *s_From, int s_Size)
{
#ifdef WIN32
 (void)memcpy(s_To, s_From, (size_t)s_Size);
#else
 __asm__ volatile(
  "\n\t"
  "cld\n\t"
  "shrl $1, %2\n\t"
  "jnc 0f\n\t"
  "movsb %%ds:(%1), %%es:(%0)\n\t"
  "0:\n\t"
  "shrl $1, %2\n\t"
  "jnc 0f\n\t"
  "movsw %%ds:(%1), %%es:(%0)\n\t"
  "0:\n\t"
  "repz movsl %%ds:(%1), %%es:(%0)\n\t"
  "\n\t"
  :
  : "D"(s_To), "S"(s_From), "c"(s_Size)
 );
#endif
}

t_VT *MZ_OpenVT(void)
{
 const char c_DefaultTTY[] = {"/dev/tty"};
 t_VT *s_Return;
 int s_IsOK = 0;
 char *s_TTY_Name;
 s_Return = (t_VT *)malloc(sizeof(t_VT));
 if(s_Return)
 {
  s_Return->InitLevel = 0;
  s_TTY_Name = ttyname(STDIN_FILENO);
  s_Return->Handle = open(s_TTY_Name ? s_TTY_Name : c_DefaultTTY, O_RDONLY | O_NOCTTY);
  if(s_Return->Handle != (-1))
  {
   s_Return->InitLevel |= 0x00000001;
   if(ioctl(s_Return->Handle, VT_GETMODE, (void *)(&s_Return->OldMode)) != (-1))
   {
    s_Return->InitLevel |= 0x00000002;
    __MZ_CopyMemory__((void *)(&s_Return->NewMode), (void *)(&s_Return->OldMode), sizeof(struct vt_mode));
    s_Return->NewMode.mode = VT_PROCESS;
    if(ioctl(s_Return->Handle, VT_SETMODE, (void *)(&s_Return->NewMode)) != (-1))
    {
     s_Return->InitLevel |= 0x00000004;
    }
   }
   /* else fprintf(stdout, "ioctl set VT_MODE error !\n"); */
   if(tcgetattr(STDIN_FILENO, (struct termios *)(&s_Return->OldTermios)) != (-1))
   {
    s_Return->InitLevel |= 0x00000008; /* 3 */
    __MZ_CopyMemory__((void *)(&s_Return->NewTermios), (void *)(&s_Return->OldTermios), sizeof(struct termios));
    s_Return->NewTermios.c_iflag &= (~BRKINT);
    s_Return->NewTermios.c_iflag |= (IGNBRK);
    s_Return->NewTermios.c_lflag &= (~( ISIG | ECHO | ICANON ));
    tcsetattr(STDIN_FILENO, TCSANOW, (struct termios *)(&s_Return->NewTermios));
    s_IsOK = 1;
   }
   else fprintf(stdout, "get tcgetattr error !\n");
  }
  if(s_IsOK == 0)s_Return = MZ_CloseVT(s_Return);
 }
 return(s_Return);
}

t_VT *MZ_CloseVT(t_VT *s_Handle)
{
 if(s_Handle)
 {
  if(s_Handle->Handle != (-1))
  {
   if((s_Handle->InitLevel & 0x00000008))
   {
    tcsetattr(STDIN_FILENO, TCSANOW, (struct termios *)(&s_Handle->OldTermios));
    tcflush(s_Handle->Handle, TCIOFLUSH);
   }
   if((s_Handle->InitLevel & 0x00000004))ioctl(s_Handle->Handle, VT_SETMODE, (void *)(&s_Handle->OldMode));
   if((s_Handle->InitLevel & 0x00000001))close(s_Handle->Handle);
  }
  free(s_Handle);
  s_Handle = (t_VT *)0;
 }
 return(s_Handle);
}

int MZ_ReadVT(t_VT *s_Handle, int s_TimeOut /* mSec */)
{
 int s_Return = (-1), s_ReadBytes;
 fd_set s_FD_Read;
 struct timeval s_LocalTimeVal;
 unsigned char s_Byte;
 if(s_Handle)
 {
  if(s_Handle->Handle != (-1))
  {
   if(s_TimeOut > 0)
   { /* Select */
    s_LocalTimeVal.tv_sec = s_TimeOut / 1000, s_LocalTimeVal.tv_usec = (s_TimeOut % 1000) * 1000;
    FD_ZERO(&s_FD_Read);
    FD_SET(s_Handle->Handle, &s_FD_Read);
    if(select(s_Handle->Handle + 1, (fd_set *)(&s_FD_Read), (fd_set *)0, (fd_set *)0, (struct timeval *)(&s_LocalTimeVal)) > 0)
    {
     if(FD_ISSET(s_Handle->Handle, &s_FD_Read))
     {
      if(read(s_Handle->Handle, (void *)(&s_Byte), sizeof(s_Byte)) > 0)s_Return = (int)s_Byte;
     }
    }
   }
   else
   { /* Block */
    s_ReadBytes = read(s_Handle->Handle, (void *)(&s_Byte), sizeof(s_Byte));
    if(s_ReadBytes > 0)s_Return = (int)s_Byte;
   }
  }
 }
 return(s_Return);
}

int main(void)
{
 int s_Return = 0, s_Escape, s_Key;
 t_VT *s_VT;
 s_VT = MZ_OpenVT();
 if(s_VT)
 {
  fprintf(stdout, "Use VT : Handle=%d\n", s_VT->Handle);
  s_Escape = 0;
  while(1)
  {
   s_Key = MZ_ReadVT(s_VT, 8000);
   if(s_Key >= 0)
   {
    if(s_Key == 0x1b)s_Escape++;
    else s_Escape = 0;

    fprintf(stdout, "[%c(0x%02x)]\n", (s_Key < 0x20 || s_Key >= 0x7f) ? '.' : s_Key, s_Key);
   }
   else fprintf(stdout, "Wait for key : 'ESC' key double press to exit.\n");
   if(s_Escape >= 2)break;
  }
  s_VT = MZ_CloseVT(s_VT);
 }
 else fprintf(stdout, "Can not open VT !\n");
 return(s_Return);
}

#endif

/* End of source */

ID
Password
Join
Today is a good day to bribe a high ranking public official.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2004-12-04 20:53:31
Processing time 0.0039 sec