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

📄 kb_input.c

📁 功能强大的文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
       (msec >= TIMER_TICK))         /* or big pause ?           */
   {                         /* compromise:                      */
                             /* fall back to old fashioned style */
      msec /= TIMER_TICK;    /* scale: msec --> timer ticks (LSB = 1 sec) */
      msec = max (1, msec);  /* unix: minimal 1 tick */
      sleep (msec);          /* do it */
   }
   else
   {
      goal = (long) msec * CLOCKS_PER_SEC / 1000L + clock();   /* LSB = msec --> usec */
   
   /* loop: waste of time */
   /* limit prevents endless loop */
      for (limit = 0 ; limit < 1000000L ; limit++)
      {           /* this handling prevents modulo problems, if 31 bit clock */
         if (((clock() - goal) & 0x7fffffff) <= 0x40000000)
            break;     /* normal exit */
      }
   }

#else

   msec /= TIMER_TICK;    /* scale: msec --> timer ticks (LSB = 1 sec) */
   msec = max (1, msec);  /* unix: minimal 1 tick */
   sleep (msec);          /* do it */

#endif

   return;
}  /* sleep_msec (UNIX) */


/************************************************************************/
/* set the terminal I/O blocking on and off                             */
/************************************************************************/

static void setblock (int fd, int on)
{
   static int blockf, nonblockf;
   static int first = 1;
   int flags;

   if (first)
   {
      first = 0;
      if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
         syserr("fcntl");

#if (ACT_OP_SYSTEM == QNX)
      blockf    = flags & ~O_NONBLOCK;     /* O_NDELAY off */
      nonblockf = flags |  O_NONBLOCK;     /* O_NDELAY on  */
#else
      blockf    = flags & ~O_NDELAY;       /* O_NDELAY off */
      nonblockf = flags |  O_NDELAY;       /* O_NDELAY on  */
#endif
   }

   if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
      syserr("fcntl2");
}  /* setblock */


/*************************/
/* avoid hanging display */
/*************************/

void avoid_hanging_display(void)
{
   setblock (PATH_0, 0);
   setblock (PATH_0, 1);
}


/************************/
/*  is key pressed ?    */
/************************/

#define EMPTY '\0'
static char cbuf[16] = "\0";

int loc_key_pressed (void)
{
/* return true, if key is pressed, else false */

   if (input_redirected) return 0;

   if (*cbuf != EMPTY)
      return (1);

   setblock (PATH_0, 0);
   switch (read (PATH_0, cbuf, 1))
   {
      case -1:
         errno = 0;
         return (EMPTY);

      case  0:
         return (EMPTY);          /* could be EOF too */

      default:
         cbuf[1]=EMPTY;
         return 1;
   }
}  /* loc_key_pressed */


/************************/
/*  get 1 single byte   */
/************************/

static int get_1_byte (void)
{
int num;
char c;

   if (*cbuf != EMPTY)
   {
       c = *cbuf;
       strcpy(cbuf,&cbuf[1]);  /* shift buffer 1 charact. down */
       return(c);
   }

   setblock (PATH_0, 1);
   num = read (PATH_0, &c, 1);
   switch (num)
   {
      case -1: 
         if (errno == EINTR)
         {
            errno = 0;
            return (KEY_DO_NOTHING);   /* NEU !! wg. SIGWINCH, vorher : -1 */
         }
         else
         {
            syserr("read 1 stdin");
         }
         /* fall through */
         
      case 0:
         return (-1);             /* must be EOF  */
         
      default:
         return (c);
   }

}  /* get_1_byte */

/* -FF-  */

/************************/
/*  get with timeout    */
/************************/

#if (WITH_USEC_CLOCK)

#define TIMER_TICK_10 10

static int get_1_byte_with_timeout (int wait_time)
{
/* if key is pressed before wait_time elapsed, key is returned, else -1 */
/* wait_time : LSB = 1 msec */
/* special cases: wait_time = 0 : no wait */
/*                wait_time < 0 : wait forever */

int time;

/* wait forever ? */
   if (wait_time < 0)  return get_1_byte ();

/* is key already there ? */
   if (loc_key_pressed ()) return get_1_byte ();
   
/* wait given time */
   for (time = 0 ; time < wait_time ; time += TIMER_TICK_10)
   {
      sleep_msec (TIMER_TICK_10);
      if (loc_key_pressed ()) return get_1_byte ();
   }

   return -1;  /* timeout */
}  /* get_1_byte_with_timeout */

#else

static jmp_buf env;

static int get_1_byte_with_timeout (int w_time)
{
char c;
int nr, tms, jmpret;

   tms = max(1, ((w_time + (TIMER_TICK-1)) / TIMER_TICK));

   if (w_time < 0 )
       return (get_1_byte());

   if (*cbuf != EMPTY)
   {
       c = *cbuf;
       strcpy (cbuf, &cbuf[1]);  /* shift buffer 1 charact. down */
       return(c);
   }

   setblock (PATH_0, 1);          /* das fehlen dieser anweisung verursachte */
                                  /* die probleme unter unix svr4 !!         */

   signal (SIGALRM, key_brk);     /* set signal handling       */

   alarm (tms);                   /* set timeout: LSB 1 sec !! */
   jmpret = setjmp (env);

   if (jmpret == 0)                  /* auf unix svr4 ueberfluessig, da bei */
      nr = read (PATH_0, cbuf, 2);   /* SIGALRM die read function abgebro-  */
   else                              /* chen wird (-1), bei ultrix nicht !! */
      nr = jmpret;

   alarm (0);                     /* reset timeout */

   switch (nr)
   {
      case -1:
         return (-1);
          
      case 0:
         return (-1);           /* EOF */
 
      default:
         cbuf[nr] = EMPTY;
         c = *cbuf;
         strcpy( cbuf, &cbuf[1] );  /* shift buffer */
         return(c);
   }
}  /* get_1_byte_with_timeout */


/* dummy routine fuer alarm handling */
static void key_brk (int sig)
{
   sig;
   longjmp (env, -1);
}

#endif

/* -FF-  */

/************************/
/*  echo on / off       */
/************************/

static int on_off;

void kb_echo_off (void)
{
#if (TEST_PRINT)
   printf ("\n>>> kb_echo_off: input_redirected = %d, on_off = %d \n",
                            input_redirected, on_off);
#endif


#if (WITH_WINCH)
   if ((signal(SIGWINCH, cmd_winch)) == SIG_ERR)
      syserr("signal SIGWINCH, cmd_winch");
#endif


   if (input_redirected) return;

   if (on_off == 0)
   {
      on_off = 1;

#if (OS_QNX6)
      if (tcgetattr(PATH_0, &tbuf) == -1)
#else
      if (ioctl (PATH_0, TCGETA, &tbuf) == -1)
#endif
         syserr("ioctl get termio");

#if 0
      tbufsave = tbuf;                        /* save the old structure */
#else
      memcpy (&tbufsave, &tbuf, sizeof (tbufsave));
#endif

      setraw (1, 1);
   }
   set_wrap_off();

   return;

}  /* kb_echo_off */

static void setraw (uchar c_num, uchar t_msec10)
{

/* INLCR : map (not map) NL to CR                               */
/* ICRNL : map (not map) CR to NL                               */
/* IUCLC : map (not map) upper case to lower case on input      */
/* ISTRIP: strip (not)   input characters to seven bits         */

#if (ACT_OP_SYSTEM == QNX)
   tbuf.c_iflag &= ~(INLCR | ICRNL | ISTRIP | BRKINT);
#else
   tbuf.c_iflag &= ~(INLCR | ICRNL | IUCLC | ISTRIP | BRKINT);
#endif

#if 0
   tbuf.c_iflag |=  (IXON | IXOFF);    /* handshake in both (!) directions */
#else
   tbuf.c_iflag &= ~(IXON | IXOFF);    /* ^S / ^Q available for application */
#endif

   tbuf.c_oflag &= ~OPOST;
   tbuf.c_lflag &= ~(ICANON | ISIG | ECHO);
   tbuf.c_cc[4] = c_num;          /* MIN */
   tbuf.c_cc[5] = t_msec10;       /* TIME */

#if (OS_QNX6)
   if (tcsetattr(PATH_0, TCSADRAIN, &tbuf) == -1)
#else
   if (ioctl (PATH_0, TCSETA, &tbuf) == -1)
#endif
         syserr("ioctl set termio");

   return;
}  /* setraw */


void kb_echo_on (void)
{
#if (TEST_PRINT)
   printf ("\n>>> kb_echo_on: input_redirected = %d, on_off = %d \n",
                           input_redirected, on_off);
#endif


#if (WITH_WINCH)
   if ((signal(SIGWINCH, SIG_IGN)) == SIG_ERR)
      syserr("signal SIGWINCH, SIG_IGN");
#endif


   if (input_redirected) return;
   
   if (on_off == 1)
   {
      on_off = 0;

#if (OS_QNX6)
      if (tcsetattr(PATH_0, TCSADRAIN, &tbufsave) == -1)
#else
      if (ioctl (PATH_0, TCSETA, &tbufsave) == -1)   /* vorher: TCSETAF */
#endif
         syserr("ioctl reset term");
   }
   set_wrap_on();

   return;
}  /* kb_echo_on */

#endif  /* UNIX */

/* -FF-  */

/* Modification History */
/* 21.10.92 - file erzeugt */
/* 01.12.92 - vt100 ansteuerung  */
/* 04.12.92 - keyboard_echo on/off */
/* 05.12.92 - pause_msec () */
/* 21.12.92 - get_1_key (): fflush (stdout); bei VT_100 */
/* 01.01.93 - loc_get_1_key () */
/* 03.01.93 - loc_get_1_key () public (for mbedit.c) */
/* 15.08.93 - loc_key_pressed: #if INPUT_VIA_BIOS */
/* 12.09.93 - show_status_line_2 (..., ignore_batch) */
/* 14.09.93 - get_1_key(), special case <cr><lf> */
/* 30.09.93 - TEST_EOLN */
/* 08.10.93 - loc_get_1_key() --> loc_get_1_int() */
/* 04.11.93 - TEST_EOLN entfaellt */
/* 07.12.93 - ctrlchandler (int sig) */
/* 08.12.93 - ctrlchandler auch bei os/9 */
/* 08.12.93 - os/9: tsleep min. 2 ticks */
/* 10.12.93 - keyboard and mouse polling */
/* 15.12.93 - KEYBOARD_FIFO_OVERFLOW: only for the 1st occurance */
/* 15.12.93 - get_1_key: key = (int) (*string_buff & 0xff); only LSB */
/* 15.12.93 - ALLOW_SLOW_CONNECTIONS */
/* 20.12.93 - ESCAPE_SEQUENCE_ERROR */
/* 22.12.93 - old_toggle */
/* 09.05.94 - WITH_USEC_CLOCK (quick <esc> handling) */
/* 09.05.94 - variable esc_waittime */
/* 10.05.94 - HP7_XTERM */
/* 11.05.94 - increase of esc_waittime in case of <esc> sequence error */
/* 17.05.94 - sleep_msec (UNIX), prevent endless loop */
/* 18.05.94 - sleep_msec (UNIX), bugfix */
/* 19.05.94 - sleep_msec (UNIX), msec >= 1000: old function */
/* 20.05.94 - action_flag */
/* 03.06.94 - get_1_byte (): case -1: return KEY_DO_NOTHING (vorher: -1) */
/* 09.06.94 - kb_echo_off (UNIX): "memcpy" anstatt "struct 1 = struct 2" */
/* 09.06.94 - TEST_PRINT */
/* 15.06.94 - kb_echo_on (): TCSETAF --> TCSETA */
/* 15.06.94 - 6-mal neu: reset_macro_stack() */
/* 23.09.94 - setraw(): tbuf.c_iflag &= ~(IXON | IXOFF); */
/* 26.09.94 - <esc> [ 7 ~, <esc> [ 8 ~ */
/* 21.11.94 - WRAP_ON / WRAP_OFF bei SCO_UNIX */
/* 22.02.95 - ESC_WRAP_ON / ESC_WRAP_OFF immer */
/* 24.02.95 - key_break (int sig) */
/* 26.02.95 - set_wrap_on, _off */
/* 27.02.95 - sleep_msec(): CLOCKS_PER_SEC (unix) */
/* 28.11.95 - sleep_msec(): CLOCKS_PER_SEC (os/9) */
/* 09.09.98 - code for QNX */
/* 04.03.99 - OS-9000: simulate getstat + setstat */
/* 07.03.99 - OS_9_PPC: simulate getstat + setstat */
/* 16.03.99 - OS_9_PPC: simulate getstat/setstat with _os_gs_popt/_os_ss_popt */
/* 20.03.99 - OS_9_PPC: bugfix (missing 4 end of comment in setstat) */
/* 20.03.99 - OS_9_PPC: scf_lu_opts (disable ^C, ^E) */
/* 06.12.03 - avoid_hanging_display() */
/* 05.02.04 - loc_get_1_int(): return (key & 0xff); */
/* 17.02.04 - QNX6: New ! */

⌨️ 快捷键说明

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