/ao-tools/ao-view/aoview_replay.c

https://github.com/ajtowns/altos · C · 147 lines · 114 code · 17 blank · 16 comment · 18 complexity · 1dbebe7445dad9583fd8ba2f210a1fc7 MD5 · raw file

  1. /*
  2. * Copyright © 2009 Keith Packard <keithp@keithp.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; version 2 of the License.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  16. */
  17. #include "aoview.h"
  18. static GtkFileChooser *replay_dialog;
  19. static GtkWidget *replay_ok;
  20. static FILE *replay_file;
  21. static int replay_tick;
  22. static int
  23. find_tick(char *line, gboolean *is_pad)
  24. {
  25. char *state = strstr(line, "STATE");
  26. if (!state)
  27. return -1;
  28. state = strchr(state, ' ');
  29. if (!state)
  30. return -1;
  31. while (*state == ' ')
  32. state++;
  33. *is_pad = strncmp(state, "pad", 3) == 0;
  34. while (*state && !isdigit(*state))
  35. state++;
  36. return atoi(state);
  37. }
  38. static void
  39. aoview_replay_close(void)
  40. {
  41. if (replay_file) {
  42. fclose(replay_file);
  43. replay_file = NULL;
  44. }
  45. }
  46. static char replay_line[1024];
  47. static gboolean
  48. aoview_replay_read(gpointer data);
  49. static gboolean
  50. aoview_replay_execute(gpointer data)
  51. {
  52. aoview_monitor_parse(replay_line);
  53. g_idle_add(aoview_replay_read, NULL);
  54. return FALSE;
  55. }
  56. static gboolean
  57. aoview_replay_read(gpointer data)
  58. {
  59. int tick;
  60. gboolean is_pad;
  61. if (!replay_file)
  62. return FALSE;
  63. if (fgets(replay_line, sizeof (replay_line), replay_file)) {
  64. tick = find_tick(replay_line, &is_pad);
  65. if (tick >= 0 && replay_tick >= 0 && !is_pad) {
  66. while (tick < replay_tick)
  67. tick += 65536;
  68. g_timeout_add((tick - replay_tick) * 10,
  69. aoview_replay_execute,
  70. NULL);
  71. } else {
  72. aoview_replay_execute(NULL);
  73. }
  74. replay_tick = tick;
  75. } else {
  76. aoview_replay_close();
  77. }
  78. return FALSE;
  79. }
  80. static void
  81. aoview_replay_open(GtkWidget *widget, gpointer data)
  82. {
  83. char *replay_file_name;
  84. GtkWidget *dialog;
  85. aoview_replay_close();
  86. replay_file_name = gtk_file_chooser_get_filename(replay_dialog);
  87. replay_file = fopen(replay_file_name, "r");
  88. if (!replay_file) {
  89. dialog = gtk_message_dialog_new(GTK_WINDOW(replay_dialog),
  90. GTK_DIALOG_DESTROY_WITH_PARENT,
  91. GTK_MESSAGE_ERROR,
  92. GTK_BUTTONS_CLOSE,
  93. "Error loading file '%s': %s",
  94. replay_file_name, g_strerror(errno));
  95. gtk_dialog_run(GTK_DIALOG(dialog));
  96. gtk_widget_destroy(dialog);
  97. } else {
  98. replay_tick = -1;
  99. aoview_state_reset();
  100. aoview_replay_read(NULL);
  101. }
  102. gtk_widget_hide(GTK_WIDGET(replay_dialog));
  103. }
  104. void
  105. aoview_replay_init(GladeXML *xml)
  106. {
  107. GtkFileFilter *telem_filter;
  108. GtkFileFilter *all_filter;
  109. GtkFileFilter *log_filter;
  110. telem_filter = gtk_file_filter_new();
  111. gtk_file_filter_add_pattern(telem_filter, "*.telem");
  112. gtk_file_filter_set_name(telem_filter, "Telemetry Files");
  113. log_filter = gtk_file_filter_new();
  114. gtk_file_filter_add_pattern(log_filter, "*.log");
  115. gtk_file_filter_set_name(log_filter, "Log Files");
  116. all_filter = gtk_file_filter_new();
  117. gtk_file_filter_add_pattern(all_filter, "*");
  118. gtk_file_filter_set_name(all_filter, "All Files");
  119. replay_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "ao_replay_dialog"));
  120. assert(replay_dialog);
  121. gtk_file_chooser_set_current_folder(replay_dialog, aoview_file_dir);
  122. gtk_file_chooser_add_filter(replay_dialog, telem_filter);
  123. gtk_file_chooser_add_filter(replay_dialog, log_filter);
  124. gtk_file_chooser_add_filter(replay_dialog, all_filter);
  125. replay_ok = glade_xml_get_widget(xml, "ao_replay_ok");
  126. assert(replay_ok);
  127. g_signal_connect(G_OBJECT(replay_ok), "clicked",
  128. G_CALLBACK(aoview_replay_open),
  129. replay_dialog);
  130. }