scribble.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <draw.h>
  12. #include <thread.h>
  13. #include <mouse.h>
  14. #include <keyboard.h>
  15. #include <control.h>
  16. #include <scribble.h>
  17. typedef struct Scrib Scrib;
  18. struct Scrib
  19. {
  20. Control Control;
  21. int border;
  22. CImage *image;
  23. CImage *color;
  24. CImage *bordercolor;
  25. CFont *font;
  26. int align;
  27. int lastbut;
  28. char lastchar[8];
  29. Scribble *scrib;
  30. };
  31. enum{
  32. EAlign,
  33. EBorder,
  34. EBordercolor,
  35. EFocus,
  36. EFont,
  37. EHide,
  38. EImage,
  39. ELinecolor,
  40. ERect,
  41. EReveal,
  42. EShow,
  43. ESize,
  44. };
  45. static char *cmds[] = {
  46. [EAlign] = "align",
  47. [EBorder] = "border",
  48. [EBordercolor] ="bordercolor",
  49. [EFocus] = "focus",
  50. [EFont] = "font",
  51. [EHide] = "hide",
  52. [EImage] = "image",
  53. [ELinecolor] = "linecolor",
  54. [ERect] = "rect",
  55. [EReveal] = "reveal",
  56. [EShow] = "show",
  57. [ESize] = "size",
  58. nil
  59. };
  60. static void scribshow(Scrib*);
  61. static void scribchar(Scrib*, Rune);
  62. static void resetstroke(Scrib *w);
  63. static void displaylast(Scrib *w);
  64. static void addpoint(Scrib *w, Point p);
  65. static void
  66. scribmouse(Control *c, Mouse *m)
  67. {
  68. Scrib *b;
  69. Rune r;
  70. b = (Scrib*)c;
  71. if (m->buttons & 0x1) {
  72. if ((b->lastbut & 0x1) == 0) {
  73. /* mouse went down */
  74. resetstroke(b);
  75. }
  76. /* mouse is down */
  77. if (ptinrect(m->xy,b->Control.rect))
  78. addpoint(b, m->xy);
  79. } else if (b->lastbut & 0x1) {
  80. /* mouse went up */
  81. if (ptinrect(m->xy,b->Control.rect)) {
  82. r = recognize(b->scrib);
  83. scribchar(b, r);
  84. scribshow(b);
  85. if (r) chanprint(b->Control.event, b->Control.format, b->Control.name, r);
  86. }
  87. }
  88. b->lastbut = m->buttons;
  89. }
  90. static void
  91. scribfree(Control *c)
  92. {
  93. Scrib *b;
  94. b = (Scrib*)c;
  95. _putctlimage(b->image);
  96. _putctlimage(b->color);
  97. _putctlimage(b->bordercolor);
  98. _putctlfont(b->font);
  99. // scribblefree(b->scrib);
  100. }
  101. static void
  102. scribchar(Scrib *b, Rune r)
  103. {
  104. if(r == 0)
  105. b->lastchar[0] = '\0';
  106. else if(r == ' ')
  107. strcpy(b->lastchar, "' '");
  108. else if(r < ' ')
  109. sprint(b->lastchar, "ctl-%c", r+'@');
  110. else
  111. sprint(b->lastchar, "%C", r);
  112. }
  113. static void
  114. scribshow(Scrib *b)
  115. {
  116. Image *i;
  117. Rectangle r;
  118. char *mode;
  119. Scribble *s = b->scrib;
  120. char buf[32];
  121. if (b->Control.hidden)
  122. return;
  123. if(b->border > 0){
  124. r = insetrect(b->Control.rect, b->border);
  125. border(b->Control.screen, b->Control.rect, b->border, b->bordercolor->image, ZP);
  126. }else
  127. r = b->Control.rect;
  128. i = b->image->image;
  129. draw(b->Control.screen, r, i, nil, i->r.min);
  130. if (s->ctrlShift)
  131. mode = " ^C";
  132. else if (s->puncShift)
  133. mode = " #&^";
  134. else if (s->curCharSet == CS_DIGITS)
  135. mode = " 123";
  136. else if (s->capsLock)
  137. mode = " ABC";
  138. else if (s->tmpShift)
  139. mode = " Abc";
  140. else
  141. mode = " abc";
  142. snprint(buf, sizeof buf, "%s %s", mode, b->lastchar);
  143. string(b->Control.screen, r.min, b->color->image, ZP, b->font->font, buf);
  144. flushimage(display, 1);
  145. }
  146. static void
  147. scribctl(Control *c, CParse *cp)
  148. {
  149. int cmd;
  150. Rectangle r;
  151. Scrib *b;
  152. b = (Scrib*)c;
  153. cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
  154. switch(cmd){
  155. default:
  156. abort();
  157. ctlerror("%q: unrecognized message '%s'", b->Control.name, cp->str);
  158. break;
  159. case EAlign:
  160. _ctlargcount(&b->Control, cp, 2);
  161. b->align = _ctlalignment(cp->args[1]);
  162. break;
  163. case EBorder:
  164. _ctlargcount(&b->Control, cp, 2);
  165. if(cp->iargs[1] < 0)
  166. ctlerror("%q: bad border: %c", b->Control.name, cp->str);
  167. b->border = cp->iargs[1];
  168. break;
  169. case EBordercolor:
  170. _ctlargcount(&b->Control, cp, 2);
  171. _setctlimage(&b->Control, &b->bordercolor, cp->args[1]);
  172. break;
  173. case EFocus:
  174. break;
  175. case EImage:
  176. _ctlargcount(&b->Control, cp, 2);
  177. _setctlimage(&b->Control, &b->image, cp->args[1]);
  178. break;
  179. case ELinecolor:
  180. _ctlargcount(&b->Control, cp, 2);
  181. _setctlimage(&b->Control, &b->bordercolor, cp->args[1]);
  182. break;
  183. case ERect:
  184. _ctlargcount(&b->Control, cp, 5);
  185. r.min.x = cp->iargs[1];
  186. r.min.y = cp->iargs[2];
  187. r.max.x = cp->iargs[3];
  188. r.max.y = cp->iargs[4];
  189. if(Dx(r)<0 || Dy(r)<0)
  190. ctlerror("%q: bad rectangle: %s", b->Control.name, cp->str);
  191. b->Control.rect = r;
  192. break;
  193. case EReveal:
  194. _ctlargcount(&b->Control, cp, 1);
  195. b->Control.hidden = 0;
  196. scribshow(b);
  197. break;
  198. case EShow:
  199. _ctlargcount(&b->Control, cp, 1);
  200. scribshow(b);
  201. break;
  202. case EFont:
  203. _ctlargcount(&b->Control, cp, 2);
  204. _setctlfont(&b->Control, &b->font, cp->args[1]);
  205. break;
  206. case EHide:
  207. _ctlargcount(&b->Control, cp, 1);
  208. b->Control.hidden = 1;
  209. break;
  210. case ESize:
  211. if (cp->nargs == 3)
  212. r.max = Pt(0x7fffffff, 0x7fffffff);
  213. else{
  214. _ctlargcount(&b->Control, cp, 5);
  215. r.max.x = cp->iargs[3];
  216. r.max.y = cp->iargs[4];
  217. }
  218. r.min.x = cp->iargs[1];
  219. r.min.y = cp->iargs[2];
  220. if(r.min.x<=0 || r.min.y<=0 || r.max.x<=0 || r.max.y<=0 || r.max.x < r.min.x || r.max.y < r.min.y)
  221. ctlerror("%q: bad sizes: %s", b->Control.name, cp->str);
  222. b->Control.size.min = r.min;
  223. b->Control.size.max = r.max;
  224. break;
  225. }
  226. }
  227. static void
  228. resetstroke(Scrib *w)
  229. {
  230. Scribble *s = w->scrib;
  231. s->ps.npts = 0;
  232. scribshow(w);
  233. }
  234. static void
  235. displaylast(Scrib *w)
  236. {
  237. int npt;
  238. Scribble *s = w->scrib;
  239. npt = s->ps.npts;
  240. if (npt > 2)
  241. npt = 2;
  242. poly(w->Control.screen, s->pt + (s->ps.npts - npt), npt, Endsquare, Endsquare,
  243. 0, w->color->image, ZP);
  244. flushimage(display, 1);
  245. }
  246. static void
  247. addpoint(Scrib *w, Point p)
  248. {
  249. pen_point *ppa;
  250. Point *pt;
  251. int ppasize;
  252. Scribble *s = w->scrib;
  253. if (s->ps.npts == s->ppasize) {
  254. ppasize = s->ppasize + 100;
  255. ppa = malloc ((sizeof (pen_point) + sizeof (Point)) * ppasize);
  256. if (!ppa)
  257. return;
  258. pt = (Point *) (ppa + ppasize);
  259. memmove(ppa, s->ps.pts, s->ppasize * sizeof (pen_point));
  260. memmove(pt, s->pt, s->ppasize * sizeof (Point));
  261. free (s->ps.pts);
  262. s->ps.pts = ppa;
  263. s->pt = pt;
  264. s->ppasize = ppasize;
  265. }
  266. ppa = &s->ps.pts[s->ps.npts];
  267. ppa->Point = p;
  268. pt = &s->pt[s->ps.npts];
  269. *pt = p;
  270. s->ps.npts++;
  271. displaylast(w);
  272. }
  273. Control*
  274. createscribble(Controlset *cs, char *name)
  275. {
  276. Scrib *b;
  277. b = (Scrib*)_createctl(cs, "scribble", sizeof(Scrib), name);
  278. b->image = _getctlimage("white");
  279. b->color = _getctlimage("black");
  280. b->bordercolor = _getctlimage("black");
  281. b->align = Aupperleft;
  282. b->Control.format = ctlstrdup("%q: value 0x%x");
  283. b->font = _getctlfont("font");
  284. b->scrib = scribblealloc();
  285. b->lastbut = 0;
  286. b->bordercolor = _getctlimage("black");
  287. b->border = 0;
  288. b->Control.ctl = scribctl;
  289. b->Control.mouse = scribmouse;
  290. b->Control.exit = scribfree;
  291. return (Control*)b;
  292. }