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.
 
 
 
 
 
 

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