0 #include <X11/Xlib.h>
1 #include <X11/Xutil.h>
2 #include <X11/Xos.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <locale.h>
6 #include <assert.h>
7
8 int text_box(char* input, size_t len) {
9 Display *dpy;
10 Window win;
11 XIM xim;
12 XIC ic;
13 int scr, ret = 0;
14 size_t pos = 0;
15
16 dpy = XOpenDisplay(NULL);
17 scr = DefaultScreen(dpy);
18 win = XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy),
19 0, 0, 240, 30, 5,
20 BlackPixel(dpy, scr),
21 WhitePixel(dpy, scr));
22 XMapWindow(dpy, win);
23
24 xim = XOpenIM(dpy, NULL, NULL, NULL);
25 ic = XCreateIC(xim, XNInputStyle,
26 XIMPreeditNothing | XIMStatusNothing,
27 XNClientWindow, win, NULL);
28 XSetICFocus(ic);
29
30
31 XSelectInput(dpy, win, ExposureMask | KeyPressMask);
32 XMapWindow(dpy, win);
33
34 for (;;)
35 {
36 char hidden[256];
37 char buf[16];
38 size_t c;
39 int keysym;
40 KeySym ksym;
41 Status status;
42
43 XEvent ev;
44 XNextEvent(dpy, &ev);
45
46 if (XFilterEvent(&ev, None))
47 continue;
48 if (ev.type == Expose) goto draw;
49 if (ev.type != KeyPress) continue;
50 keysym = XLookupKeysym(&ev.xkey, 0);
51 if (keysym == XK_Escape) {
52 ret = -1;
53 break;
54 }
55 if (keysym == XK_Return)
56 break;
57 if (keysym == XK_BackSpace) {
58 if (pos < 1) continue;
59 pos--;
60 input[pos] = '\0';
61 goto draw;
62 }
63 c = Xutf8LookupString(ic, &ev.xkey, buf, sizeof(buf) - 1,
64 &ksym, &status);
65
66 if (status == XBufferOverflow) continue;
67 if (c < 1 || pos + c > len) continue;
68
69 memcpy(&input[pos], buf, c);
70 pos += c;
71 input[pos] = '\0';
72 memset(hidden, '*',
73 (pos > sizeof(hidden) - 1)?sizeof(hidden) - 1:pos);
74 draw:
75 XClearWindow(dpy, win);
76 XDrawString(dpy, win, DefaultGC(dpy, scr),
77 10, 20, hidden, pos);
78 }
79 XDestroyWindow(dpy, win);
80 XCloseDisplay(dpy);
81 return ret;
82 }
83