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