devkbmap.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * keyboard map
  3. */
  4. #include "u.h"
  5. #include "../port/lib.h"
  6. #include "mem.h"
  7. #include "dat.h"
  8. #include "fns.h"
  9. #include "../port/error.h"
  10. enum{
  11. Qdir,
  12. Qdata,
  13. };
  14. Dirtab kbmaptab[]={
  15. {".", {Qdir, 0, QTDIR}, 0, 0555},
  16. {"kbmap", {Qdata, 0}, 0, 0600},
  17. };
  18. #define NKBFILE sizeof(kbmaptab)/sizeof(kbmaptab[0])
  19. #define KBLINELEN (3*NUMSIZE+1) /* t code val\n */
  20. static Chan *
  21. kbmapattach(char *spec)
  22. {
  23. return devattach(L'κ', spec);
  24. }
  25. static Walkqid*
  26. kbmapwalk(Chan *c, Chan *nc, char **name, int nname)
  27. {
  28. return devwalk(c, nc, name, nname, kbmaptab, NKBFILE, devgen);
  29. }
  30. static int
  31. kbmapstat(Chan *c, uint8_t *dp, int n)
  32. {
  33. return devstat(c, dp, n, kbmaptab, NKBFILE, devgen);
  34. }
  35. static Chan*
  36. kbmapopen(Chan *c, int omode)
  37. {
  38. if(!iseve())
  39. error(Eperm);
  40. return devopen(c, omode, kbmaptab, NKBFILE, devgen);
  41. }
  42. static void
  43. kbmapclose(Chan *c)
  44. {
  45. if(c->aux){
  46. free(c->aux);
  47. c->aux = nil;
  48. }
  49. }
  50. static int32_t
  51. kbmapread(Chan *c, void *a, int32_t n, int64_t offset)
  52. {
  53. char *bp;
  54. char tmp[KBLINELEN+1];
  55. int t, sc;
  56. Rune r;
  57. if(c->qid.type == QTDIR)
  58. return devdirread(c, a, n, kbmaptab, NKBFILE, devgen);
  59. switch((int)(c->qid.path)){
  60. case Qdata:
  61. if(kbdgetmap(offset/KBLINELEN, &t, &sc, &r)) {
  62. bp = tmp;
  63. bp += readnum(0, bp, NUMSIZE, t, NUMSIZE);
  64. bp += readnum(0, bp, NUMSIZE, sc, NUMSIZE);
  65. bp += readnum(0, bp, NUMSIZE, r, NUMSIZE);
  66. *bp++ = '\n';
  67. *bp = 0;
  68. n = readstr(offset%KBLINELEN, a, n, tmp);
  69. } else
  70. n = 0;
  71. break;
  72. default:
  73. n=0;
  74. break;
  75. }
  76. return n;
  77. }
  78. static Rune
  79. kbgetrune(char **p){
  80. Rune r = 0;
  81. char *lp=*p;
  82. while(*lp == ' ' || *lp == '\t')
  83. lp++;
  84. if(*lp == '\'' && lp[1])
  85. chartorune(&r, lp+1);
  86. else if(*lp == '^' && lp[1]){
  87. chartorune(&r, lp+1);
  88. if(0x40 <= r && r < 0x60)
  89. r -= 0x40;
  90. else
  91. error(Ebadarg);
  92. }else if(*lp == 'M' && ('1' <= lp[1] && lp[1] <= '5'))
  93. r = 0xF900+lp[1]-'0';
  94. else if(*lp>='0' && *lp<='9') /* includes 0x... */
  95. r = strtoul(lp, &lp, 0);
  96. else
  97. error(Ebadarg);
  98. return r;
  99. }
  100. static int32_t
  101. kbmapwrite(Chan *c, void *a, int32_t n, int64_t v)
  102. {
  103. char line[100], *lp, *b;
  104. int key, m, l;
  105. Rune r;
  106. if(c->qid.type == QTDIR)
  107. error(Eperm);
  108. switch((int)(c->qid.path)){
  109. case Qdata:
  110. initDeadKeys();
  111. b = a;
  112. l = n;
  113. lp = line;
  114. if(c->aux){
  115. strcpy(line, c->aux);
  116. lp = line+strlen(line);
  117. free(c->aux);
  118. c->aux = nil;
  119. }
  120. while(--l >= 0) {
  121. *lp++ = *b++;
  122. if(lp[-1] == '\n' || lp == &line[sizeof(line)-1]) {
  123. *lp = 0;
  124. if(*line == 0)
  125. error(Ebadarg);
  126. if(*line == '\n' || *line == '#'){
  127. lp = line;
  128. continue;
  129. }
  130. lp = line;
  131. while(*lp == ' ' || *lp == '\t')
  132. lp++;
  133. m = strtoul(line, &lp, 0);
  134. if(m==5ul){
  135. Rune k, f;
  136. while(*lp == ' ' || *lp == '\t')
  137. lp++;
  138. k=kbgetrune(&lp);
  139. //Move next
  140. while (!(*lp == ' ' || *lp == '\t' || *lp == '\0'))
  141. lp++;
  142. while(*lp == ' ' || *lp == '\t')
  143. lp++;
  144. r=kbgetrune(&lp);
  145. //Move next
  146. while (!(*lp == ' ' || *lp == '\t' || *lp == '\0'))
  147. lp++;
  148. while(*lp == ' ' || *lp == '\t')
  149. lp++;
  150. f=kbgetrune(&lp);
  151. kdbputdeadkey(k,r,f);
  152. }else{
  153. key = strtoul(lp, &lp, 0);
  154. r = kbgetrune(&lp);
  155. kbdputmap(m, key, r);
  156. }
  157. lp = line;
  158. }
  159. }
  160. if(lp != line){
  161. l = lp-line;
  162. c->aux = lp = smalloc(l+1);
  163. memmove(lp, line, l);
  164. lp[l] = 0;
  165. }
  166. break;
  167. default:
  168. error(Ebadusefd);
  169. }
  170. return n;
  171. }
  172. Dev kbmapdevtab = {
  173. L'κ',
  174. "kbmap",
  175. devreset,
  176. devinit,
  177. devshutdown,
  178. kbmapattach,
  179. kbmapwalk,
  180. kbmapstat,
  181. kbmapopen,
  182. devcreate,
  183. kbmapclose,
  184. kbmapread,
  185. devbread,
  186. kbmapwrite,
  187. devbwrite,
  188. devremove,
  189. devwstat,
  190. };