📄 kb_input.c
字号:
(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 + -