Advertisement
mdgaziur001

command line arrow key detection without termios.h

Apr 2nd, 2024
953
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.95 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <sys/ioctl.h>
  4. #include <unistd.h>
  5.  
  6. #define stdin 0
  7. #define stdout 1
  8. #define __KERNEL_NCCS 19
  9. #define ICANON 0000002
  10. #define ECHO   0000010
  11.  
  12. typedef unsigned int tcflag_t;
  13. typedef unsigned char cc_t;
  14.  
  15. int printf(const char*, ...);
  16.  
  17. struct linux_termios {
  18.   tcflag_t c_iflag;         /* Input flags */
  19.   tcflag_t c_oflag;         /* Output flags */
  20.   tcflag_t c_cflag;         /* Control mode flags */
  21.   tcflag_t c_lflag;         /* Local mode flags  */
  22.   cc_t c_line;              /* Line discipline */
  23.   cc_t c_cc[__KERNEL_NCCS]; /* Control characters */
  24. };
  25.  
  26. struct linux_termios termios_orig;
  27.  
  28. void backup_termios() {
  29.   struct linux_termios l_termios;
  30.  
  31.   ioctl(stdin, TCGETS, &l_termios);
  32.  
  33.   memcpy(&termios_orig, &l_termios, sizeof(struct linux_termios));
  34.   memcpy(&termios_orig.c_cc[0], &l_termios.c_cc[0], __KERNEL_NCCS);
  35. }
  36.  
  37. struct linux_termios get_termios() {
  38.   struct linux_termios l_termios;
  39.   ioctl(stdin, TCGETS, &l_termios);
  40.  
  41.   return l_termios;
  42. }
  43.  
  44. void enable_raw_mode() {
  45.   struct linux_termios termios = get_termios();
  46.   termios.c_lflag &= ~(ECHO | ICANON);
  47.   ioctl(stdin, TCSETSF, &termios);
  48. }
  49.  
  50. void revert_termios() {
  51.   ioctl(stdin, TCSETSF, &termios_orig);
  52. }
  53.  
  54. int main() {
  55.   backup_termios();
  56.   enable_raw_mode();
  57.   atexit(revert_termios);
  58.  
  59.   char buf;
  60.   while(read(stdin, &buf, 1) == 1 && buf != 'q') {
  61.     if (buf == 27) {
  62.       // Arrow key pressed, skip '['
  63.       read(stdin, &buf, 1);
  64.  
  65.       read(stdin, &buf, 1);
  66.       switch (buf) {
  67.         case 'A': {
  68.           write(stdout, "U", 1);
  69.           break;
  70.         }
  71.         case 'B': {
  72.           write(stdout, "D", 1);
  73.           break;
  74.         }
  75.         case 'C': {
  76.           write(stdout, "L", 1);
  77.           break;
  78.         }
  79.         case 'D': {
  80.           write(stdout, "R", 1);
  81.           break;
  82.         }
  83.         default: write(stdout, &buf, 1);
  84.       }
  85.     }
  86.   }
  87.  
  88.   return 0;
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement