Virtual Terminal Keyboard
Virtual terminal ÀÔ·Â ¶
/*
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 */ |
You will have good luck and overcome many hardships. |