1
0

bounce_aio.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* bounce_aio.c
  2. * purpose animation with user control, using aio_read() etc
  3. * note set_ticker() sends SIGALRM, handler does animation
  4. * keyboard sends SIGIO, main only calls pause()
  5. * compile cc bounce_aio.c set_ticker.c -lrt -lcurses -o bounce_aio
  6. */
  7. #include <stdio.h>
  8. #include <curses.h>
  9. #include <signal.h>
  10. #include <aio.h>
  11. /* The state of the game */
  12. #define MESSAGE "hello"
  13. #define BLANK " "
  14. int row = 10; /* current row */
  15. int col = 0; /* current column */
  16. int dir = 1; /* where we are going */
  17. int delay = 200; /* how long to wait */
  18. int done = 0;
  19. struct aiocb kbcbuf; /* an aio control buf */
  20. main()
  21. {
  22. void on_alarm(int); /* handler for alarm */
  23. void on_input(int); /* handler for keybd */
  24. void setup_aio_buffer();
  25. initscr(); /* set up screen */
  26. crmode();
  27. noecho();
  28. clear();
  29. signal(SIGIO, on_input); /* install a handler */
  30. setup_aio_buffer(); /* initialize aio ctrl buff */
  31. aio_read(&kbcbuf); /* place a read request */
  32. signal(SIGALRM, on_alarm); /* install alarm handler */
  33. set_ticker(delay); /* start ticking */
  34. mvaddstr( row, col, MESSAGE ); /* draw initial image */
  35. while( !done ) /* the main loop */
  36. pause();
  37. endwin();
  38. }
  39. /*
  40. * handler called when aio_read() has stuff to read
  41. * First check for any error codes, and if ok, then get the return code
  42. */
  43. void on_input(int dummy)
  44. {
  45. int c;
  46. char *cp = (char *) kbcbuf.aio_buf; /* cast to char * */
  47. /* check for errors */
  48. if ( aio_error(&kbcbuf) != 0 )
  49. perror("reading failed");
  50. else
  51. /* get number of chars read */
  52. if ( aio_return(&kbcbuf) == 1 )
  53. {
  54. c = *cp;
  55. if ( c == 'Q' || c == EOF )
  56. done = 1;
  57. else if ( c == ' ' )
  58. dir = -dir;
  59. else if( c == '+' ){
  60. delay += 10;
  61. set_ticker(delay);
  62. }
  63. else if( c == '-' ){
  64. delay -= 10;
  65. set_ticker(delay);
  66. }
  67. }
  68. /* place a new request */
  69. aio_read(&kbcbuf);
  70. }
  71. void on_alarm(int dummy)
  72. {
  73. signal(SIGALRM, on_alarm); /* reset, just in case */
  74. mvaddstr( row, col, BLANK ); /* clear old string */
  75. col += dir; /* move to new column */
  76. mvaddstr( row, col, MESSAGE ); /* draw new string */
  77. refresh(); /* and show it */
  78. /*
  79. * now handle borders
  80. */
  81. if ( dir == -1 && col <= 0 )
  82. dir = 1;
  83. else if ( dir == 1 && col+strlen(MESSAGE) >= COLS )
  84. dir = -1;
  85. }
  86. /*
  87. * set members of struct.
  88. * First specify args like those for read(fd, buf, num) and offset
  89. * Then specify what to do (send signal) and what signal (SIGIO)
  90. */
  91. void setup_aio_buffer()
  92. {
  93. static char input[1]; /* 1 char of input */
  94. /* describe what to read */
  95. kbcbuf.aio_fildes = 0; /* standard intput */
  96. kbcbuf.aio_buf = input; /* buffer */
  97. kbcbuf.aio_nbytes = 1; /* number to read */
  98. kbcbuf.aio_offset = 0; /* offset in file */
  99. /* describe what to do when read is ready */
  100. kbcbuf.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
  101. kbcbuf.aio_sigevent.sigev_signo = SIGIO; /* send sIGIO */
  102. }