home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / mm1_tracker.lzh / TRACKER4.6 / Unix / ui.c
Text File  |  1994-11-24  |  7KB  |  393 lines

  1. /* unix/ui.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* special termio discipline for sun/sgi,
  6.  * for non blocking io and such.
  7.  * These functions should not be too difficult
  8.  * to write for a PC.
  9.  */
  10. /* $Id: ui.c,v 4.1 1994/01/13 09:18:48 espie Exp espie $
  11.  * $Log: ui.c,v $
  12.  *
  13.  * Revision 4.0  1994/01/11  18:02:31  espie
  14.  * Major change: lots of new calls.
  15.  * Stupid termio bug: shouldn't restore term to sanity if we don't
  16.  * know what sanity is. For instance, if we haven't modified anything.
  17.  * cflags interpreted correctly.
  18.  * Hsavolai fix.
  19.  * Added bg/fg test.
  20.  */
  21.  
  22. #ifdef dec
  23. #define stub_only
  24. #endif
  25.  
  26. #if defined(linux) || defined(__386BSD__)
  27. #include <termios.h>
  28. #else
  29. #ifdef __hpux
  30. #include <sys/bsdtty.h>
  31. #endif
  32. #include <sys/termio.h>
  33. #endif
  34. #ifdef __386BSD__
  35. #include <sys/ioctl.h>
  36. #endif
  37. #include <stdio.h>
  38. #include <signal.h>
  39. #include "defs.h"
  40. #include "extern.h"
  41. #include "tags.h"
  42. #include "prefs.h"
  43.  
  44.  
  45. LOCAL void nonblocking_io P((void));
  46. LOCAL void sane_tty P((void));
  47.  
  48. LOCAL void (*INIT)P((void)) = nonblocking_io;
  49.  
  50.  
  51. LOCAL int show;
  52. /* poor man's timer */
  53. LOCAL int current_pattern;
  54. LOCAL int count_pattern, count_song;
  55. #define SMALL_DELAY 25
  56.  
  57. /* do not define any stdio routines if it's known not to work */
  58.  
  59. #ifdef stub_only
  60.  
  61. int run_in_fg()
  62.    {
  63.    return TRUE;
  64.    }
  65.  
  66. LOCAL void sane_tty()
  67.    {
  68.    }
  69.  
  70. LOCAL struct tag end_marker;
  71.  
  72. struct tag *get_ui()
  73.    {
  74.    end_marker.type = TAG_END;
  75.    return &end_marker;
  76.    }
  77.  
  78. #else
  79.  
  80. LOCAL struct termio sanity;
  81. LOCAL struct termio *psanity = 0;
  82.  
  83. LOCAL int is_fg;
  84.  
  85. /* signal handler */
  86.  
  87. LOCAL void goodbye(sig)
  88. int sig;
  89.     {
  90.     static char buffer[25];
  91.  
  92.     sprintf(buffer, "Signal %d", sig);
  93.     end_all(buffer);
  94.     }
  95.  
  96. LOCAL void abort_this(sig)
  97. int sig;
  98.    {
  99.    end_all("Abort");
  100.    }
  101.  
  102. #ifdef SIGTSTP
  103. LOCAL void suspend(sig)
  104. int sig;
  105.    {
  106.    fflush(stdout);
  107.    sane_tty();
  108.    signal(SIGTSTP, SIG_DFL);
  109.    kill(0, SIGTSTP);
  110.    }
  111. #endif
  112.  
  113. int run_in_fg()
  114.    {
  115.    int val;
  116.  
  117. #ifdef __hpux
  118.     if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))
  119.         return FALSE;
  120. #endif
  121.  
  122.    /* real check for running in foreground */
  123.    if (ioctl(fileno(stdin), TIOCGPGRP, &val))
  124.       return FALSE; 
  125.    if (val == getpgrp())
  126.       return TRUE;
  127.    else
  128.       return FALSE;
  129.    }
  130.  
  131. LOCAL void switch_mode()
  132.    {
  133.    struct termio zap;
  134.  
  135. #ifdef SIGTSTP
  136.    signal(SIGTSTP, suspend);
  137. #endif
  138.    signal(SIGCONT, switch_mode);
  139.    signal(SIGINT, goodbye);
  140.    signal(SIGQUIT, goodbye);
  141.    signal(SIGUSR1, abort_this);
  142.  
  143.    if (run_in_fg())
  144.       {
  145. #ifdef __386BSD__
  146.       tcgetattr(fileno(stdin), &zap);
  147. #else
  148.       ioctl(fileno(stdin), TCGETA, &zap);
  149. #endif
  150. #ifdef linux
  151.       zap.c_cc[VMIN] = 0;
  152.       zap.c_cc[VTIME] = 0;
  153. /* Commented out
  154. As Hannu said:
  155. The current Linux kernel interprets correctly the c_lflags field so it
  156. should be set like for the other systems. 
  157.       zap.c_lflag = 0;
  158.  */
  159. #else
  160. #ifdef __386BSD__
  161.       zap.c_cc[VMIN] = 0;     /* can't work with old */
  162.       zap.c_cc[VTIME] = 0; /* FreeBSD versions    */
  163.       zap.c_lflag &= ~(ICANON|ECHO|ECHONL);
  164. #endif
  165.       zap.c_cc[VEOL] = 0;
  166.       zap.c_cc[VEOF] = 0;
  167. #endif
  168.       zap.c_lflag &= ~(ICANON | ECHO);
  169. #ifdef __386BSD__
  170.       tcsetattr(fileno(stdin, TCSANOW, &zap);
  171. #else
  172.       ioctl(fileno(stdin), TCSETA, &zap);
  173. #endif
  174.       is_fg = TRUE;
  175.       }
  176.    else
  177.       is_fg = FALSE;
  178.    }
  179.  
  180. /* nonblocking_io():
  181.  * try to setup the keyboard to non blocking io
  182.  */
  183. LOCAL void nonblocking_io()
  184.    {
  185.    show = get_pref_scalar(PREF_SHOW);
  186.    /* try to renice our own process to get more cpu time */
  187.    if (nice(-15) == -1)
  188.       nice(0);
  189.    if (!psanity)
  190.       {
  191.       psanity = &sanity;
  192. #ifdef __386BSD__
  193.       tcgetattr(fileno(stdin), &sanity);
  194. #else
  195.       ioctl(fileno(stdin), TCGETA, psanity);
  196. #endif
  197.       }
  198.    switch_mode();
  199.    at_end(sane_tty);
  200.    }
  201.  
  202.  
  203. /* sane_tty():
  204.  * restores everything to a sane state before returning to shell */
  205. LOCAL void sane_tty()
  206.    {
  207. #ifdef __386BSD__
  208.       tcsetattr(fileno(stdin), &sanity);
  209. #else
  210.       ioctl(fileno(stdin), TCSETA, psanity);
  211. #endif
  212.    }
  213.  
  214. LOCAL int may_getchar()
  215.    {
  216.    char buffer;
  217.  
  218.    INIT_ONCE;
  219.  
  220.    if (run_in_fg() && !is_fg)
  221.       switch_mode();
  222.    if (run_in_fg() && read(fileno(stdin), &buffer, 1))
  223.       return buffer;
  224.    return EOF;
  225.    }
  226.  
  227. LOCAL struct tag result[2];
  228.  
  229. struct tag *get_ui()
  230.    {
  231.    result[0].type = TAG_END;
  232.    result[1].type = TAG_END;
  233.    count_pattern++;
  234.    count_song++;
  235.    switch(may_getchar())
  236.       {
  237.    case 'n':
  238.       result[0].type = UI_NEXT_SONG;
  239.       break;
  240.    case 'p':
  241.       if (count_song > SMALL_DELAY)
  242.          result[0].type = UI_RESTART;
  243.       else
  244.          result[0].type = UI_PREVIOUS_SONG;
  245.       count_song = 0;
  246.       break;
  247.    case 'x':
  248.    case 'e':
  249.    case 'q':
  250.       result[0].type = UI_QUIT;
  251.       break;
  252.    case 's':
  253.       result[0].type = UI_SET_BPM;
  254.       result[0].data.scalar = 50;
  255.       break;
  256.    case 'S':
  257.       result[0].type = UI_SET_BPM;
  258.       result[0].data.scalar = 60;
  259.       break;
  260.    case '>':
  261.       result[0].type = UI_JUMP_TO_PATTERN;
  262.       result[0].data.scalar = current_pattern + 1;
  263.       break;
  264.    case '<':
  265.       result[0].type = UI_JUMP_TO_PATTERN;
  266.       result[0].data.scalar = current_pattern;
  267.       if (count_pattern < SMALL_DELAY)
  268.          result[0].data.scalar--;
  269.       break;
  270.    case '?':
  271.       show = !show;
  272.         set_pref_scalar(PREF_SHOW, show);
  273.         if (show)
  274.             putchar('\n');
  275.       break;
  276.    default:
  277.       break;
  278.       }
  279.    return result;
  280.    }
  281.       
  282.          
  283. #endif
  284.  
  285.  
  286. void notice(s)
  287. char *s;
  288.    {
  289.    fprintf(stderr, "%s\n", s);
  290.    }
  291.  
  292. void status(s)
  293. char *s;
  294.    {
  295.    if (run_in_fg())
  296.       {
  297.         if (s)
  298.          {
  299.          puts(s);
  300.          }
  301.       else
  302.          putchar('\n');
  303.       }
  304.    }
  305.  
  306. LOCAL char title[25];
  307. void song_title(s)
  308. char *s;
  309.    {
  310.     strncpy(title, s, 25);
  311.     if (run_in_fg() && !show)
  312.         puts(title);
  313.    count_song = 0;
  314.    }
  315.  
  316.  
  317. LOCAL char scroll_buffer[80];
  318.  
  319. GENERIC begin_info(title)
  320. char *title;
  321.    {
  322.    if (run_in_fg())
  323.       return scroll_buffer;
  324.    else
  325.       return 0;
  326.    }
  327.  
  328. void infos(handle, s)
  329. GENERIC handle;
  330. char *s;
  331.    {
  332.    if (handle)
  333.       printf(s);
  334.    }
  335.  
  336. void info(handle, line)
  337. GENERIC handle;
  338. char *line;
  339.    {
  340.    if (handle)
  341.       puts(line);
  342.    }
  343.  
  344. void end_info(handle)
  345. GENERIC handle;
  346.    {
  347.    if (handle)
  348.       fflush(stdout);
  349.    }
  350.  
  351. LOCAL char *last_result = 0;
  352.  
  353. char *new_scroll(void)
  354.    {
  355.    if (run_in_fg())
  356.       {
  357.       last_result = scroll_buffer;
  358.       strcpy(scroll_buffer, "             |             |             |             ");
  359.       }
  360.    else
  361.       last_result = 0;
  362.    return last_result;
  363.    }
  364.    
  365. void scroll()
  366.    {
  367.    if (run_in_fg() && last_result)
  368.         {
  369.       puts(scroll_buffer);
  370.         fflush(stdout);
  371.         }
  372.    }
  373.  
  374. void display_pattern(current, total, real)
  375. int current, total, real;
  376.    {
  377.    if (run_in_fg())
  378.       {
  379.       if (show)
  380.          printf("\n%3d/%3d[%3d] %s\n", current, total, real, title);
  381.       else
  382.          printf("%3d/%3d\b\b\b\b\b\b\b", current, total);
  383.       fflush(stdout); 
  384.       }
  385.    current_pattern = current;
  386.    count_pattern = 0;
  387.    }
  388.  
  389. int checkbrk()
  390.    {
  391.    return FALSE;
  392.    }
  393.