2 * Copyright Neil Brown ©2023 <neil@brown.name>
3 * May be distributed under terms of GPLv2 - see file:COPYING
5 * askpass - ask for a password.
6 * This doesn't yet have any focus on protecting the password
7 * from being swapped out.
9 * We place a popup in mid-display with a message and
10 * "HEAVY BALLOT X" for each character typed.
16 #define PANE_DATA_TYPE struct apinfo
24 #include "core-pane.h"
26 static struct map *askpass_map;
27 DEF_LOOKUP_CMD(askpass_handle, askpass_map);
29 DEF_CMD(askpass_refresh_view)
32 struct apinfo *ai = ci->home->data;
37 buf_concat(&b, ai->msg);
38 for (i = 0; i < utf8_strlen(buf_final(&ai->b)); i++)
39 buf_append(&b, 0x2718); /* HEAVY BALLOT X */
40 call("render-line:set", ci->focus, b.len, NULL, buf_final(&b));
41 for (i = 0; i < 10; i++) {
43 attr_set_int(&ci->focus->attrs, "render-wrap", shift);
44 call("render-line:measure", ci->focus, b.len);
45 cw = pane_attr_get_int(ci->focus, "curs_width", 1);
46 if (ci->home->parent->cx < ci->home->parent->w - cw)
56 const char *k = ksuffix(ci, "K-");
57 struct apinfo *ai = ci->home->data;
59 buf_concat(&ai->b, k);
60 pane_damaged(ci->home, DAMAGED_VIEW);
66 struct apinfo *ai = ci->home->data;
69 ai->b.len = utf8_round_len(ai->b.b, ai->b.len-1);
70 pane_damaged(ci->home, DAMAGED_VIEW);
74 DEF_CMD(askpass_ignore)
81 struct apinfo *ai = ci->home->data;
83 comm_call(ai->c, "cb", ci->focus, ai->b.len, NULL,
85 memset(ai->b.b, 0, ai->b.size);
86 call("popup:close", ci->focus);
90 DEF_CMD(askpass_abort)
92 struct apinfo *ai = ci->home->data;
94 memset(ai->b.b, 0, ai->b.size);
95 comm_call(ai->c, "cb", ci->focus, -1);
96 call("popup:close", ci->focus);
100 DEF_CMD(askpass_attach)
104 if (!ci->str || !ci->comm2)
106 p = call_ret(pane, "PopupTile", ci->focus, 0, NULL, "D2");
109 p2 = call_ret(pane, "attach-view", p);
114 p2 = call_ret(pane, "attach-renderline", p);
119 p2 = pane_register(p, 0, &askpass_handle.c);
124 attr_set_str(&p->attrs, "pane-title", "Ask Password");
126 p->data->msg = strdup(ci->str);
127 p->data->c = command_get(ci->comm2);
128 buf_init(&p->data->b);
129 pane_damaged(p, DAMAGED_VIEW);
133 if (ci->focus->focus)
134 pane_close(ci->focus->focus);
138 DEF_CMD_CLOSED(askpass_close)
140 struct apinfo *ai = ci->home->data;
143 ai->msg = safe_cast NULL;
144 free(buf_final(&ai->b));
145 ai->b.b = safe_cast NULL;
151 void edlib_init(struct pane *ed safe)
153 call_comm("global-set-command", ed, &askpass_attach,
156 askpass_map = key_alloc();
157 key_add(askpass_map, "Close", &askpass_close);
158 key_add_prefix(askpass_map, "K-", &askpass_key);
159 key_add_prefix(askpass_map, "K:", &askpass_ignore);
160 key_add_prefix(askpass_map, "M:", &askpass_ignore);
161 key_add(askpass_map, "K:Enter", &askpass_done);
162 key_add(askpass_map, "K:Backspace", &askpass_bs);
163 key_add(askpass_map, "K:ESC", &askpass_abort);
164 key_add(askpass_map, "K:C-C", &askpass_abort);
165 key_add(askpass_map, "K:C-G", &askpass_abort);
166 key_add_prefix(askpass_map, "Refresh:view", &askpass_refresh_view);