bounce_async.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* bounce_async.c
  2. * purpose animation with user control, using O_ASYNC on fd
  3. * note set_ticker() sends SIGALRM, handler does animation
  4. * keyboard sends SIGIO, main only calls pause()
  5. * compile cc bounce_async.c set_ticker.c -lcurses -o bounce_async
  6. */
  7. #include <stdio.h>
  8. #include <curses.h>
  9. #include <signal.h>
  10. #include <fcntl.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. main()
  20. {
  21. void on_alarm(int); /* handler for alarm */
  22. void on_input(int); /* handler for keybd */
  23. void enable_kbd_signals();
  24. initscr(); /* set up screen */
  25. crmode();
  26. noecho();
  27. clear();
  28. signal(SIGIO, on_input); /* install a handler */
  29. enable_kbd_signals(); /* turn on kbd signals */
  30. signal(SIGALRM, on_alarm); /* install alarm handler */
  31. set_ticker(delay); /* start ticking */
  32. move(row,col); /* get into position */
  33. addstr( MESSAGE ); /* draw initial image */
  34. while( !done ) /* the main loop */
  35. pause();
  36. endwin();
  37. }
  38. void on_input(int signum)
  39. {
  40. int c = getch(); /* grab the char */
  41. if ( c == 'Q' || c == EOF )
  42. done = 1;
  43. else if ( c == ' ' )
  44. dir = -dir;
  45. }
  46. void on_alarm(int signum)
  47. {
  48. signal(SIGALRM, on_alarm); /* reset, just in case */
  49. mvaddstr( row, col, BLANK ); /* note mvaddstr() */
  50. col += dir; /* move to new column */
  51. mvaddstr( row, col, MESSAGE ); /* redo message */
  52. refresh(); /* and show it */
  53. /*
  54. * now handle borders
  55. */
  56. if ( dir == -1 && col <= 0 )
  57. dir = 1;
  58. else if ( dir == 1 && col+strlen(MESSAGE) >= COLS )
  59. dir = -1;
  60. }
  61. /*
  62. * install a handler, tell kernel who to notify on input, enable signals
  63. */
  64. void enable_kbd_signals()
  65. {
  66. int fd_flags;
  67. fcntl(0, F_SETOWN, getpid());
  68. fd_flags = fcntl(0, F_GETFL);
  69. fcntl(0, F_SETFL, (fd_flags|O_ASYNC));
  70. }