dots_mvcur.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /****************************************************************************
  2. * Copyright 2019,2020 Thomas E. Dickey *
  3. * Copyright 2007-2013,2017 Free Software Foundation, Inc. *
  4. * *
  5. * Permission is hereby granted, free of charge, to any person obtaining a *
  6. * copy of this software and associated documentation files (the *
  7. * "Software"), to deal in the Software without restriction, including *
  8. * without limitation the rights to use, copy, modify, merge, publish, *
  9. * distribute, distribute with modifications, sublicense, and/or sell *
  10. * copies of the Software, and to permit persons to whom the Software is *
  11. * furnished to do so, subject to the following conditions: *
  12. * *
  13. * The above copyright notice and this permission notice shall be included *
  14. * in all copies or substantial portions of the Software. *
  15. * *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
  17. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
  19. * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
  20. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
  21. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
  22. * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
  23. * *
  24. * Except as contained in this notice, the name(s) of the above copyright *
  25. * holders shall not be used in advertising or otherwise to promote the *
  26. * sale, use or other dealings in this Software without prior written *
  27. * authorization. *
  28. ****************************************************************************/
  29. /*
  30. * Author: Thomas E. Dickey - 2007
  31. *
  32. * $Id: dots_mvcur.c,v 1.26 2020/05/29 23:04:02 tom Exp $
  33. *
  34. * A simple demo of the terminfo interface, and mvcur.
  35. */
  36. #define USE_TINFO
  37. #include <test.priv.h>
  38. #if HAVE_SETUPTERM
  39. #include <time.h>
  40. static bool interrupted = FALSE;
  41. static long total_chars = 0;
  42. static time_t started;
  43. static
  44. TPUTS_PROTO(outc, c)
  45. {
  46. int rc = c;
  47. if (interrupted) {
  48. char tmp = (char) c;
  49. if (write(STDOUT_FILENO, &tmp, (size_t) 1) == -1)
  50. rc = EOF;
  51. } else {
  52. if (putc(c, stdout) == EOF)
  53. rc = EOF;
  54. }
  55. TPUTS_RETURN(rc);
  56. }
  57. static bool
  58. outs(const char *s)
  59. {
  60. if (VALID_STRING(s)) {
  61. tputs(s, 1, outc);
  62. return TRUE;
  63. }
  64. return FALSE;
  65. }
  66. static void
  67. cleanup(void)
  68. {
  69. outs(exit_attribute_mode);
  70. if (!outs(orig_colors))
  71. outs(orig_pair);
  72. outs(clear_screen);
  73. outs(cursor_normal);
  74. fflush(stdout);
  75. fprintf(stderr, "\n\n%ld total cells, rate %.2f/sec\n",
  76. total_chars,
  77. ((double) (total_chars) / (double) (time((time_t *) 0) - started)));
  78. }
  79. static void
  80. onsig(int n GCC_UNUSED)
  81. {
  82. interrupted = TRUE;
  83. }
  84. static double
  85. ranf(void)
  86. {
  87. long r = (rand() & 077777);
  88. return ((double) r / 32768.);
  89. }
  90. static int
  91. get_number(NCURSES_CONST char *cap, int map)
  92. {
  93. int result = map;
  94. if (cap != 0) {
  95. int check = tigetnum(cap);
  96. if (check > 0)
  97. result = check;
  98. }
  99. return result;
  100. }
  101. static void
  102. usage(void)
  103. {
  104. static const char *msg[] =
  105. {
  106. "Usage: dots_termcap [options]"
  107. ,""
  108. ,"Options:"
  109. ," -T TERM override $TERM"
  110. #if HAVE_USE_ENV
  111. ," -e allow environment $LINES / $COLUMNS"
  112. #endif
  113. ," -f use tigetnum rather than <term.h> mapping"
  114. ," -m SIZE set margin (default: 2)"
  115. ," -r SECS self-interrupt/exit after specified number of seconds"
  116. ," -s MSECS delay 1% of the time (default: 1 msecs)"
  117. };
  118. size_t n;
  119. for (n = 0; n < SIZEOF(msg); n++)
  120. fprintf(stderr, "%s\n", msg[n]);
  121. ExitProgram(EXIT_FAILURE);
  122. }
  123. int
  124. main(int argc GCC_UNUSED,
  125. char *argv[]GCC_UNUSED)
  126. {
  127. int x0 = 1, y0 = 1;
  128. int ch;
  129. double r;
  130. double c;
  131. SCREEN *sp;
  132. int my_colors;
  133. int f_option = 0;
  134. int m_option = 2;
  135. int r_option = 0;
  136. int s_option = 1;
  137. size_t need;
  138. char *my_env;
  139. while ((ch = getopt(argc, argv, "T:efm:r:s:")) != -1) {
  140. switch (ch) {
  141. case 'T':
  142. need = 6 + strlen(optarg);
  143. my_env = malloc(need);
  144. _nc_SPRINTF(my_env, _nc_SLIMIT(need) "TERM=%s", optarg);
  145. putenv(my_env);
  146. break;
  147. #if HAVE_USE_ENV
  148. case 'e':
  149. use_env(TRUE);
  150. break;
  151. #endif
  152. case 'f':
  153. f_option = 1;
  154. break;
  155. case 'm':
  156. m_option = atoi(optarg);
  157. break;
  158. case 'r':
  159. r_option = atoi(optarg);
  160. break;
  161. case 's':
  162. s_option = atoi(optarg);
  163. break;
  164. default:
  165. usage();
  166. break;
  167. }
  168. }
  169. SetupAlarm(r_option);
  170. InitAndCatch((sp = newterm((char *) 0, stdout, stdin)), onsig);
  171. refresh(); /* needed with Solaris curses to cancel endwin */
  172. if (sp == 0) {
  173. fprintf(stderr, "Cannot initialize terminal\n");
  174. ExitProgram(EXIT_FAILURE);
  175. }
  176. srand((unsigned) time(0));
  177. outs(clear_screen);
  178. outs(cursor_home);
  179. outs(cursor_invisible);
  180. #define GetNumber(ln,sn) get_number(f_option ? #sn : 0, ln)
  181. my_colors = GetNumber(max_colors, colors);
  182. if (my_colors > 1) {
  183. if (!VALID_STRING(set_a_foreground)
  184. || !VALID_STRING(set_a_background)
  185. || (!VALID_STRING(orig_colors) && !VALID_STRING(orig_pair)))
  186. my_colors = -1;
  187. }
  188. r = (double) (GetNumber(lines, lines) - (m_option * 2));
  189. c = (double) (GetNumber(columns, cols) - (m_option * 2));
  190. started = time((time_t *) 0);
  191. while (!interrupted) {
  192. int x = (int) (c * ranf()) + m_option;
  193. int y = (int) (r * ranf()) + m_option;
  194. int p = (ranf() > 0.9) ? '*' : ' ';
  195. if (mvcur(y0, x0, y, x) != ERR) {
  196. x0 = x;
  197. y0 = y;
  198. }
  199. if (my_colors > 0) {
  200. int z = (int) (ranf() * my_colors);
  201. if (ranf() > 0.01) {
  202. tputs(tparm2(set_a_foreground, z), 1, outc);
  203. } else {
  204. tputs(tparm2(set_a_background, z), 1, outc);
  205. if (s_option)
  206. napms(s_option);
  207. }
  208. } else if (VALID_STRING(exit_attribute_mode)
  209. && VALID_STRING(enter_reverse_mode)) {
  210. if (ranf() <= 0.01) {
  211. outs((ranf() > 0.6)
  212. ? enter_reverse_mode
  213. : exit_attribute_mode);
  214. if (s_option)
  215. napms(s_option);
  216. }
  217. }
  218. outc(p);
  219. ++x0;
  220. fflush(stdout);
  221. ++total_chars;
  222. }
  223. cleanup();
  224. endwin();
  225. delscreen(sp);
  226. ExitProgram(EXIT_SUCCESS);
  227. }
  228. #else
  229. int
  230. main(int argc GCC_UNUSED,
  231. char *argv[]GCC_UNUSED)
  232. {
  233. fprintf(stderr, "This program requires terminfo\n");
  234. exit(EXIT_FAILURE);
  235. }
  236. #endif