devtk.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "dat.h"
  2. #include "fns.h"
  3. #include "error.h"
  4. #include <interp.h>
  5. #include "draw.h"
  6. #include <memdraw.h>
  7. #include <memlayer.h>
  8. #include <cursor.h>
  9. enum{
  10. Qdir,
  11. Qtkevents
  12. };
  13. static
  14. Dirtab tkdirtab[]=
  15. {
  16. ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
  17. "tkevents", {Qtkevents, 0}, 0, 0600,
  18. };
  19. static struct {
  20. QLock l;
  21. Queue* eq;
  22. Ref inuse;
  23. } tkevents;
  24. static void
  25. tkwiretapper(void *top, char *cmd, char *result, void *image, Rectangle *rp)
  26. {
  27. Block *b;
  28. int n;
  29. char *s, *e;
  30. //fprint(2, "wiretap %p %q %q\n", top, cmd, result);
  31. if(tkevents.eq == nil)
  32. return;
  33. n = 12;
  34. if(cmd != nil)
  35. n += strlen(cmd)+2+1;
  36. if(result != nil)
  37. n += strlen(result)+2+1;
  38. if(image != nil)
  39. n += 12;
  40. if(rp != nil)
  41. n += 4*20;
  42. n++;
  43. b = allocb(n);
  44. if(b != nil){
  45. s = (char*)b->wp;
  46. e = s+n;
  47. s += snprint(s, e-s, "%p", top);
  48. if(cmd != nil){
  49. *s++ = ' ';
  50. *s++ = '[';
  51. n = strlen(cmd);
  52. memmove(s, cmd, n);
  53. s += n;
  54. *s++ = ']';
  55. }
  56. /* ignore result for now */
  57. if(image != nil)
  58. s += snprint(s, e-s, " %p", image);
  59. if(rp != nil)
  60. s += snprint(s, e-s, " %d %d %d %d", rp->min.x, rp->min.y, rp->max.x, rp->max.y);
  61. b->wp = (uchar*)s;
  62. release();
  63. qlock(&tkevents.l);
  64. if(waserror()){
  65. freeb(b);
  66. qunlock(&tkevents.l);
  67. acquire();
  68. return;
  69. }
  70. if(tkevents.eq != nil)
  71. qbwrite(tkevents.eq, b);
  72. else
  73. freeb(b);
  74. poperror();
  75. qunlock(&tkevents.l);
  76. acquire();
  77. }
  78. }
  79. void (*tkwiretap)(void*, char*, char*, void*, Rectangle*) = tkwiretapper;
  80. static Chan*
  81. tkattach(char* spec)
  82. {
  83. return devattach(L'τ', spec);
  84. }
  85. static Walkqid*
  86. tkwalk(Chan *c, Chan *nc, char **name, int nname)
  87. {
  88. return devwalk(c, nc, name, nname, tkdirtab, nelem(tkdirtab), devgen);
  89. }
  90. static int
  91. tkstat(Chan *c, uchar *db, int n)
  92. {
  93. return devstat(c, db, n, tkdirtab, nelem(tkdirtab), devgen);
  94. }
  95. static Chan*
  96. tkopen(Chan* c, int omode)
  97. {
  98. if(c->qid.type & QTDIR)
  99. return devopen(c, omode, tkdirtab, nelem(tkdirtab), devgen);
  100. switch(c->qid.path){
  101. case Qtkevents:
  102. c = devopen(c, omode, tkdirtab, nelem(tkdirtab), devgen);
  103. qlock(&tkevents.l);
  104. if(incref(&tkevents.inuse) != 1){
  105. qunlock(&tkevents.l);
  106. error(Einuse);
  107. }
  108. if(tkevents.eq == nil)
  109. tkevents.eq = qopen(256*1024, 0, nil, nil);
  110. else
  111. qreopen(tkevents.eq);
  112. qunlock(&tkevents.l);
  113. break;
  114. }
  115. return c;
  116. }
  117. static void
  118. tkclose(Chan* c)
  119. {
  120. if(c->qid.type & QTDIR || (c->flag & COPEN) == 0)
  121. return;
  122. qlock(&tkevents.l);
  123. if(decref(&tkevents.inuse) == 0)
  124. qclose(tkevents.eq);
  125. qunlock(&tkevents.l);
  126. }
  127. static long
  128. tkread(Chan* c, void* a, long n, vlong offset)
  129. {
  130. USED(offset);
  131. if(c->qid.type & QTDIR)
  132. return devdirread(c, a, n, tkdirtab, nelem(tkdirtab), devgen);
  133. switch((ulong)c->qid.path){
  134. case Qtkevents:
  135. return qread(tkevents.eq, a, n);
  136. default:
  137. n=0;
  138. break;
  139. }
  140. return n;
  141. }
  142. static long
  143. tkwrite(Chan *c, void* a, long n, vlong offset)
  144. {
  145. USED(c); USED(a); USED(n); USED(offset);
  146. error(Ebadusefd);
  147. return 0;
  148. }
  149. Dev tkdevtab = {
  150. L'τ',
  151. "tk",
  152. // devreset,
  153. devinit,
  154. tkattach,
  155. // devdetach,
  156. tkwalk,
  157. tkstat,
  158. tkopen,
  159. devcreate,
  160. tkclose,
  161. tkread,
  162. devbread,
  163. tkwrite,
  164. devbwrite,
  165. devremove,
  166. devwstat,
  167. };