wctl.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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 <thread.h>
  12. #include <keyboard.h>
  13. #include <fcall.h>
  14. #include <plumb.h>
  15. #include "dat.h"
  16. #include "fns.h"
  17. #include <ctype.h>
  18. char Ebadwr[] = "bad rectangle in wctl request";
  19. char Ewalloc[] = "window allocation failed in wctl request";
  20. /* >= Top are disallowed if mouse button is pressed */
  21. enum
  22. {
  23. New,
  24. Resize,
  25. Move,
  26. Scroll,
  27. Noscroll,
  28. Set,
  29. Top,
  30. Bottom,
  31. Current,
  32. Hide,
  33. Unhide,
  34. Delete,
  35. };
  36. static char *cmds[] = {
  37. [New] = "new",
  38. [Resize] = "resize",
  39. [Move] = "move",
  40. [Scroll] = "scroll",
  41. [Noscroll] = "noscroll",
  42. [Set] = "set",
  43. [Top] = "top",
  44. [Bottom] = "bottom",
  45. [Current] = "current",
  46. [Hide] = "hide",
  47. [Unhide] = "unhide",
  48. [Delete] = "delete",
  49. nil
  50. };
  51. enum
  52. {
  53. Cd,
  54. Deltax,
  55. Deltay,
  56. Hidden,
  57. Id,
  58. Maxx,
  59. Maxy,
  60. Minx,
  61. Miny,
  62. PID,
  63. R,
  64. Scrolling,
  65. Noscrolling,
  66. };
  67. static char *params[] = {
  68. [Cd] = "-cd",
  69. [Deltax] = "-dx",
  70. [Deltay] = "-dy",
  71. [Hidden] = "-hide",
  72. [Id] = "-id",
  73. [Maxx] = "-maxx",
  74. [Maxy] = "-maxy",
  75. [Minx] = "-minx",
  76. [Miny] = "-miny",
  77. [PID] = "-pid",
  78. [R] = "-r",
  79. [Scrolling] = "-scroll",
  80. [Noscrolling] = "-noscroll",
  81. nil
  82. };
  83. static
  84. int
  85. word(char **sp, char *tab[])
  86. {
  87. print_func_entry();
  88. char *s, *t;
  89. int i;
  90. s = *sp;
  91. while(isspace(*s))
  92. s++;
  93. t = s;
  94. while(*s!='\0' && !isspace(*s))
  95. s++;
  96. for(i=0; tab[i]!=nil; i++)
  97. if(strncmp(tab[i], t, strlen(tab[i])) == 0){
  98. *sp = s;
  99. print_func_exit();
  100. return i;
  101. }
  102. print_func_exit();
  103. return -1;
  104. }
  105. int
  106. set(int sign, int neg, int abs, int pos)
  107. {
  108. print_func_entry();
  109. if(sign < 0) {
  110. print_func_exit();
  111. return neg;
  112. }
  113. if(sign > 0) {
  114. print_func_exit();
  115. return pos;
  116. }
  117. print_func_exit();
  118. return abs;
  119. }
  120. void
  121. shift(int *minp, int *maxp, int min, int max)
  122. {
  123. print_func_entry();
  124. if(*minp < min){
  125. *maxp += min-*minp;
  126. *minp = min;
  127. }
  128. if(*maxp > max){
  129. *minp += max-*maxp;
  130. *maxp = max;
  131. }
  132. print_func_exit();
  133. }
  134. /* permit square brackets, in the manner of %R */
  135. int
  136. riostrtol(char *s, char **t)
  137. {
  138. print_func_entry();
  139. int n;
  140. while(*s!='\0' && (*s==' ' || *s=='\t' || *s=='['))
  141. s++;
  142. if(*s == '[')
  143. s++;
  144. n = strtol(s, t, 10);
  145. if(*t != s)
  146. while((*t)[0] == ']')
  147. (*t)++;
  148. print_func_exit();
  149. return n;
  150. }
  151. int
  152. parsewctl(char **argp, int *pidp, int *idp,
  153. char **cdp, char *s,
  154. char *err)
  155. {
  156. print_func_entry();
  157. int cmd, param, xy = 0;
  158. *pidp = 0;
  159. *cdp = nil;
  160. cmd = word(&s, cmds);
  161. if(cmd < 0){
  162. strcpy(err, "unrecognized wctl command");
  163. print_func_exit();
  164. return -1;
  165. }
  166. strcpy(err, "missing or bad wctl parameter");
  167. while((param = word(&s, params)) >= 0){
  168. switch(param){ /* special cases */
  169. case Id:
  170. if(idp != nil)
  171. *idp = xy;
  172. break;
  173. case PID:
  174. if(pidp != nil)
  175. *pidp = xy;
  176. break;
  177. }
  178. }
  179. while(isspace(*s))
  180. s++;
  181. if(cmd!=New && *s!='\0'){
  182. strcpy(err, "extraneous text in wctl message");
  183. print_func_exit();
  184. return -1;
  185. }
  186. if(argp)
  187. *argp = s;
  188. print_func_exit();
  189. return cmd;
  190. }
  191. int
  192. wctlnew(char *arg, int pid, char *dir, char *err)
  193. {
  194. print_func_entry();
  195. char **argv;
  196. Console *i = nil;
  197. argv = emalloc(4*sizeof(char*));
  198. argv[0] = "rc";
  199. argv[1] = "-c";
  200. while(isspace(*arg))
  201. arg++;
  202. if(*arg == '\0'){
  203. argv[1] = "-i";
  204. argv[2] = nil;
  205. }else{
  206. argv[2] = arg;
  207. argv[3] = nil;
  208. }
  209. if(i == nil){
  210. strcpy(err, Ewalloc);
  211. print_func_exit();
  212. return -1;
  213. }
  214. //new(i, hideit, scrollit, pid, dir, "/bin/rc", argv);
  215. free(argv); /* when new() returns, argv and args have been copied */
  216. print_func_exit();
  217. return 1;
  218. }
  219. int
  220. writewctl(Xfid *x, char *err)
  221. {
  222. print_func_entry();
  223. int cnt, cmd, j, id, pid;
  224. char *arg, *dir;
  225. Window *w;
  226. w = x->f->w;
  227. cnt = x->count;
  228. x->data[cnt] = '\0';
  229. id = 0;
  230. cmd = parsewctl(&arg, &pid, &id, &dir, x->data, err);
  231. if(cmd < 0) {
  232. print_func_exit();
  233. return -1;
  234. }
  235. if(id != 0){
  236. for(j=0; j<nwindow; j++)
  237. if(window[j]->id == id)
  238. break;
  239. if(j == nwindow){
  240. strcpy(err, "no such window id");
  241. print_func_exit();
  242. return -1;
  243. }
  244. w = window[j];
  245. if(w->deleted){
  246. strcpy(err, "window deleted");
  247. print_func_exit();
  248. return -1;
  249. }
  250. }
  251. switch(cmd){
  252. case New:
  253. print_func_exit();
  254. return wctlnew(arg, pid, dir, err);
  255. case Set:
  256. if(pid > 0)
  257. wsetpid(w, pid, 0);
  258. print_func_exit();
  259. return 1;
  260. case Current:
  261. wcurrent(w);
  262. print_func_exit();
  263. return 1;
  264. case Delete:
  265. //wsendctlmesg(w, Deleted, ZR, nil);
  266. print_func_exit();
  267. return 1;
  268. }
  269. strcpy(err, "invalid wctl message");
  270. print_func_exit();
  271. return -1;
  272. }
  273. void
  274. wctlthread(void *v)
  275. {
  276. print_func_entry();
  277. char *buf, *arg, *dir;
  278. int cmd, id, pid;
  279. char err[ERRMAX];
  280. Channel *c;
  281. c = v;
  282. threadsetname("WCTLTHREAD");
  283. for(;;){
  284. buf = recvp(c);
  285. cmd = parsewctl(&arg, &pid, &id, &dir, buf, err);
  286. switch(cmd){
  287. case New:
  288. wctlnew(arg, pid, dir, err);
  289. }
  290. free(buf);
  291. }
  292. print_func_exit();
  293. }
  294. void
  295. wctlproc(void *v)
  296. {
  297. print_func_entry();
  298. char *buf;
  299. int n, eofs;
  300. Channel *c;
  301. threadsetname("WCTLPROC");
  302. c = v;
  303. eofs = 0;
  304. for(;;){
  305. buf = emalloc(messagesize);
  306. n = read(wctlfd, buf, messagesize-1); /* room for \0 */
  307. if(n < 0)
  308. break;
  309. if(n == 0){
  310. if(++eofs > 20)
  311. break;
  312. continue;
  313. }
  314. eofs = 0;
  315. buf[n] = '\0';
  316. sendp(c, buf);
  317. }
  318. print_func_exit();
  319. }