Logiciels divers autour du protocole « Open Sound Control » aka OSC
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
7.1 KiB

  1. /*
  2. * SHOW BUTTONS
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7. #include <unistd.h>
  8. #include <errno.h>
  9. #include <getopt.h>
  10. #include <lo/lo.h>
  11. #include "functions/ncursefuncs.h"
  12. /* ----------------------------------------------------------------- */
  13. #define LOCAL_PORT "9002"
  14. #define NB_BUTTONS 24
  15. int verbosity;
  16. typedef struct {
  17. int type;
  18. int value;
  19. char texte[20];
  20. } Event;
  21. #define BUTTONS_EV 1
  22. #define XY_EV 2
  23. #define ID_EV 3
  24. static int count;
  25. static int pipefd[2];
  26. #define EVNT_RD (pipefd[0])
  27. #define EVNT_WR (pipefd[1])
  28. unsigned char buttons[NB_BUTTONS];
  29. short xy_values[2];
  30. /* ----------------------------------------------------------------- */
  31. #define LINE0 8 /* vertical position of the top line */
  32. int draw_buttons(unsigned char *states, int nbre, int unused)
  33. {
  34. int idx, pos_c, pos_l;
  35. char txt[20];
  36. #if DEBUG_LEVEL
  37. fprintf(stderr, "--> %s ( %p %d )\n", __func__, states, nbre);
  38. #endif
  39. for (idx=0; idx<nbre; idx++) {
  40. pos_c = 5 + ((idx % 8) * 9);
  41. pos_l = LINE0 + ((idx / 8) * 5);
  42. sprintf(txt, "%03d", idx);
  43. draw_a_button(stdscr, pos_l, pos_c, txt, states[idx]);
  44. }
  45. return 0;
  46. }
  47. /* ----------------------------------------------------------------- */
  48. int display_a_value(int lig, short value, char letter)
  49. {
  50. char buffer[80], symbol;
  51. int width, seuil, foo;
  52. sprintf(buffer, "%6d [", value);
  53. mvaddstr(lig, 4, buffer);
  54. if (value < 0) symbol = '-';
  55. else symbol = '+';
  56. width = 60;
  57. seuil = (abs((int)value) * width) / 32767;
  58. #if DEBUG_LEVEL > 1
  59. fprintf(stderr, "in %s : value=%6d, seuil=%d\n", __func__, value, seuil);
  60. #endif
  61. for (foo=0; foo<width; foo++) {
  62. if (foo < seuil) mvaddch(lig, foo+12, symbol);
  63. else mvaddch(lig, foo+12, ' ');
  64. }
  65. refresh();
  66. #if DEBUG_LEVEL > 1
  67. sprintf(buffer, "%s : %6d ", __func__, value);
  68. blast_error_message(buffer, 0, 0);
  69. #endif
  70. return 0;
  71. }
  72. /* ----------------------------------------------------------------- */
  73. int display_values(short *vals, int nbre, int ligne)
  74. {
  75. int foo;
  76. char buffer[80];
  77. for (foo=0; foo<nbre; foo ++) {
  78. display_a_value(ligne + foo, vals[foo], '?');
  79. }
  80. return 0;
  81. }
  82. /* ----------------------------------------------------------------- */
  83. int animation(int cycles, int speed)
  84. {
  85. int foo;
  86. short values[2];
  87. #if DEBUG_LEVEL
  88. fprintf(stderr, "entering %s ( %d %d )\n", __func__, cycles, speed);
  89. #endif
  90. for (foo=0; foo<cycles; foo++) {
  91. draw_buttons(buttons, NB_BUTTONS, 0);
  92. display_values(values, 2, 2);
  93. refresh();
  94. usleep(speed*1000);
  95. buttons[rand()%NB_BUTTONS] = rand() & 1;
  96. values[0] += rand() % 320;
  97. values[0] = abs(values[0]);
  98. if (rand()%100 < 10)
  99. values[1] = rand() % 32000;
  100. }
  101. /* may be we can make some cleanup after the show ? */
  102. return 0;
  103. }
  104. /* ----------------------------------------------------------------- */
  105. int do_animation(int cycles, int speed)
  106. {
  107. (void)initcurses();
  108. animation(cycles, speed);
  109. sleep(2);
  110. exit(0);
  111. return 0;
  112. }
  113. /* ----------------------------------------------------------------- */
  114. void error(int num, const char *msg, const char *path)
  115. {
  116. fprintf(stderr, "liblo server error %d in path %s : %s\n", num, path, msg);
  117. exit(1);
  118. }
  119. /* ----------------------------------------------------------------- */
  120. int xy_handler(const char *path, const char *types, lo_arg ** argv,
  121. int argc, void *data, void *user_data)
  122. {
  123. int x, y, foo;
  124. Event evt;
  125. #if DEBUG_LEVEL
  126. fprintf(stderr, "%s : %s %s %d %p\n", __func__,
  127. path, types, argc, user_data);
  128. #endif
  129. x = argv[0]->i; y = argv[1]->i;
  130. /* may be we can bound-check that pair or values ? */
  131. xy_values[0] = x; xy_values[1] = y;
  132. evt.type = XY_EV; evt.value = 0x55;
  133. foo = write(EVNT_WR, &evt, sizeof(Event));
  134. if (sizeof(Event) != foo) {
  135. fprintf(stderr, "%s : fifo error %d\n", __func__, errno);
  136. exit(1);
  137. }
  138. count++;
  139. return 0;
  140. }
  141. /* ----------------------------------------------------------------- */
  142. int id_handler(const char *path, const char *types, lo_arg ** argv,
  143. int argc, void *data, void *user_data)
  144. {
  145. Event evt;
  146. int foo;
  147. evt.type = ID_EV; evt.value = 0x55;
  148. foo = write(EVNT_WR, &evt, sizeof(Event));
  149. if (sizeof(Event) != foo) {
  150. fprintf(stderr, "%s : fifo error %d\n", __func__, errno);
  151. exit(1);
  152. }
  153. return 0;
  154. }
  155. /* ----------------------------------------------------------------- */
  156. int button_handler(const char *path, const char *types, lo_arg ** argv,
  157. int argc, void *data, void *user_data)
  158. {
  159. // char ligne[80];
  160. int button, state, foo;
  161. Event evt;
  162. #if DEBUG_LEVEL
  163. fprintf(stderr, "%s : %s %s %d %p\n", __func__,
  164. path, types, argc, user_data);
  165. #endif
  166. button = argv[0]->i; state = argv[1]->i;
  167. if (button<0 || button>=NB_BUTTONS) {
  168. return 1;
  169. }
  170. ((unsigned char *)user_data)[button] = state;
  171. evt.type = BUTTONS_EV; evt.value = 0x55;
  172. foo = write(EVNT_WR, &evt, sizeof(Event));
  173. if (sizeof(Event) != foo) {
  174. fprintf(stderr, "%s : fifo error %d\n", __func__, errno);
  175. exit(1);
  176. }
  177. count++;
  178. return 0;
  179. }
  180. /* ----------------------------------------------------------------- */
  181. static void help(int k)
  182. {
  183. puts("\t * showbuttons " __DATE__ " *");
  184. puts("\t-a\tshow animation");
  185. puts("\t-p\tlocal udp port ("LOCAL_PORT")");
  186. puts("\t-v\tenhance my verbosity");
  187. exit(0);
  188. }
  189. /* ----------------------------------------------------------------- */
  190. int main(int argc, char *argv[])
  191. {
  192. int foo;
  193. lo_server_thread st;
  194. char *local_port = LOCAL_PORT;
  195. int opt;
  196. char ligne[81];
  197. long tdebut;
  198. Event event;
  199. /* parsing command line options */
  200. while ((opt = getopt(argc, argv, "ahp:vE:C:")) != -1) {
  201. switch (opt) {
  202. case 'a': do_animation(200, 20); break;
  203. case 'h': help(0); break;
  204. case 'p': local_port = optarg; break;
  205. case 'v': verbosity++; break;
  206. default: exit(1);
  207. }
  208. }
  209. tdebut = time(NULL);
  210. count = 0;
  211. /*
  212. * setup the inter-thread event synthetizer
  213. */
  214. foo = pipe(pipefd);
  215. if (foo) {
  216. perror("event synth");
  217. exit(1);
  218. }
  219. /* set up the pretty screen user interface */
  220. foo = initcurses();
  221. sprintf(ligne, ":%s ", local_port);
  222. foo = draw_main_screen(ligne, 0);
  223. if (foo) {
  224. endwin();
  225. fprintf(stderr, "main screen : err %d\n", foo);
  226. exit(1);
  227. }
  228. /* fireup the OSC liblo engine */
  229. st = lo_server_thread_new(local_port, error);
  230. #if DEBUG_LEVEL
  231. fprintf(stderr, "Address of 'values' = %p\n", buttons);
  232. #endif
  233. lo_server_thread_add_method(st, "/joystick/b", "ii",
  234. button_handler, buttons);
  235. lo_server_thread_add_method(st, "/joystick/xy", "ii",
  236. xy_handler, NULL);
  237. lo_server_thread_start(st);
  238. sprintf(ligne, "process %d on board, captain", getpid());
  239. blast_error_message(ligne, 0, 0);
  240. sleep(1);
  241. for (;;) {
  242. /* wait for un event from liblo threads */
  243. foo = read(EVNT_RD, &event, sizeof(Event));
  244. if (sizeof(Event) != foo) { /* FAILURE */
  245. perror("event fifo read error");
  246. exit(1);
  247. }
  248. #if DEBUG_LEVEL
  249. fprintf(stderr, "event %5d %8d %s\n",
  250. event.type, event.value, event.texte);
  251. #endif
  252. switch (event.type) {
  253. case BUTTONS_EV:
  254. draw_buttons(buttons, NB_BUTTONS, 0);
  255. break;
  256. case XY_EV:
  257. display_values(xy_values, 2, 4);
  258. break;
  259. case ID_EV:
  260. break;
  261. default:
  262. blast_error_message("bad event", 0, 0);
  263. break;
  264. }
  265. }
  266. if (verbosity)
  267. { fprintf(stderr, "elapsed %ld s.\n", time(NULL)-tdebut); }
  268. return 0;
  269. }
  270. /* ----------------------------------------------------------------- */