screen.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <cursor.h>
  5. #include <event.h>
  6. #include <bio.h>
  7. #include "proof.h"
  8. static int checkmouse(void);
  9. static int buttondown(void);
  10. static char *getmousestr(void);
  11. static char *getkbdstr(int);
  12. extern Cursor blot;
  13. extern char *track;
  14. Mouse mouse;
  15. void
  16. mapscreen(void)
  17. {
  18. if(initdraw(0, 0, "proof") < 0){
  19. fprint(2, "proof: initdraw failed: %r\n");
  20. exits("initdraw");
  21. }
  22. einit(Ekeyboard|Emouse);
  23. }
  24. void
  25. clearscreen(void)
  26. {
  27. draw(screen, screen->r, display->black, nil, ZP);
  28. }
  29. void
  30. screenprint(char *fmt, ...)
  31. {
  32. char buf[100];
  33. Point p;
  34. va_list args;
  35. va_start(args, fmt);
  36. vseprint(buf, &buf[sizeof buf], fmt, args);
  37. va_end(args);
  38. p = Pt(screen->clipr.min.x+40, screen->clipr.max.y-40);
  39. string(screen, p, display->black, ZP, font, buf);
  40. }
  41. #define Viewkey 0xb2
  42. char *
  43. getcmdstr(void)
  44. {
  45. Event ev;
  46. int e;
  47. static ulong timekey = 0;
  48. ulong tracktm = 0;
  49. Dir *dir;
  50. if(track){
  51. if(timekey == 0)
  52. timekey = etimer(0, 5000);
  53. dir = dirstat(track);
  54. if(dir != nil){
  55. tracktm = dir->mtime;
  56. free(dir);
  57. }
  58. }
  59. for (;;) {
  60. e = event(&ev);
  61. if(resized){
  62. resized = 0;
  63. return "p";
  64. }
  65. if ((e & Emouse) && ev.mouse.buttons) {
  66. mouse = ev.mouse;
  67. return getmousestr();
  68. } else if (e & Ekeyboard)
  69. return getkbdstr(ev.kbdc); /* sadly, no way to unget */
  70. else if (e & timekey) {
  71. if((dir = dirstat(track)) != nil){
  72. if(tracktm < dir->mtime){
  73. free(dir);
  74. return "q";
  75. }
  76. free(dir);
  77. }
  78. }
  79. }
  80. }
  81. static char *
  82. getkbdstr(int c0)
  83. {
  84. static char buf[100];
  85. char *p;
  86. int c;
  87. if (c0 == '\n')
  88. return "";
  89. buf[0] = c0;
  90. buf[1] = 0;
  91. screenprint("%s", buf);
  92. for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) {
  93. if (c == '\b' && p > buf) {
  94. *--p = ' ';
  95. } else {
  96. *p++ = c;
  97. *p = 0;
  98. }
  99. screenprint("%s", buf);
  100. }
  101. *p = 0;
  102. return buf;
  103. }
  104. #define button3(b) ((b) & 4)
  105. #define button2(b) ((b) & 2)
  106. #define button1(b) ((b) & 1)
  107. #define button23(b) ((b) & 6)
  108. #define button123(b) ((b) & 7)
  109. #define butcvt(b) (1 << ((b) - 1))
  110. static int buttondown(void) /* report state of buttons, if any */
  111. {
  112. if (!ecanmouse()) /* no event pending */
  113. return 0;
  114. mouse = emouse(); /* something, but it could be motion */
  115. return mouse.buttons & 7;
  116. }
  117. int waitdown(void) /* wait until some button is down */
  118. {
  119. while (!(mouse.buttons & 7))
  120. mouse = emouse();
  121. return mouse.buttons & 7;
  122. }
  123. int waitup(void)
  124. {
  125. while (mouse.buttons & 7)
  126. mouse = emouse();
  127. return mouse.buttons & 7;
  128. }
  129. char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };
  130. char *m2[] = { 0 };
  131. enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit };
  132. Menu mbut3 = { m3, 0, 0 };
  133. Menu mbut2 = { m2, 0, 0 };
  134. int last_hit;
  135. int last_but;
  136. char *pan(void)
  137. {
  138. Point dd, xy, lastxy, min, max;
  139. esetcursor(&blot);
  140. waitdown();
  141. xy = mouse.xy;
  142. do{
  143. lastxy = mouse.xy;
  144. mouse = emouse();
  145. dd = subpt(mouse.xy, lastxy);
  146. min = addpt(screen->clipr.min, dd);
  147. max = addpt(screen->clipr.max, dd);
  148. draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)),
  149. screen, nil, screen->r.min);
  150. if(mouse.xy.x < lastxy.x) /* moved left, clear right */
  151. draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y),
  152. display->white, nil, ZP);
  153. else /* moved right, clear left*/
  154. draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y),
  155. display->white, nil, ZP);
  156. if(mouse.xy.y < lastxy.y) /* moved up, clear down */
  157. draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y),
  158. display->white, nil, ZP);
  159. else /* moved down, clear up */
  160. draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y),
  161. display->white, nil, ZP);
  162. flushimage(display, 1);
  163. }while(mouse.buttons);
  164. xyoffset = addpt(xyoffset, subpt(mouse.xy, xy));
  165. esetcursor(0);
  166. return "p";
  167. }
  168. static char *
  169. getmousestr(void)
  170. {
  171. static char buf[64];
  172. checkmouse();
  173. if (last_but == 1)
  174. return "p"; /* repaint after panning */
  175. if (last_but == 2) {
  176. return "c";
  177. } else if (last_but == 3) {
  178. switch (last_hit) {
  179. case Next:
  180. return "";
  181. case Prev:
  182. return "-1";
  183. case Page:
  184. screenprint("page? ");
  185. return "c";
  186. case Again:
  187. return "p";
  188. case Bigger:
  189. snprint(buf, sizeof buf, "m%g", mag * 1.1);
  190. return buf;
  191. case Smaller:
  192. snprint(buf, sizeof buf, "m%g", mag / 1.1);
  193. return buf;
  194. case Pan:
  195. return pan();
  196. case Quit:
  197. return "q";
  198. default:
  199. return "c";
  200. }
  201. } else { /* button 1 or bail out */
  202. return "c";
  203. }
  204. }
  205. static int
  206. checkmouse(void) /* return button touched if any */
  207. {
  208. int c, b;
  209. char *p;
  210. extern int confirm(int);
  211. b = waitdown();
  212. last_but = 0;
  213. last_hit = -1;
  214. c = 0;
  215. if (button3(b)) {
  216. last_hit = emenuhit(3, &mouse, &mbut3);
  217. last_but = 3;
  218. } else if (button2(b)) {
  219. last_hit = emenuhit(2, &mouse, &mbut2);
  220. last_but = 2;
  221. } else { /* button1() */
  222. pan();
  223. last_but = 1;
  224. }
  225. waitup();
  226. if (last_but == 3 && last_hit >= 0) {
  227. p = m3[last_hit];
  228. c = p[strlen(p) - 1];
  229. }
  230. if (c == '?' && !confirm(last_but))
  231. last_hit = -1;
  232. return last_but;
  233. }
  234. Cursor deadmouse = {
  235. { 0, 0}, /* offset */
  236. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  237. 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
  238. 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
  239. 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
  240. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  241. 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
  242. 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
  243. 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
  244. };
  245. Cursor blot ={
  246. { 0, 0 },
  247. { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  248. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  249. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  250. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
  251. { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  252. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  253. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  254. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
  255. };
  256. Cursor skull ={
  257. { 0, 0 },
  258. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
  259. 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
  260. 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
  261. 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
  262. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
  263. 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
  264. 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
  265. 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
  266. };
  267. confirm(int but) /* ask for confirmation if menu item ends with '?' */
  268. {
  269. int c;
  270. static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 };
  271. esetcursor(&skull);
  272. c = waitdown();
  273. waitup();
  274. esetcursor(0);
  275. return but == but_cvt[c];
  276. }