home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
SOUNDUTILS
/
tracker.4.6.lzh
/
TRACKER4.6
/
Unix
/
ui.c
Wrap
Text File
|
1994-11-24
|
7KB
|
393 lines
/* unix/ui.c
vi:ts=3 sw=3:
*/
/* special termio discipline for sun/sgi,
* for non blocking io and such.
* These functions should not be too difficult
* to write for a PC.
*/
/* $Id: ui.c,v 4.1 1994/01/13 09:18:48 espie Exp espie $
* $Log: ui.c,v $
*
* Revision 4.0 1994/01/11 18:02:31 espie
* Major change: lots of new calls.
* Stupid termio bug: shouldn't restore term to sanity if we don't
* know what sanity is. For instance, if we haven't modified anything.
* cflags interpreted correctly.
* Hsavolai fix.
* Added bg/fg test.
*/
#ifdef dec
#define stub_only
#endif
#if defined(linux) || defined(__386BSD__)
#include <termios.h>
#else
#ifdef __hpux
#include <sys/bsdtty.h>
#endif
#include <sys/termio.h>
#endif
#ifdef __386BSD__
#include <sys/ioctl.h>
#endif
#include <stdio.h>
#include <signal.h>
#include "defs.h"
#include "extern.h"
#include "tags.h"
#include "prefs.h"
LOCAL void nonblocking_io P((void));
LOCAL void sane_tty P((void));
LOCAL void (*INIT)P((void)) = nonblocking_io;
LOCAL int show;
/* poor man's timer */
LOCAL int current_pattern;
LOCAL int count_pattern, count_song;
#define SMALL_DELAY 25
/* do not define any stdio routines if it's known not to work */
#ifdef stub_only
int run_in_fg()
{
return TRUE;
}
LOCAL void sane_tty()
{
}
LOCAL struct tag end_marker;
struct tag *get_ui()
{
end_marker.type = TAG_END;
return &end_marker;
}
#else
LOCAL struct termio sanity;
LOCAL struct termio *psanity = 0;
LOCAL int is_fg;
/* signal handler */
LOCAL void goodbye(sig)
int sig;
{
static char buffer[25];
sprintf(buffer, "Signal %d", sig);
end_all(buffer);
}
LOCAL void abort_this(sig)
int sig;
{
end_all("Abort");
}
#ifdef SIGTSTP
LOCAL void suspend(sig)
int sig;
{
fflush(stdout);
sane_tty();
signal(SIGTSTP, SIG_DFL);
kill(0, SIGTSTP);
}
#endif
int run_in_fg()
{
int val;
#ifdef __hpux
if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))
return FALSE;
#endif
/* real check for running in foreground */
if (ioctl(fileno(stdin), TIOCGPGRP, &val))
return FALSE;
if (val == getpgrp())
return TRUE;
else
return FALSE;
}
LOCAL void switch_mode()
{
struct termio zap;
#ifdef SIGTSTP
signal(SIGTSTP, suspend);
#endif
signal(SIGCONT, switch_mode);
signal(SIGINT, goodbye);
signal(SIGQUIT, goodbye);
signal(SIGUSR1, abort_this);
if (run_in_fg())
{
#ifdef __386BSD__
tcgetattr(fileno(stdin), &zap);
#else
ioctl(fileno(stdin), TCGETA, &zap);
#endif
#ifdef linux
zap.c_cc[VMIN] = 0;
zap.c_cc[VTIME] = 0;
/* Commented out
As Hannu said:
The current Linux kernel interprets correctly the c_lflags field so it
should be set like for the other systems.
zap.c_lflag = 0;
*/
#else
#ifdef __386BSD__
zap.c_cc[VMIN] = 0; /* can't work with old */
zap.c_cc[VTIME] = 0; /* FreeBSD versions */
zap.c_lflag &= ~(ICANON|ECHO|ECHONL);
#endif
zap.c_cc[VEOL] = 0;
zap.c_cc[VEOF] = 0;
#endif
zap.c_lflag &= ~(ICANON | ECHO);
#ifdef __386BSD__
tcsetattr(fileno(stdin, TCSANOW, &zap);
#else
ioctl(fileno(stdin), TCSETA, &zap);
#endif
is_fg = TRUE;
}
else
is_fg = FALSE;
}
/* nonblocking_io():
* try to setup the keyboard to non blocking io
*/
LOCAL void nonblocking_io()
{
show = get_pref_scalar(PREF_SHOW);
/* try to renice our own process to get more cpu time */
if (nice(-15) == -1)
nice(0);
if (!psanity)
{
psanity = &sanity;
#ifdef __386BSD__
tcgetattr(fileno(stdin), &sanity);
#else
ioctl(fileno(stdin), TCGETA, psanity);
#endif
}
switch_mode();
at_end(sane_tty);
}
/* sane_tty():
* restores everything to a sane state before returning to shell */
LOCAL void sane_tty()
{
#ifdef __386BSD__
tcsetattr(fileno(stdin), &sanity);
#else
ioctl(fileno(stdin), TCSETA, psanity);
#endif
}
LOCAL int may_getchar()
{
char buffer;
INIT_ONCE;
if (run_in_fg() && !is_fg)
switch_mode();
if (run_in_fg() && read(fileno(stdin), &buffer, 1))
return buffer;
return EOF;
}
LOCAL struct tag result[2];
struct tag *get_ui()
{
result[0].type = TAG_END;
result[1].type = TAG_END;
count_pattern++;
count_song++;
switch(may_getchar())
{
case 'n':
result[0].type = UI_NEXT_SONG;
break;
case 'p':
if (count_song > SMALL_DELAY)
result[0].type = UI_RESTART;
else
result[0].type = UI_PREVIOUS_SONG;
count_song = 0;
break;
case 'x':
case 'e':
case 'q':
result[0].type = UI_QUIT;
break;
case 's':
result[0].type = UI_SET_BPM;
result[0].data.scalar = 50;
break;
case 'S':
result[0].type = UI_SET_BPM;
result[0].data.scalar = 60;
break;
case '>':
result[0].type = UI_JUMP_TO_PATTERN;
result[0].data.scalar = current_pattern + 1;
break;
case '<':
result[0].type = UI_JUMP_TO_PATTERN;
result[0].data.scalar = current_pattern;
if (count_pattern < SMALL_DELAY)
result[0].data.scalar--;
break;
case '?':
show = !show;
set_pref_scalar(PREF_SHOW, show);
if (show)
putchar('\n');
break;
default:
break;
}
return result;
}
#endif
void notice(s)
char *s;
{
fprintf(stderr, "%s\n", s);
}
void status(s)
char *s;
{
if (run_in_fg())
{
if (s)
{
puts(s);
}
else
putchar('\n');
}
}
LOCAL char title[25];
void song_title(s)
char *s;
{
strncpy(title, s, 25);
if (run_in_fg() && !show)
puts(title);
count_song = 0;
}
LOCAL char scroll_buffer[80];
GENERIC begin_info(title)
char *title;
{
if (run_in_fg())
return scroll_buffer;
else
return 0;
}
void infos(handle, s)
GENERIC handle;
char *s;
{
if (handle)
printf(s);
}
void info(handle, line)
GENERIC handle;
char *line;
{
if (handle)
puts(line);
}
void end_info(handle)
GENERIC handle;
{
if (handle)
fflush(stdout);
}
LOCAL char *last_result = 0;
char *new_scroll(void)
{
if (run_in_fg())
{
last_result = scroll_buffer;
strcpy(scroll_buffer, " | | | ");
}
else
last_result = 0;
return last_result;
}
void scroll()
{
if (run_in_fg() && last_result)
{
puts(scroll_buffer);
fflush(stdout);
}
}
void display_pattern(current, total, real)
int current, total, real;
{
if (run_in_fg())
{
if (show)
printf("\n%3d/%3d[%3d] %s\n", current, total, real, title);
else
printf("%3d/%3d\b\b\b\b\b\b\b", current, total);
fflush(stdout);
}
current_pattern = current;
count_pattern = 0;
}
int checkbrk()
{
return FALSE;
}