My dmenu build
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 lines
4.9 KiB

  1. /* See LICENSE file for copyright and license details. */
  2. #include <ctype.h>
  3. #include <locale.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <X11/keysym.h>
  8. #include <X11/Xlib.h>
  9. #include <X11/Xutil.h>
  10. #include "dmenu.h"
  11. /* forward declarations */
  12. static void cleanup(void);
  13. /* variables */
  14. static size_t cursor = 0;
  15. void
  16. cleanup(void) {
  17. cleanupdraw(&dc);
  18. XDestroyWindow(dpy, win);
  19. XUngrabKeyboard(dpy, CurrentTime);
  20. XCloseDisplay(dpy);
  21. }
  22. void
  23. drawbar(void)
  24. {
  25. dc.x = 0;
  26. dc.y = 0;
  27. dc.w = mw;
  28. dc.h = mh;
  29. drawtext(&dc, NULL, normcol);
  30. /* print prompt? */
  31. if(prompt) {
  32. dc.w = promptw;
  33. drawtext(&dc, prompt, selcol);
  34. dc.x += dc.w;
  35. }
  36. dc.w = mw - dc.x;
  37. drawtext(&dc, text, normcol);
  38. drawcursor(&dc, text, cursor, normcol);
  39. commitdraw(&dc, win);
  40. }
  41. void
  42. kpress(XKeyEvent *e) {
  43. char buf[sizeof text];
  44. int num;
  45. unsigned int i, len;
  46. KeySym ksym;
  47. len = strlen(text);
  48. num = XLookupString(e, buf, sizeof buf, &ksym, NULL);
  49. if(ksym == XK_KP_Enter)
  50. ksym = XK_Return;
  51. else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
  52. ksym = (ksym - XK_KP_0) + XK_0;
  53. else if(IsFunctionKey(ksym) || IsKeypadKey(ksym)
  54. || IsMiscFunctionKey(ksym) || IsPFKey(ksym)
  55. || IsPrivateKeypadKey(ksym))
  56. return;
  57. /* first check if a control mask is omitted */
  58. if(e->state & ControlMask) {
  59. switch(tolower(ksym)) {
  60. default:
  61. return;
  62. case XK_a:
  63. ksym = XK_Home;
  64. break;
  65. case XK_b:
  66. ksym = XK_Left;
  67. break;
  68. case XK_c:
  69. ksym = XK_Escape;
  70. break;
  71. case XK_e:
  72. ksym = XK_End;
  73. break;
  74. case XK_f:
  75. ksym = XK_Right;
  76. break;
  77. case XK_h:
  78. ksym = XK_BackSpace;
  79. break;
  80. case XK_j:
  81. case XK_m:
  82. ksym = XK_Return;
  83. break;
  84. case XK_k:
  85. text[cursor] = '\0';
  86. break;
  87. case XK_u:
  88. memmove(text, text + cursor, sizeof text - cursor + 1);
  89. cursor = 0;
  90. break;
  91. case XK_w:
  92. if(cursor > 0) {
  93. i = cursor;
  94. while(i-- > 0 && text[i] == ' ');
  95. while(i-- > 0 && text[i] != ' ');
  96. memmove(text + i + 1, text + cursor, sizeof text - cursor + 1);
  97. cursor = i + 1;
  98. }
  99. break;
  100. case XK_y:
  101. {
  102. FILE *fp;
  103. char *s;
  104. if(!(fp = popen("sselp", "r")))
  105. eprint("cannot popen sselp\n");
  106. s = fgets(buf, sizeof buf, fp);
  107. pclose(fp);
  108. if(s == NULL)
  109. return;
  110. }
  111. num = strlen(buf);
  112. if(num && buf[num-1] == '\n')
  113. buf[--num] = '\0';
  114. break;
  115. }
  116. }
  117. switch(ksym) {
  118. default:
  119. num = MIN(num, sizeof text - cursor);
  120. if(num && !iscntrl((int) buf[0])) {
  121. memmove(text + cursor + num, text + cursor, sizeof text - cursor - num);
  122. memcpy(text + cursor, buf, num);
  123. cursor += num;
  124. }
  125. break;
  126. case XK_BackSpace:
  127. if(cursor == 0)
  128. return;
  129. for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++);
  130. memmove(text + cursor - i, text + cursor, sizeof text - cursor + i);
  131. cursor -= i;
  132. break;
  133. case XK_Delete:
  134. if(cursor == len)
  135. return;
  136. for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++);
  137. memmove(text + cursor, text + cursor + i, sizeof text - cursor);
  138. break;
  139. case XK_End:
  140. cursor = len;
  141. break;
  142. case XK_Escape:
  143. exit(EXIT_FAILURE);
  144. case XK_Home:
  145. cursor = 0;
  146. break;
  147. case XK_Left:
  148. if(cursor == 0)
  149. return;
  150. while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor]));
  151. break;
  152. case XK_Return:
  153. fprintf(stdout, "%s", text);
  154. fflush(stdout);
  155. exit(EXIT_SUCCESS);
  156. case XK_Right:
  157. if(cursor == len)
  158. return;
  159. while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor]));
  160. break;
  161. }
  162. drawbar();
  163. }
  164. int
  165. main(int argc, char *argv[]) {
  166. unsigned int i;
  167. /* command line args */
  168. progname = "dinput";
  169. for(i = 1; i < argc; i++)
  170. if(!strcmp(argv[i], "-i"))
  171. ; /* ignore flag */
  172. else if(!strcmp(argv[i], "-b"))
  173. topbar = False;
  174. else if(!strcmp(argv[i], "-l"))
  175. i++; /* ignore flag */
  176. else if(!strcmp(argv[i], "-fn")) {
  177. if(++i < argc) font = argv[i];
  178. }
  179. else if(!strcmp(argv[i], "-nb")) {
  180. if(++i < argc) normbgcolor = argv[i];
  181. }
  182. else if(!strcmp(argv[i], "-nf")) {
  183. if(++i < argc) normfgcolor = argv[i];
  184. }
  185. else if(!strcmp(argv[i], "-p")) {
  186. if(++i < argc) prompt = argv[i];
  187. }
  188. else if(!strcmp(argv[i], "-sb")) {
  189. if(++i < argc) selbgcolor = argv[i];
  190. }
  191. else if(!strcmp(argv[i], "-sf")) {
  192. if(++i < argc) selfgcolor = argv[i];
  193. }
  194. else if(!strcmp(argv[i], "-v")) {
  195. printf("dinput-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n");
  196. exit(EXIT_SUCCESS);
  197. }
  198. else if(!*text) {
  199. strncpy(text, argv[i], sizeof text);
  200. cursor = strlen(text);
  201. }
  202. else {
  203. fputs("usage: dinput [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n"
  204. " [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr);
  205. exit(EXIT_FAILURE);
  206. }
  207. if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
  208. fprintf(stderr, "dinput: warning: no locale support\n");
  209. if(!(dpy = XOpenDisplay(NULL)))
  210. eprint("cannot open display\n");
  211. if(atexit(&cleanup) != 0)
  212. eprint("cannot register cleanup\n");
  213. screen = DefaultScreen(dpy);
  214. root = RootWindow(dpy, screen);
  215. grabkeyboard();
  216. setup(0);
  217. run();
  218. return 0;
  219. }