gui_over.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * gui_over.c - GUI, canvas overlays
  3. *
  4. * Written 2009, 2010 by Werner Almesberger
  5. * Copyright 2009, 2010 by Werner Almesberger
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. */
  12. /*
  13. * This file is for the overlay state machine only. Given the heavy use of
  14. * global variables, adding other functionality would quickly render it
  15. * illegible.
  16. */
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include "coord.h"
  20. #include "gui_util.h"
  21. #include "gui_over.h"
  22. #if 0
  23. #define DPRINTF(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
  24. #define DSAVE(pix_buf) debug_save_pixbuf(pix_buf->buf)
  25. #else
  26. #define DPRINTF(fmt, ...)
  27. #define DSAVE(buf)
  28. #endif
  29. static enum states {
  30. NOTHING,
  31. HOVER,
  32. DRAG,
  33. BOTH,
  34. } state = NOTHING;
  35. /*
  36. * We cache some externally provided state so that we can redraw without the
  37. * outside telling us what to redraw, etc.
  38. */
  39. static struct pix_buf *buf_D, *buf_H;
  40. static struct pix_buf *(*over_D_save_and_draw)(void *user, struct coord to);
  41. static void *over_D_user;
  42. static struct pix_buf *(*over_H_save_and_draw)(void *user);
  43. static void *over_H_user;
  44. static struct coord over_pos;
  45. /* ----- actions ----------------------------------------------------------- */
  46. static void draw_D(void)
  47. {
  48. buf_D = over_D_save_and_draw(over_D_user, over_pos);
  49. DSAVE(buf_D);
  50. }
  51. static void draw_H(void)
  52. {
  53. buf_H = over_H_save_and_draw(over_H_user);
  54. DSAVE(buf_H);
  55. }
  56. #define STATE(s) DPRINTF("%s", #s); state = s; break;
  57. #define restore(x) DPRINTF(" restore(%s)", #x); restore_pix_buf(buf_##x)
  58. #define drop(x) DPRINTF(" drop(%s)", #x); free_pix_buf(buf_##x)
  59. #define save(x) DPRINTF(" save(%s)", #x)
  60. #define draw(x) DPRINTF(" draw(%s)", #x); draw_##x()
  61. #define update() DPRINTF(" update"); over_pos = pos
  62. /* ----- state machine ----------------------------------------------------- */
  63. void over_enter(struct pix_buf *(*save_and_draw)(void *user), void *user)
  64. {
  65. over_H_save_and_draw = save_and_draw;
  66. over_H_user = user;
  67. DPRINTF("enter");
  68. switch (state) {
  69. case NOTHING:
  70. save(H);
  71. draw(H);
  72. STATE(HOVER);
  73. case DRAG:
  74. restore(D);
  75. save(H);
  76. draw(H);
  77. save(D);
  78. draw(D);
  79. STATE(BOTH);
  80. default:
  81. abort();
  82. }
  83. }
  84. void over_leave(void)
  85. {
  86. DPRINTF("leave");
  87. switch (state) {
  88. case HOVER:
  89. restore(H);
  90. STATE(NOTHING);
  91. case BOTH:
  92. restore(D);
  93. restore(H);
  94. save(D);
  95. draw(D);
  96. STATE(DRAG);
  97. default:
  98. abort();
  99. }
  100. }
  101. void over_begin(struct pix_buf *(*save_and_draw)(void *user, struct coord to),
  102. void *user, struct coord pos)
  103. {
  104. over_pos = pos;
  105. over_D_save_and_draw = save_and_draw;
  106. over_D_user = user;
  107. DPRINTF("begin");
  108. switch (state) {
  109. case NOTHING:
  110. save(D);
  111. draw(D);
  112. STATE(DRAG);
  113. case HOVER:
  114. save(D);
  115. draw(D);
  116. STATE(BOTH);
  117. default:
  118. abort();
  119. }
  120. }
  121. void over_move(struct coord pos)
  122. {
  123. over_pos = pos;
  124. DPRINTF("move");
  125. switch (state) {
  126. case NOTHING:
  127. break;
  128. case HOVER:
  129. break;
  130. case DRAG:
  131. restore(D);
  132. update();
  133. save(D);
  134. draw(D);
  135. STATE(DRAG);
  136. case BOTH:
  137. restore(D);
  138. update();
  139. save(D);
  140. draw(D);
  141. STATE(BOTH);
  142. default:
  143. abort();
  144. }
  145. }
  146. void over_end(void)
  147. {
  148. DPRINTF("end");
  149. switch (state) {
  150. case DRAG:
  151. restore(D);
  152. STATE(NOTHING);
  153. case BOTH:
  154. restore(D);
  155. STATE(HOVER);
  156. default:
  157. abort();
  158. }
  159. }
  160. void over_reset(void)
  161. {
  162. DPRINTF("reset");
  163. switch (state) {
  164. case NOTHING:
  165. break;
  166. case HOVER:
  167. drop(H);
  168. STATE(NOTHING);
  169. case DRAG:
  170. drop(D);
  171. STATE(NOTHING);
  172. case BOTH:
  173. drop(D);
  174. drop(H);
  175. STATE(NOTHING);
  176. default:
  177. abort();
  178. }
  179. }