· 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
Be careful how you get yourself involved with persons or situations that can't bear inspection.


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.0042 sec