Blame


1 f5e234d6 2018-05-18 omar.polo #include <stdio.h>
2 f5e234d6 2018-05-18 omar.polo #include <stdlib.h>
3 1d13acf5 2018-10-04 omar.polo #include <string.h> /* strdup, strlen */
4 1d13acf5 2018-10-04 omar.polo #include <ctype.h> /* isalnum */
5 1d13acf5 2018-10-04 omar.polo #include <locale.h> /* setlocale */
6 f5e234d6 2018-05-18 omar.polo #include <unistd.h>
7 f5e234d6 2018-05-18 omar.polo #include <sysexits.h>
8 f5e234d6 2018-05-18 omar.polo #include <limits.h>
9 f5e234d6 2018-05-18 omar.polo #include <errno.h>
10 1a4491e5 2018-09-19 omar.polo #include <unistd.h>
11 e5bea6d2 2018-09-19 omar.polo #include <stdint.h>
12 f5e234d6 2018-05-18 omar.polo
13 f5e234d6 2018-05-18 omar.polo #include <X11/Xlib.h>
14 1d13acf5 2018-10-04 omar.polo #include <X11/Xutil.h>
15 f5e234d6 2018-05-18 omar.polo #include <X11/Xresource.h>
16 1d13acf5 2018-10-04 omar.polo #include <X11/Xcms.h>
17 347d23da 2018-05-19 omar.polo #include <X11/keysym.h>
18 f5e234d6 2018-05-18 omar.polo
19 f5e234d6 2018-05-18 omar.polo #ifdef USE_XINERAMA
20 f5e234d6 2018-05-18 omar.polo # include <X11/extensions/Xinerama.h>
21 f5e234d6 2018-05-18 omar.polo #endif
22 f5e234d6 2018-05-18 omar.polo
23 c9a3bfaa 2018-05-21 omar.polo #ifdef USE_XFT
24 c9a3bfaa 2018-05-21 omar.polo # include <X11/Xft/Xft.h>
25 b500fe86 2018-06-07 omar.polo #endif
26 b500fe86 2018-06-07 omar.polo
27 b500fe86 2018-06-07 omar.polo #ifndef VERSION
28 b500fe86 2018-06-07 omar.polo # define VERSION "unknown"
29 c9a3bfaa 2018-05-21 omar.polo #endif
30 c9a3bfaa 2018-05-21 omar.polo
31 347d23da 2018-05-19 omar.polo #define resname "MyMenu"
32 347d23da 2018-05-19 omar.polo #define resclass "mymenu"
33 f5e234d6 2018-05-18 omar.polo
34 b5d751bd 2018-07-07 omar.polo #define SYM_BUF_SIZE 4
35 b5d751bd 2018-07-07 omar.polo
36 9e94fcbe 2018-05-22 omar.polo #ifdef USE_XFT
37 9e94fcbe 2018-05-22 omar.polo # define default_fontname "monospace"
38 9e94fcbe 2018-05-22 omar.polo #else
39 9e94fcbe 2018-05-22 omar.polo # define default_fontname "fixed"
40 9e94fcbe 2018-05-22 omar.polo #endif
41 ae801529 2018-07-13 omar.polo
42 df29e05e 2018-10-17 omar.polo #define ARGS "Aahmve:p:P:l:f:W:H:x:y:b:B:t:T:c:C:s:S:d:G:g:I:i:J:j:"
43 9e94fcbe 2018-05-22 omar.polo
44 9e94fcbe 2018-05-22 omar.polo #define MIN(a, b) ((a) < (b) ? (a) : (b))
45 f5e234d6 2018-05-18 omar.polo #define MAX(a, b) ((a) > (b) ? (a) : (b))
46 9e94fcbe 2018-05-22 omar.polo
47 5e448381 2018-10-09 omar.polo #define EXPANDBITS(x) (((x & 0xf0) * 0x100) | (x & 0x0f) * 0x10)
48 6bb186a7 2018-09-13 omar.polo
49 1d13acf5 2018-10-04 omar.polo /*
50 1d13acf5 2018-10-04 omar.polo * If we don't have or we don't want an "ignore case" completion
51 1d13acf5 2018-10-04 omar.polo * style, fall back to `strstr(3)`
52 1d13acf5 2018-10-04 omar.polo */
53 9e94fcbe 2018-05-22 omar.polo #ifndef USE_STRCASESTR
54 fa5a6135 2018-05-25 omar.polo # define strcasestr strstr
55 9e94fcbe 2018-05-22 omar.polo #endif
56 f5e234d6 2018-05-18 omar.polo
57 1d13acf5 2018-10-04 omar.polo /* The number of char to read */
58 4f769efa 2018-10-06 omar.polo #define STDIN_CHUNKS 128
59 1a4491e5 2018-09-19 omar.polo
60 1d13acf5 2018-10-04 omar.polo /* The number of lines to allocate in advance */
61 4f769efa 2018-10-06 omar.polo #define LINES_CHUNK 64
62 f5e234d6 2018-05-18 omar.polo
63 1d13acf5 2018-10-04 omar.polo /* Abort on NULL */
64 1d13acf5 2018-10-04 omar.polo #define check_allocation(a) { \
65 1d13acf5 2018-10-04 omar.polo if (a == NULL) { \
66 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Could not allocate memory\n"); \
67 1d13acf5 2018-10-04 omar.polo abort(); \
68 1d13acf5 2018-10-04 omar.polo } \
69 f5e234d6 2018-05-18 omar.polo }
70 f5e234d6 2018-05-18 omar.polo
71 4c0d79a0 2018-10-09 omar.polo #define inner_height(r) (r->height - r->borders[0] - r->borders[2])
72 4c0d79a0 2018-10-09 omar.polo #define inner_width(r) (r->width - r->borders[1] - r->borders[3])
73 42c3f269 2018-07-08 omar.polo
74 1d13acf5 2018-10-04 omar.polo /* The states of the event loop */
75 991c5d3c 2018-08-13 omar.polo enum state {LOOPING, OK_LOOP, OK, ERR};
76 f5e234d6 2018-05-18 omar.polo
77 1d13acf5 2018-10-04 omar.polo /*
78 1d13acf5 2018-10-04 omar.polo * For the drawing-related function. The text to be rendere could be
79 1d13acf5 2018-10-04 omar.polo * the prompt, a completion or a highlighted completion
80 1d13acf5 2018-10-04 omar.polo */
81 df29e05e 2018-10-17 omar.polo enum obj_type {PROMPT, COMPL, COMPL_HIGH};
82 c9a3bfaa 2018-05-21 omar.polo
83 1d13acf5 2018-10-04 omar.polo /* These are the possible action to be performed after user input. */
84 2128b469 2018-06-30 omar.polo enum action {
85 1d13acf5 2018-10-04 omar.polo EXIT,
86 1d13acf5 2018-10-04 omar.polo CONFIRM,
87 1d13acf5 2018-10-04 omar.polo CONFIRM_CONTINUE,
88 1d13acf5 2018-10-04 omar.polo NEXT_COMPL,
89 1d13acf5 2018-10-04 omar.polo PREV_COMPL,
90 1d13acf5 2018-10-04 omar.polo DEL_CHAR,
91 1d13acf5 2018-10-04 omar.polo DEL_WORD,
92 1d13acf5 2018-10-04 omar.polo DEL_LINE,
93 1d13acf5 2018-10-04 omar.polo ADD_CHAR,
94 1d13acf5 2018-10-04 omar.polo TOGGLE_FIRST_SELECTED
95 2128b469 2018-06-30 omar.polo };
96 2128b469 2018-06-30 omar.polo
97 1d13acf5 2018-10-04 omar.polo /* A big set of values that needs to be carried around for drawing. A
98 1d13acf5 2018-10-04 omar.polo big struct to rule them all */
99 f5e234d6 2018-05-18 omar.polo struct rendering {
100 1d13acf5 2018-10-04 omar.polo Display *d; /* Connection to xorg */
101 1d13acf5 2018-10-04 omar.polo Window w;
102 43e30577 2018-10-20 omar.polo XIM xim;
103 1d13acf5 2018-10-04 omar.polo int width;
104 1d13acf5 2018-10-04 omar.polo int height;
105 df29e05e 2018-10-17 omar.polo int p_padding[4];
106 df29e05e 2018-10-17 omar.polo int c_padding[4];
107 df29e05e 2018-10-17 omar.polo int ch_padding[4];
108 1d13acf5 2018-10-04 omar.polo int x_zero; /* the "zero" on the x axis (may not be exactly 0 'cause the borders) */
109 1d13acf5 2018-10-04 omar.polo int y_zero; /* like x_zero but for the y axis */
110 11e67c66 2018-08-11 omar.polo
111 1d13acf5 2018-10-04 omar.polo size_t offset; /* scroll offset */
112 42c3f269 2018-07-08 omar.polo
113 26b541d8 2018-10-04 omar.polo short free_text;
114 26b541d8 2018-10-04 omar.polo short first_selected;
115 26b541d8 2018-10-04 omar.polo short multiple_select;
116 991c5d3c 2018-08-13 omar.polo
117 1d13acf5 2018-10-04 omar.polo /* four border width */
118 4c0d79a0 2018-10-09 omar.polo int borders[4];
119 df29e05e 2018-10-17 omar.polo int p_borders[4];
120 df29e05e 2018-10-17 omar.polo int c_borders[4];
121 df29e05e 2018-10-17 omar.polo int ch_borders[4];
122 42c3f269 2018-07-08 omar.polo
123 26b541d8 2018-10-04 omar.polo short horizontal_layout;
124 42c3f269 2018-07-08 omar.polo
125 1d13acf5 2018-10-04 omar.polo /* prompt */
126 1d13acf5 2018-10-04 omar.polo char *ps1;
127 1d13acf5 2018-10-04 omar.polo int ps1len;
128 aed48307 2018-10-06 omar.polo int ps1w; /* ps1 width */
129 aed48307 2018-10-06 omar.polo int ps1h; /* ps1 height */
130 42c3f269 2018-07-08 omar.polo
131 df29e05e 2018-10-17 omar.polo int text_height; /* cache for the vertical layout */
132 df29e05e 2018-10-17 omar.polo
133 1d13acf5 2018-10-04 omar.polo XIC xic;
134 991c5d3c 2018-08-13 omar.polo
135 1d13acf5 2018-10-04 omar.polo /* colors */
136 4c0d79a0 2018-10-09 omar.polo GC fgs[4];
137 4c0d79a0 2018-10-09 omar.polo GC bgs[4];
138 4c0d79a0 2018-10-09 omar.polo GC borders_bg[4];
139 df29e05e 2018-10-17 omar.polo GC p_borders_bg[4];
140 df29e05e 2018-10-17 omar.polo GC c_borders_bg[4];
141 df29e05e 2018-10-17 omar.polo GC ch_borders_bg[4];
142 c9a3bfaa 2018-05-21 omar.polo #ifdef USE_XFT
143 1d13acf5 2018-10-04 omar.polo XftFont *font;
144 1d13acf5 2018-10-04 omar.polo XftDraw *xftdraw;
145 4c0d79a0 2018-10-09 omar.polo XftColor xft_colors[3];
146 c9a3bfaa 2018-05-21 omar.polo #else
147 1d13acf5 2018-10-04 omar.polo XFontSet font;
148 c9a3bfaa 2018-05-21 omar.polo #endif
149 f5e234d6 2018-05-18 omar.polo };
150 f5e234d6 2018-05-18 omar.polo
151 b5d751bd 2018-07-07 omar.polo struct completion {
152 1d13acf5 2018-10-04 omar.polo char *completion;
153 1d13acf5 2018-10-04 omar.polo char *rcompletion;
154 f5e234d6 2018-05-18 omar.polo };
155 f5e234d6 2018-05-18 omar.polo
156 1d13acf5 2018-10-04 omar.polo /* Wrap the linked list of completions */
157 b5d751bd 2018-07-07 omar.polo struct completions {
158 1d13acf5 2018-10-04 omar.polo struct completion *completions;
159 1d13acf5 2018-10-04 omar.polo ssize_t selected;
160 1d13acf5 2018-10-04 omar.polo size_t length;
161 b5d751bd 2018-07-07 omar.polo };
162 b5d751bd 2018-07-07 omar.polo
163 6bb186a7 2018-09-13 omar.polo /* idea stolen from lemonbar. ty lemonboy */
164 6bb186a7 2018-09-13 omar.polo typedef union {
165 1d13acf5 2018-10-04 omar.polo struct {
166 1d13acf5 2018-10-04 omar.polo uint8_t b;
167 1d13acf5 2018-10-04 omar.polo uint8_t g;
168 1d13acf5 2018-10-04 omar.polo uint8_t r;
169 1d13acf5 2018-10-04 omar.polo uint8_t a;
170 4f769efa 2018-10-06 omar.polo } rgba;
171 1d13acf5 2018-10-04 omar.polo uint32_t v;
172 6bb186a7 2018-09-13 omar.polo } rgba_t;
173 6bb186a7 2018-09-13 omar.polo
174 2dba87e5 2018-10-09 omar.polo extern char *optarg;
175 2dba87e5 2018-10-09 omar.polo extern int optind;
176 2dba87e5 2018-10-09 omar.polo
177 1d13acf5 2018-10-04 omar.polo /* Return a newly allocated (and empty) completion list */
178 1d13acf5 2018-10-04 omar.polo struct completions *
179 1d13acf5 2018-10-04 omar.polo compls_new(size_t length)
180 1d13acf5 2018-10-04 omar.polo {
181 1d13acf5 2018-10-04 omar.polo struct completions *cs = malloc(sizeof(struct completions));
182 347d23da 2018-05-19 omar.polo
183 1d13acf5 2018-10-04 omar.polo if (cs == NULL)
184 1d13acf5 2018-10-04 omar.polo return cs;
185 347d23da 2018-05-19 omar.polo
186 1d13acf5 2018-10-04 omar.polo cs->completions = calloc(length, sizeof(struct completion));
187 1d13acf5 2018-10-04 omar.polo if (cs->completions == NULL) {
188 1d13acf5 2018-10-04 omar.polo free(cs);
189 1d13acf5 2018-10-04 omar.polo return NULL;
190 1d13acf5 2018-10-04 omar.polo }
191 36319ab7 2018-07-01 omar.polo
192 1d13acf5 2018-10-04 omar.polo cs->selected = -1;
193 1d13acf5 2018-10-04 omar.polo cs->length = length;
194 1d13acf5 2018-10-04 omar.polo return cs;
195 1d13acf5 2018-10-04 omar.polo }
196 3518f203 2018-07-21 omar.polo
197 1d13acf5 2018-10-04 omar.polo /* Delete the wrapper and the whole list */
198 1d13acf5 2018-10-04 omar.polo void
199 1d13acf5 2018-10-04 omar.polo compls_delete(struct completions *cs)
200 1d13acf5 2018-10-04 omar.polo {
201 1d13acf5 2018-10-04 omar.polo if (cs == NULL)
202 1d13acf5 2018-10-04 omar.polo return;
203 ddd1263a 2018-09-24 omar.polo
204 1d13acf5 2018-10-04 omar.polo free(cs->completions);
205 1d13acf5 2018-10-04 omar.polo free(cs);
206 1d13acf5 2018-10-04 omar.polo }
207 f5e234d6 2018-05-18 omar.polo
208 1d13acf5 2018-10-04 omar.polo /*
209 1d13acf5 2018-10-04 omar.polo * Create a completion list from a text and the list of possible
210 1d13acf5 2018-10-04 omar.polo * completions (null terminated). Expects a non-null `cs'. `lines' and
211 1d13acf5 2018-10-04 omar.polo * `vlines' should have the same length OR `vlines' is NULL.
212 1d13acf5 2018-10-04 omar.polo */
213 1d13acf5 2018-10-04 omar.polo void
214 1d13acf5 2018-10-04 omar.polo filter(struct completions *cs, char *text, char **lines, char **vlines)
215 1d13acf5 2018-10-04 omar.polo {
216 1d13acf5 2018-10-04 omar.polo size_t index = 0;
217 1d13acf5 2018-10-04 omar.polo size_t matching = 0;
218 4f769efa 2018-10-06 omar.polo char *l;
219 f5e234d6 2018-05-18 omar.polo
220 1d13acf5 2018-10-04 omar.polo if (vlines == NULL)
221 1d13acf5 2018-10-04 omar.polo vlines = lines;
222 f5e234d6 2018-05-18 omar.polo
223 26b541d8 2018-10-04 omar.polo while (1) {
224 1d13acf5 2018-10-04 omar.polo if (lines[index] == NULL)
225 1d13acf5 2018-10-04 omar.polo break;
226 2128b469 2018-06-30 omar.polo
227 4f769efa 2018-10-06 omar.polo l = vlines[index] != NULL ? vlines[index] : lines[index];
228 b5d751bd 2018-07-07 omar.polo
229 1d13acf5 2018-10-04 omar.polo if (strcasestr(l, text) != NULL) {
230 1d13acf5 2018-10-04 omar.polo struct completion *c = &cs->completions[matching];
231 1d13acf5 2018-10-04 omar.polo c->completion = l;
232 1d13acf5 2018-10-04 omar.polo c->rcompletion = lines[index];
233 1d13acf5 2018-10-04 omar.polo matching++;
234 1d13acf5 2018-10-04 omar.polo }
235 36319ab7 2018-07-01 omar.polo
236 1d13acf5 2018-10-04 omar.polo index++;
237 1d13acf5 2018-10-04 omar.polo }
238 1d13acf5 2018-10-04 omar.polo cs->length = matching;
239 1d13acf5 2018-10-04 omar.polo cs->selected = -1;
240 1d13acf5 2018-10-04 omar.polo }
241 2128b469 2018-06-30 omar.polo
242 1d13acf5 2018-10-04 omar.polo /* Update the given completion */
243 1d13acf5 2018-10-04 omar.polo void
244 26b541d8 2018-10-04 omar.polo update_completions(struct completions *cs, char *text, char **lines, char **vlines, short first_selected)
245 1d13acf5 2018-10-04 omar.polo {
246 1d13acf5 2018-10-04 omar.polo filter(cs, text, lines, vlines);
247 1d13acf5 2018-10-04 omar.polo if (first_selected && cs->length > 0)
248 1d13acf5 2018-10-04 omar.polo cs->selected = 0;
249 1d13acf5 2018-10-04 omar.polo }
250 b5d751bd 2018-07-07 omar.polo
251 1d13acf5 2018-10-04 omar.polo /*
252 1d13acf5 2018-10-04 omar.polo * Select the next or previous selection and update some state. `text'
253 1d13acf5 2018-10-04 omar.polo * will be updated with the text of the completion and `textlen' with
254 1d13acf5 2018-10-04 omar.polo * the new length. If the memory cannot be allocated `status' will be
255 1d13acf5 2018-10-04 omar.polo * set to `ERR'.
256 1d13acf5 2018-10-04 omar.polo */
257 1d13acf5 2018-10-04 omar.polo void
258 26b541d8 2018-10-04 omar.polo complete(struct completions *cs, short first_selected, short p, char **text, int *textlen, enum state *status)
259 1d13acf5 2018-10-04 omar.polo {
260 1d13acf5 2018-10-04 omar.polo struct completion *n;
261 1d13acf5 2018-10-04 omar.polo int index;
262 b5d751bd 2018-07-07 omar.polo
263 1d13acf5 2018-10-04 omar.polo if (cs == NULL || cs->length == 0)
264 1d13acf5 2018-10-04 omar.polo return;
265 2128b469 2018-06-30 omar.polo
266 1d13acf5 2018-10-04 omar.polo /*
267 1d13acf5 2018-10-04 omar.polo * If the first is always selected and the first entry is
268 1d13acf5 2018-10-04 omar.polo * different from the text, expand the text and return
269 1d13acf5 2018-10-04 omar.polo */
270 1d13acf5 2018-10-04 omar.polo if (first_selected
271 1d13acf5 2018-10-04 omar.polo && cs->selected == 0
272 1d13acf5 2018-10-04 omar.polo && strcmp(cs->completions->completion, *text) != 0
273 1d13acf5 2018-10-04 omar.polo && !p) {
274 1d13acf5 2018-10-04 omar.polo free(*text);
275 1d13acf5 2018-10-04 omar.polo *text = strdup(cs->completions->completion);
276 1d13acf5 2018-10-04 omar.polo if (text == NULL) {
277 1d13acf5 2018-10-04 omar.polo *status = ERR;
278 1d13acf5 2018-10-04 omar.polo return;
279 1d13acf5 2018-10-04 omar.polo }
280 1d13acf5 2018-10-04 omar.polo *textlen = strlen(*text);
281 1d13acf5 2018-10-04 omar.polo return;
282 1d13acf5 2018-10-04 omar.polo }
283 f5e234d6 2018-05-18 omar.polo
284 1d13acf5 2018-10-04 omar.polo index = cs->selected;
285 f5e234d6 2018-05-18 omar.polo
286 1d13acf5 2018-10-04 omar.polo if (index == -1 && p)
287 1d13acf5 2018-10-04 omar.polo index = 0;
288 1d13acf5 2018-10-04 omar.polo index = cs->selected = (cs->length + (p ? index - 1 : index + 1)) % cs->length;
289 347d23da 2018-05-19 omar.polo
290 1d13acf5 2018-10-04 omar.polo n = &cs->completions[cs->selected];
291 347d23da 2018-05-19 omar.polo
292 1d13acf5 2018-10-04 omar.polo free(*text);
293 1d13acf5 2018-10-04 omar.polo *text = strdup(n->completion);
294 1d13acf5 2018-10-04 omar.polo if (text == NULL) {
295 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Memory allocation error!\n");
296 1d13acf5 2018-10-04 omar.polo *status = ERR;
297 1d13acf5 2018-10-04 omar.polo return;
298 1d13acf5 2018-10-04 omar.polo }
299 1d13acf5 2018-10-04 omar.polo *textlen = strlen(*text);
300 f5e234d6 2018-05-18 omar.polo }
301 f5e234d6 2018-05-18 omar.polo
302 1d13acf5 2018-10-04 omar.polo /* Push the character c at the end of the string pointed by p */
303 1d13acf5 2018-10-04 omar.polo int
304 1d13acf5 2018-10-04 omar.polo pushc(char **p, int maxlen, char c)
305 1d13acf5 2018-10-04 omar.polo {
306 4f769efa 2018-10-06 omar.polo int len;
307 1e4bc498 2018-07-15 omar.polo
308 4f769efa 2018-10-06 omar.polo len = strnlen(*p, maxlen);
309 1d13acf5 2018-10-04 omar.polo if (!(len < maxlen -2)) {
310 1d13acf5 2018-10-04 omar.polo char *newptr;
311 1e4bc498 2018-07-15 omar.polo
312 1d13acf5 2018-10-04 omar.polo maxlen += maxlen >> 1;
313 1d13acf5 2018-10-04 omar.polo newptr = realloc(*p, maxlen);
314 1d13acf5 2018-10-04 omar.polo if (newptr == NULL) /* bad */
315 1d13acf5 2018-10-04 omar.polo return -1;
316 1d13acf5 2018-10-04 omar.polo *p = newptr;
317 1d13acf5 2018-10-04 omar.polo }
318 1e4bc498 2018-07-15 omar.polo
319 1d13acf5 2018-10-04 omar.polo (*p)[len] = c;
320 1d13acf5 2018-10-04 omar.polo (*p)[len+1] = '\0';
321 1d13acf5 2018-10-04 omar.polo return maxlen;
322 1e4bc498 2018-07-15 omar.polo }
323 1e4bc498 2018-07-15 omar.polo
324 1d13acf5 2018-10-04 omar.polo /*
325 1d13acf5 2018-10-04 omar.polo * Remove the last rune from the *UTF-8* string! This is different
326 1d13acf5 2018-10-04 omar.polo * from just setting the last byte to 0 (in some cases ofc). Return a
327 1d13acf5 2018-10-04 omar.polo * pointer (e) to the last nonzero char. If e < p then p is empty!
328 1d13acf5 2018-10-04 omar.polo */
329 1d13acf5 2018-10-04 omar.polo char *
330 1d13acf5 2018-10-04 omar.polo popc(char *p)
331 1d13acf5 2018-10-04 omar.polo {
332 1d13acf5 2018-10-04 omar.polo int len = strlen(p);
333 1d13acf5 2018-10-04 omar.polo char *e;
334 8758854a 2018-05-20 omar.polo
335 1d13acf5 2018-10-04 omar.polo if (len == 0)
336 1d13acf5 2018-10-04 omar.polo return p;
337 8758854a 2018-05-20 omar.polo
338 1d13acf5 2018-10-04 omar.polo e = p + len - 1;
339 f5e234d6 2018-05-18 omar.polo
340 1d13acf5 2018-10-04 omar.polo do {
341 1d13acf5 2018-10-04 omar.polo char c = *e;
342 e66a5010 2018-07-21 omar.polo
343 4f769efa 2018-10-06 omar.polo *e = '\0';
344 4f769efa 2018-10-06 omar.polo e -= 1;
345 f5e234d6 2018-05-18 omar.polo
346 1d13acf5 2018-10-04 omar.polo /*
347 1d13acf5 2018-10-04 omar.polo * If c is a starting byte (11......) or is under
348 1d13acf5 2018-10-04 omar.polo * U+007F we're done.
349 1d13acf5 2018-10-04 omar.polo */
350 1d13acf5 2018-10-04 omar.polo if (((c & 0x80) && (c & 0x40)) || !(c & 0x80))
351 1d13acf5 2018-10-04 omar.polo break;
352 1d13acf5 2018-10-04 omar.polo } while (e >= p);
353 f5e234d6 2018-05-18 omar.polo
354 1d13acf5 2018-10-04 omar.polo return e;
355 1a4491e5 2018-09-19 omar.polo }
356 1a4491e5 2018-09-19 omar.polo
357 1d13acf5 2018-10-04 omar.polo /* Remove the last word plus trailing white spaces from the given string */
358 1d13acf5 2018-10-04 omar.polo void
359 1d13acf5 2018-10-04 omar.polo popw(char *w)
360 1d13acf5 2018-10-04 omar.polo {
361 4f769efa 2018-10-06 omar.polo int len;
362 4f769efa 2018-10-06 omar.polo short in_word = 1;
363 1a4491e5 2018-09-19 omar.polo
364 4f769efa 2018-10-06 omar.polo if ((len = strlen(w)) == 0)
365 1d13acf5 2018-10-04 omar.polo return;
366 ddd1263a 2018-09-24 omar.polo
367 26b541d8 2018-10-04 omar.polo while (1) {
368 1d13acf5 2018-10-04 omar.polo char *e = popc(w);
369 1a4491e5 2018-09-19 omar.polo
370 1d13acf5 2018-10-04 omar.polo if (e < w)
371 1d13acf5 2018-10-04 omar.polo return;
372 1a4491e5 2018-09-19 omar.polo
373 1d13acf5 2018-10-04 omar.polo if (in_word && isspace(*e))
374 26b541d8 2018-10-04 omar.polo in_word = 0;
375 1a4491e5 2018-09-19 omar.polo
376 1d13acf5 2018-10-04 omar.polo if (!in_word && !isspace(*e))
377 1d13acf5 2018-10-04 omar.polo return;
378 1d13acf5 2018-10-04 omar.polo }
379 1d13acf5 2018-10-04 omar.polo }
380 1a4491e5 2018-09-19 omar.polo
381 1d13acf5 2018-10-04 omar.polo /*
382 1d13acf5 2018-10-04 omar.polo * If the string is surrounded by quates (`"') remove them and replace
383 1d13acf5 2018-10-04 omar.polo * every `\"' in the string with a single double-quote.
384 1d13acf5 2018-10-04 omar.polo */
385 1d13acf5 2018-10-04 omar.polo char *
386 1d13acf5 2018-10-04 omar.polo normalize_str(const char *str)
387 1d13acf5 2018-10-04 omar.polo {
388 4f769efa 2018-10-06 omar.polo int len, p;
389 4f769efa 2018-10-06 omar.polo char *s;
390 1a4491e5 2018-09-19 omar.polo
391 4f769efa 2018-10-06 omar.polo if ((len = strlen(str)) == 0)
392 1d13acf5 2018-10-04 omar.polo return NULL;
393 95b27a5e 2018-05-19 omar.polo
394 1d13acf5 2018-10-04 omar.polo s = calloc(len, sizeof(char));
395 1d13acf5 2018-10-04 omar.polo check_allocation(s);
396 1d13acf5 2018-10-04 omar.polo p = 0;
397 ddd1263a 2018-09-24 omar.polo
398 1d13acf5 2018-10-04 omar.polo while (*str) {
399 1d13acf5 2018-10-04 omar.polo char c = *str;
400 ddd1263a 2018-09-24 omar.polo
401 1d13acf5 2018-10-04 omar.polo if (*str == '\\') {
402 1d13acf5 2018-10-04 omar.polo if (*(str + 1)) {
403 1d13acf5 2018-10-04 omar.polo s[p] = *(str + 1);
404 1d13acf5 2018-10-04 omar.polo p++;
405 1d13acf5 2018-10-04 omar.polo str += 2; /* skip this and the next char */
406 1d13acf5 2018-10-04 omar.polo continue;
407 1d13acf5 2018-10-04 omar.polo } else
408 1d13acf5 2018-10-04 omar.polo break;
409 1d13acf5 2018-10-04 omar.polo }
410 1d13acf5 2018-10-04 omar.polo if (c == '"') {
411 1d13acf5 2018-10-04 omar.polo str++; /* skip only this char */
412 1d13acf5 2018-10-04 omar.polo continue;
413 1d13acf5 2018-10-04 omar.polo }
414 1d13acf5 2018-10-04 omar.polo s[p] = c;
415 1d13acf5 2018-10-04 omar.polo p++;
416 1d13acf5 2018-10-04 omar.polo str++;
417 1d13acf5 2018-10-04 omar.polo }
418 c9a3bfaa 2018-05-21 omar.polo
419 1d13acf5 2018-10-04 omar.polo return s;
420 c9a3bfaa 2018-05-21 omar.polo }
421 c9a3bfaa 2018-05-21 omar.polo
422 1d13acf5 2018-10-04 omar.polo size_t
423 1d13acf5 2018-10-04 omar.polo read_stdin(char **buf)
424 1d13acf5 2018-10-04 omar.polo {
425 4f769efa 2018-10-06 omar.polo size_t offset = 0;
426 4f769efa 2018-10-06 omar.polo size_t len = STDIN_CHUNKS;
427 c9a3bfaa 2018-05-21 omar.polo
428 1d13acf5 2018-10-04 omar.polo *buf = malloc(len * sizeof(char));
429 1d13acf5 2018-10-04 omar.polo if (*buf == NULL)
430 1d13acf5 2018-10-04 omar.polo goto err;
431 f5e234d6 2018-05-18 omar.polo
432 26b541d8 2018-10-04 omar.polo while (1) {
433 1d13acf5 2018-10-04 omar.polo ssize_t r;
434 1d13acf5 2018-10-04 omar.polo size_t i;
435 c9a3bfaa 2018-05-21 omar.polo
436 1d13acf5 2018-10-04 omar.polo r = read(0, *buf + offset, STDIN_CHUNKS);
437 c9a3bfaa 2018-05-21 omar.polo
438 1d13acf5 2018-10-04 omar.polo if (r < 1)
439 1d13acf5 2018-10-04 omar.polo return len;
440 c9a3bfaa 2018-05-21 omar.polo
441 1d13acf5 2018-10-04 omar.polo offset += r;
442 c9a3bfaa 2018-05-21 omar.polo
443 1d13acf5 2018-10-04 omar.polo len += STDIN_CHUNKS;
444 1d13acf5 2018-10-04 omar.polo *buf = realloc(*buf, len);
445 1d13acf5 2018-10-04 omar.polo if (*buf == NULL)
446 1d13acf5 2018-10-04 omar.polo goto err;
447 1d13acf5 2018-10-04 omar.polo
448 1d13acf5 2018-10-04 omar.polo for (i = offset; i < len; ++i)
449 1d13acf5 2018-10-04 omar.polo (*buf)[i] = '\0';
450 1d13acf5 2018-10-04 omar.polo }
451 1d13acf5 2018-10-04 omar.polo
452 1d13acf5 2018-10-04 omar.polo err:
453 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Error in allocating memory for stdin.\n");
454 1d13acf5 2018-10-04 omar.polo exit(EX_UNAVAILABLE);
455 c9a3bfaa 2018-05-21 omar.polo }
456 c9a3bfaa 2018-05-21 omar.polo
457 1d13acf5 2018-10-04 omar.polo size_t
458 1d13acf5 2018-10-04 omar.polo readlines(char ***lns, char **buf)
459 1d13acf5 2018-10-04 omar.polo {
460 4f769efa 2018-10-06 omar.polo size_t i, len, ll, lines;
461 4f769efa 2018-10-06 omar.polo short in_line = 0;
462 f5e234d6 2018-05-18 omar.polo
463 1d13acf5 2018-10-04 omar.polo lines = 0;
464 8758854a 2018-05-20 omar.polo
465 1d13acf5 2018-10-04 omar.polo *buf = NULL;
466 1d13acf5 2018-10-04 omar.polo len = read_stdin(buf);
467 347d23da 2018-05-19 omar.polo
468 1d13acf5 2018-10-04 omar.polo ll = LINES_CHUNK;
469 1d13acf5 2018-10-04 omar.polo *lns = malloc(ll * sizeof(char*));
470 347d23da 2018-05-19 omar.polo
471 1d13acf5 2018-10-04 omar.polo if (*lns == NULL)
472 1d13acf5 2018-10-04 omar.polo goto err;
473 f5e234d6 2018-05-18 omar.polo
474 4f769efa 2018-10-06 omar.polo for (i = 0; i < len; i++) {
475 1d13acf5 2018-10-04 omar.polo char c = (*buf)[i];
476 f5e234d6 2018-05-18 omar.polo
477 1d13acf5 2018-10-04 omar.polo if (c == '\0')
478 1d13acf5 2018-10-04 omar.polo break;
479 f5e234d6 2018-05-18 omar.polo
480 1d13acf5 2018-10-04 omar.polo if (c == '\n')
481 1d13acf5 2018-10-04 omar.polo (*buf)[i] = '\0';
482 f5e234d6 2018-05-18 omar.polo
483 1d13acf5 2018-10-04 omar.polo if (in_line && c == '\n')
484 26b541d8 2018-10-04 omar.polo in_line = 0;
485 124df174 2018-08-11 omar.polo
486 1d13acf5 2018-10-04 omar.polo if (!in_line && c != '\n') {
487 26b541d8 2018-10-04 omar.polo in_line = 1;
488 1d13acf5 2018-10-04 omar.polo (*lns)[lines] = (*buf) + i;
489 1d13acf5 2018-10-04 omar.polo lines++;
490 f5e234d6 2018-05-18 omar.polo
491 26b541d8 2018-10-04 omar.polo if (lines == ll) { /* resize */
492 1d13acf5 2018-10-04 omar.polo ll += LINES_CHUNK;
493 1d13acf5 2018-10-04 omar.polo *lns = realloc(*lns, ll * sizeof(char*));
494 1d13acf5 2018-10-04 omar.polo if (*lns == NULL)
495 1d13acf5 2018-10-04 omar.polo goto err;
496 1d13acf5 2018-10-04 omar.polo }
497 1d13acf5 2018-10-04 omar.polo }
498 1d13acf5 2018-10-04 omar.polo }
499 f5e234d6 2018-05-18 omar.polo
500 1d13acf5 2018-10-04 omar.polo (*lns)[lines] = NULL;
501 347d23da 2018-05-19 omar.polo
502 1d13acf5 2018-10-04 omar.polo return lines;
503 f5e234d6 2018-05-18 omar.polo
504 1d13acf5 2018-10-04 omar.polo err:
505 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Error in memory allocation.\n");
506 1d13acf5 2018-10-04 omar.polo exit(EX_UNAVAILABLE);
507 f5e234d6 2018-05-18 omar.polo }
508 36a15a9f 2018-05-19 omar.polo
509 1d13acf5 2018-10-04 omar.polo /*
510 1d13acf5 2018-10-04 omar.polo * Compute the dimensions of the string str once rendered.
511 1d13acf5 2018-10-04 omar.polo * It'll return the width and set ret_width and ret_height if not NULL
512 1d13acf5 2018-10-04 omar.polo */
513 1d13acf5 2018-10-04 omar.polo int
514 1d13acf5 2018-10-04 omar.polo text_extents(char *str, int len, struct rendering *r, int *ret_width, int *ret_height)
515 1d13acf5 2018-10-04 omar.polo {
516 43e30577 2018-10-20 omar.polo int height, width;
517 1d13acf5 2018-10-04 omar.polo #ifdef USE_XFT
518 4f769efa 2018-10-06 omar.polo XGlyphInfo gi;
519 1d13acf5 2018-10-04 omar.polo XftTextExtentsUtf8(r->d, r->font, str, len, &gi);
520 1d13acf5 2018-10-04 omar.polo height = r->font->ascent - r->font->descent;
521 1d13acf5 2018-10-04 omar.polo width = gi.width - gi.x;
522 1d13acf5 2018-10-04 omar.polo #else
523 4f769efa 2018-10-06 omar.polo XRectangle rect;
524 1d13acf5 2018-10-04 omar.polo XmbTextExtents(r->font, str, len, NULL, &rect);
525 1d13acf5 2018-10-04 omar.polo height = rect.height;
526 1d13acf5 2018-10-04 omar.polo width = rect.width;
527 1d13acf5 2018-10-04 omar.polo #endif
528 1d13acf5 2018-10-04 omar.polo if (ret_width != NULL) *ret_width = width;
529 1d13acf5 2018-10-04 omar.polo if (ret_height != NULL) *ret_height = height;
530 1d13acf5 2018-10-04 omar.polo return width;
531 1d13acf5 2018-10-04 omar.polo }
532 36a15a9f 2018-05-19 omar.polo
533 1d13acf5 2018-10-04 omar.polo void
534 df29e05e 2018-10-17 omar.polo draw_string(char *str, int len, int x, int y, struct rendering *r, enum obj_type tt)
535 1d13acf5 2018-10-04 omar.polo {
536 1d13acf5 2018-10-04 omar.polo #ifdef USE_XFT
537 1d13acf5 2018-10-04 omar.polo XftColor xftcolor;
538 4c0d79a0 2018-10-09 omar.polo if (tt == PROMPT) xftcolor = r->xft_colors[0];
539 4c0d79a0 2018-10-09 omar.polo if (tt == COMPL) xftcolor = r->xft_colors[1];
540 4c0d79a0 2018-10-09 omar.polo if (tt == COMPL_HIGH) xftcolor = r->xft_colors[2];
541 36a15a9f 2018-05-19 omar.polo
542 1d13acf5 2018-10-04 omar.polo XftDrawStringUtf8(r->xftdraw, &xftcolor, r->font, x, y, str, len);
543 1d13acf5 2018-10-04 omar.polo #else
544 1d13acf5 2018-10-04 omar.polo GC gc;
545 37dbf9ce 2018-10-11 omar.polo if (tt == PROMPT) gc = r->fgs[0];
546 37dbf9ce 2018-10-11 omar.polo if (tt == COMPL) gc = r->fgs[1];
547 37dbf9ce 2018-10-11 omar.polo if (tt == COMPL_HIGH) gc = r->fgs[2];
548 1d13acf5 2018-10-04 omar.polo Xutf8DrawString(r->d, r->w, r->font, gc, x, y, str, len);
549 1d13acf5 2018-10-04 omar.polo #endif
550 1d13acf5 2018-10-04 omar.polo }
551 c9a3bfaa 2018-05-21 omar.polo
552 1d13acf5 2018-10-04 omar.polo /* Duplicate the string and substitute every space with a 'n` */
553 1d13acf5 2018-10-04 omar.polo char *
554 1d13acf5 2018-10-04 omar.polo strdupn(char *str)
555 1d13acf5 2018-10-04 omar.polo {
556 4f769efa 2018-10-06 omar.polo int len, i;
557 4f769efa 2018-10-06 omar.polo char *dup;
558 d29c160f 2018-07-27 omar.polo
559 1d13acf5 2018-10-04 omar.polo len = strlen(str);
560 c9a3bfaa 2018-05-21 omar.polo
561 1d13acf5 2018-10-04 omar.polo if (str == NULL || len == 0)
562 1d13acf5 2018-10-04 omar.polo return NULL;
563 b5d751bd 2018-07-07 omar.polo
564 4f769efa 2018-10-06 omar.polo if ((dup = strdup(str)) == NULL)
565 1d13acf5 2018-10-04 omar.polo return NULL;
566 36a15a9f 2018-05-19 omar.polo
567 1d13acf5 2018-10-04 omar.polo for (i = 0; i < len; ++i)
568 1d13acf5 2018-10-04 omar.polo if (dup[i] == ' ')
569 1d13acf5 2018-10-04 omar.polo dup[i] = 'n';
570 0ee198aa 2018-05-19 omar.polo
571 1d13acf5 2018-10-04 omar.polo return dup;
572 36a15a9f 2018-05-19 omar.polo }
573 36a15a9f 2018-05-19 omar.polo
574 df29e05e 2018-10-17 omar.polo int
575 df29e05e 2018-10-17 omar.polo draw_v_box(struct rendering *r, int y, char *prefix, int prefix_width, enum obj_type t, char *text)
576 1d13acf5 2018-10-04 omar.polo {
577 df29e05e 2018-10-17 omar.polo GC *border_color, bg;
578 df29e05e 2018-10-17 omar.polo int *padding, *borders;
579 df29e05e 2018-10-17 omar.polo int ret = 0, inner_width, inner_height, x;
580 42c3f269 2018-07-08 omar.polo
581 df29e05e 2018-10-17 omar.polo switch (t) {
582 df29e05e 2018-10-17 omar.polo case PROMPT:
583 df29e05e 2018-10-17 omar.polo border_color = r->p_borders_bg;
584 df29e05e 2018-10-17 omar.polo padding = r->p_padding;
585 df29e05e 2018-10-17 omar.polo borders = r->p_borders;
586 df29e05e 2018-10-17 omar.polo bg = r->bgs[0];
587 df29e05e 2018-10-17 omar.polo break;
588 df29e05e 2018-10-17 omar.polo case COMPL:
589 df29e05e 2018-10-17 omar.polo border_color = r->c_borders_bg;
590 df29e05e 2018-10-17 omar.polo padding = r->c_padding;
591 df29e05e 2018-10-17 omar.polo borders = r->c_borders;
592 df29e05e 2018-10-17 omar.polo bg = r->bgs[1];
593 df29e05e 2018-10-17 omar.polo break;
594 df29e05e 2018-10-17 omar.polo case COMPL_HIGH:
595 df29e05e 2018-10-17 omar.polo border_color = r->ch_borders_bg;
596 df29e05e 2018-10-17 omar.polo padding = r->ch_padding;
597 df29e05e 2018-10-17 omar.polo borders = r->ch_borders;
598 df29e05e 2018-10-17 omar.polo bg = r->bgs[2];
599 df29e05e 2018-10-17 omar.polo break;
600 df29e05e 2018-10-17 omar.polo }
601 42c3f269 2018-07-08 omar.polo
602 df29e05e 2018-10-17 omar.polo ret = borders[0] + padding[0] + r->text_height + padding[2] + borders[2];
603 42c3f269 2018-07-08 omar.polo
604 df29e05e 2018-10-17 omar.polo inner_width = inner_width(r) - borders[1] - borders[3];
605 df29e05e 2018-10-17 omar.polo inner_height = padding[0] + r->text_height + padding[2];
606 1d13acf5 2018-10-04 omar.polo
607 df29e05e 2018-10-17 omar.polo /* Border top */
608 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[0], r->x_zero, y, r->width, borders[0]);
609 1d13acf5 2018-10-04 omar.polo
610 df29e05e 2018-10-17 omar.polo /* Border right */
611 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[1], r->x_zero + inner_width(r) - borders[1] , y, borders[1], ret);
612 df29e05e 2018-10-17 omar.polo
613 df29e05e 2018-10-17 omar.polo /* Border bottom */
614 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[2], r->x_zero, y + borders[0] + padding[0] + r->text_height + padding[2], r->width, borders[2]);
615 1d13acf5 2018-10-04 omar.polo
616 df29e05e 2018-10-17 omar.polo /* Border left */
617 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[3], r->x_zero, y, borders[3], ret);
618 1d13acf5 2018-10-04 omar.polo
619 df29e05e 2018-10-17 omar.polo /* bg */
620 df29e05e 2018-10-17 omar.polo x = r->x_zero + borders[3];
621 df29e05e 2018-10-17 omar.polo y += borders[0];
622 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, bg, x, y, inner_width, inner_height);
623 1d13acf5 2018-10-04 omar.polo
624 df29e05e 2018-10-17 omar.polo /* content */
625 df29e05e 2018-10-17 omar.polo y += padding[0] + r->text_height;
626 df29e05e 2018-10-17 omar.polo x += padding[3];
627 df29e05e 2018-10-17 omar.polo if (prefix != NULL) {
628 df29e05e 2018-10-17 omar.polo draw_string(prefix, strlen(prefix), x, y, r, t);
629 df29e05e 2018-10-17 omar.polo x += prefix_width;
630 df29e05e 2018-10-17 omar.polo }
631 df29e05e 2018-10-17 omar.polo draw_string(text, strlen(text), x, y, r, t);
632 1d13acf5 2018-10-04 omar.polo
633 df29e05e 2018-10-17 omar.polo return ret;
634 df29e05e 2018-10-17 omar.polo }
635 1d13acf5 2018-10-04 omar.polo
636 df29e05e 2018-10-17 omar.polo int
637 df29e05e 2018-10-17 omar.polo draw_h_box(struct rendering *r, int x, char *prefix, int prefix_width, enum obj_type t, char *text)
638 df29e05e 2018-10-17 omar.polo {
639 df29e05e 2018-10-17 omar.polo GC *border_color, bg;
640 df29e05e 2018-10-17 omar.polo int *padding, *borders;
641 df29e05e 2018-10-17 omar.polo int ret = 0, inner_width, inner_height, y, text_width;
642 df29e05e 2018-10-17 omar.polo
643 df29e05e 2018-10-17 omar.polo switch (t) {
644 df29e05e 2018-10-17 omar.polo case PROMPT:
645 df29e05e 2018-10-17 omar.polo border_color = r->p_borders_bg;
646 df29e05e 2018-10-17 omar.polo padding = r->p_padding;
647 df29e05e 2018-10-17 omar.polo borders = r->p_borders;
648 df29e05e 2018-10-17 omar.polo bg = r->bgs[0];
649 df29e05e 2018-10-17 omar.polo break;
650 df29e05e 2018-10-17 omar.polo case COMPL:
651 df29e05e 2018-10-17 omar.polo border_color = r->c_borders_bg;
652 df29e05e 2018-10-17 omar.polo padding = r->c_padding;
653 df29e05e 2018-10-17 omar.polo borders = r->c_borders;
654 df29e05e 2018-10-17 omar.polo bg = r->bgs[1];
655 df29e05e 2018-10-17 omar.polo break;
656 df29e05e 2018-10-17 omar.polo case COMPL_HIGH:
657 df29e05e 2018-10-17 omar.polo border_color = r->ch_borders_bg;
658 df29e05e 2018-10-17 omar.polo padding = r->ch_padding;
659 df29e05e 2018-10-17 omar.polo borders = r->ch_borders;
660 df29e05e 2018-10-17 omar.polo bg = r->bgs[2];
661 df29e05e 2018-10-17 omar.polo break;
662 df29e05e 2018-10-17 omar.polo }
663 df29e05e 2018-10-17 omar.polo
664 df29e05e 2018-10-17 omar.polo if (padding[0] < 0 || padding[2] < 0)
665 df29e05e 2018-10-17 omar.polo padding[0] = padding[2] = (inner_height(r) - borders[0] - borders[2] - r->text_height)/2;
666 df29e05e 2018-10-17 omar.polo
667 df29e05e 2018-10-17 omar.polo /* If they are still lesser than 0, set 'em to 0 */
668 df29e05e 2018-10-17 omar.polo if (padding[0] < 0 || padding[2] < 0)
669 df29e05e 2018-10-17 omar.polo padding[0] = padding[2] = 0;
670 df29e05e 2018-10-17 omar.polo
671 df29e05e 2018-10-17 omar.polo /* Get the text width */
672 df29e05e 2018-10-17 omar.polo text_extents(text, strlen(text), r, &text_width, NULL);
673 df29e05e 2018-10-17 omar.polo if (prefix != NULL)
674 df29e05e 2018-10-17 omar.polo text_width += prefix_width;
675 df29e05e 2018-10-17 omar.polo
676 df29e05e 2018-10-17 omar.polo ret = borders[3] + padding[3] + text_width + padding[1] + borders[1];
677 df29e05e 2018-10-17 omar.polo
678 df29e05e 2018-10-17 omar.polo inner_width = padding[3] + text_width + padding[1];
679 df29e05e 2018-10-17 omar.polo inner_height = inner_height(r) - borders[0] - borders[2];
680 df29e05e 2018-10-17 omar.polo
681 df29e05e 2018-10-17 omar.polo /* Border top */
682 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[0], x, r->y_zero, ret, borders[0]);
683 df29e05e 2018-10-17 omar.polo
684 df29e05e 2018-10-17 omar.polo /* Border right */
685 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[1], x + borders[3] + inner_width, r->y_zero, borders[1], inner_height(r));
686 df29e05e 2018-10-17 omar.polo
687 df29e05e 2018-10-17 omar.polo /* Border bottom */
688 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[2], x, r->y_zero + inner_height(r) - borders[2], ret, borders[2]);
689 df29e05e 2018-10-17 omar.polo
690 df29e05e 2018-10-17 omar.polo /* Border left */
691 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, border_color[3], x, r->y_zero, borders[3], inner_height(r));
692 df29e05e 2018-10-17 omar.polo
693 df29e05e 2018-10-17 omar.polo /* bg */
694 df29e05e 2018-10-17 omar.polo x += borders[3];
695 df29e05e 2018-10-17 omar.polo y = r->y_zero + borders[0];
696 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, bg, x, y, inner_width, inner_height);
697 df29e05e 2018-10-17 omar.polo
698 df29e05e 2018-10-17 omar.polo /* content */
699 df29e05e 2018-10-17 omar.polo y += padding[0] + r->text_height;
700 df29e05e 2018-10-17 omar.polo x += padding[3];
701 df29e05e 2018-10-17 omar.polo if (prefix != NULL) {
702 df29e05e 2018-10-17 omar.polo draw_string(prefix, strlen(prefix), x, y, r, t);
703 df29e05e 2018-10-17 omar.polo x += prefix_width;
704 1d13acf5 2018-10-04 omar.polo }
705 df29e05e 2018-10-17 omar.polo draw_string(text, strlen(text), x, y, r, t);
706 df29e05e 2018-10-17 omar.polo
707 df29e05e 2018-10-17 omar.polo return ret;
708 36a15a9f 2018-05-19 omar.polo }
709 36a15a9f 2018-05-19 omar.polo
710 51986bb8 2018-10-06 omar.polo /* ,-----------------------------------------------------------------, */
711 df29e05e 2018-10-17 omar.polo /* | 20 char text | completion | completion | completion | compl | */
712 df29e05e 2018-10-17 omar.polo /* `-----------------------------------------------------------------' */
713 df29e05e 2018-10-17 omar.polo void
714 df29e05e 2018-10-17 omar.polo draw_horizontally(struct rendering *r, char *text, struct completions *cs)
715 df29e05e 2018-10-17 omar.polo {
716 df29e05e 2018-10-17 omar.polo size_t i;
717 df29e05e 2018-10-17 omar.polo int x = r->x_zero;
718 df29e05e 2018-10-17 omar.polo
719 df29e05e 2018-10-17 omar.polo /* Draw the prompt */
720 df29e05e 2018-10-17 omar.polo x += draw_h_box(r, x, r->ps1, r->ps1w, PROMPT, text);
721 df29e05e 2018-10-17 omar.polo
722 df29e05e 2018-10-17 omar.polo for (i = r->offset; i < cs->length; ++i) {
723 df29e05e 2018-10-17 omar.polo enum obj_type t = cs->selected == (ssize_t)i ? COMPL_HIGH : COMPL;
724 df29e05e 2018-10-17 omar.polo
725 df29e05e 2018-10-17 omar.polo x += draw_h_box(r, x, NULL, 0, t, cs->completions[i].completion);
726 df29e05e 2018-10-17 omar.polo
727 df29e05e 2018-10-17 omar.polo if (x > inner_width(r))
728 df29e05e 2018-10-17 omar.polo break;
729 df29e05e 2018-10-17 omar.polo }
730 df29e05e 2018-10-17 omar.polo }
731 df29e05e 2018-10-17 omar.polo
732 df29e05e 2018-10-17 omar.polo /* ,-----------------------------------------------------------------, */
733 1d13acf5 2018-10-04 omar.polo /* | prompt | */
734 1d13acf5 2018-10-04 omar.polo /* |-----------------------------------------------------------------| */
735 1d13acf5 2018-10-04 omar.polo /* | completion | */
736 1d13acf5 2018-10-04 omar.polo /* |-----------------------------------------------------------------| */
737 1d13acf5 2018-10-04 omar.polo /* | completion | */
738 51986bb8 2018-10-06 omar.polo /* `-----------------------------------------------------------------' */
739 1d13acf5 2018-10-04 omar.polo void
740 1d13acf5 2018-10-04 omar.polo draw_vertically(struct rendering *r, char *text, struct completions *cs)
741 1d13acf5 2018-10-04 omar.polo {
742 1d13acf5 2018-10-04 omar.polo size_t i;
743 df29e05e 2018-10-17 omar.polo int y = r->y_zero;
744 f5e234d6 2018-05-18 omar.polo
745 df29e05e 2018-10-17 omar.polo y += draw_v_box(r, y, r->ps1, r->ps1w, PROMPT, text);
746 f5e234d6 2018-05-18 omar.polo
747 1d13acf5 2018-10-04 omar.polo for (i = r->offset; i < cs->length; ++i) {
748 df29e05e 2018-10-17 omar.polo enum obj_type t = cs->selected == (ssize_t)i ? COMPL_HIGH : COMPL;
749 1d13acf5 2018-10-04 omar.polo
750 df29e05e 2018-10-17 omar.polo y += draw_v_box(r, y, NULL, 0, t, cs->completions[i].completion);
751 1d13acf5 2018-10-04 omar.polo
752 df29e05e 2018-10-17 omar.polo if (y > inner_height(r))
753 df29e05e 2018-10-17 omar.polo break;
754 1d13acf5 2018-10-04 omar.polo }
755 f5e234d6 2018-05-18 omar.polo }
756 f5e234d6 2018-05-18 omar.polo
757 1d13acf5 2018-10-04 omar.polo void
758 1d13acf5 2018-10-04 omar.polo draw(struct rendering *r, char *text, struct completions *cs)
759 1d13acf5 2018-10-04 omar.polo {
760 df29e05e 2018-10-17 omar.polo /* Draw the background */
761 df29e05e 2018-10-17 omar.polo XFillRectangle(r->d, r->w, r->bgs[1], r->x_zero, r->y_zero, inner_width(r), inner_height(r));
762 df29e05e 2018-10-17 omar.polo
763 df29e05e 2018-10-17 omar.polo /* Draw the contents */
764 1d13acf5 2018-10-04 omar.polo if (r->horizontal_layout)
765 1d13acf5 2018-10-04 omar.polo draw_horizontally(r, text, cs);
766 1d13acf5 2018-10-04 omar.polo else
767 1d13acf5 2018-10-04 omar.polo draw_vertically(r, text, cs);
768 1d13acf5 2018-10-04 omar.polo
769 1d13acf5 2018-10-04 omar.polo /* Draw the borders */
770 4c0d79a0 2018-10-09 omar.polo if (r->borders[0] != 0)
771 4c0d79a0 2018-10-09 omar.polo XFillRectangle(r->d, r->w, r->borders_bg[0], 0, 0, r->width, r->borders[0]);
772 1d13acf5 2018-10-04 omar.polo
773 4c0d79a0 2018-10-09 omar.polo if (r->borders[1] != 0)
774 4c0d79a0 2018-10-09 omar.polo XFillRectangle(r->d, r->w, r->borders_bg[1], r->width - r->borders[1], 0, r->borders[1], r->height);
775 1d13acf5 2018-10-04 omar.polo
776 4c0d79a0 2018-10-09 omar.polo if (r->borders[2] != 0)
777 4c0d79a0 2018-10-09 omar.polo XFillRectangle(r->d, r->w, r->borders_bg[2], 0, r->height - r->borders[2], r->width, r->borders[2]);
778 1d13acf5 2018-10-04 omar.polo
779 4c0d79a0 2018-10-09 omar.polo if (r->borders[3] != 0)
780 4c0d79a0 2018-10-09 omar.polo XFillRectangle(r->d, r->w, r->borders_bg[3], 0, 0, r->borders[3], r->height);
781 4c0d79a0 2018-10-09 omar.polo
782 1d13acf5 2018-10-04 omar.polo /* render! */
783 1d13acf5 2018-10-04 omar.polo XFlush(r->d);
784 1d13acf5 2018-10-04 omar.polo }
785 1d13acf5 2018-10-04 omar.polo
786 1d13acf5 2018-10-04 omar.polo /* Set some WM stuff */
787 1d13acf5 2018-10-04 omar.polo void
788 1d13acf5 2018-10-04 omar.polo set_win_atoms_hints(Display *d, Window w, int width, int height)
789 1d13acf5 2018-10-04 omar.polo {
790 1d13acf5 2018-10-04 omar.polo Atom type;
791 1d13acf5 2018-10-04 omar.polo XClassHint *class_hint;
792 1d13acf5 2018-10-04 omar.polo XSizeHints *size_hint;
793 1d13acf5 2018-10-04 omar.polo
794 26b541d8 2018-10-04 omar.polo type = XInternAtom(d, "_NET_WM_WINDOW_TYPE_DOCK", 0);
795 4f769efa 2018-10-06 omar.polo XChangeProperty(d,
796 1d13acf5 2018-10-04 omar.polo w,
797 26b541d8 2018-10-04 omar.polo XInternAtom(d, "_NET_WM_WINDOW_TYPE", 0),
798 26b541d8 2018-10-04 omar.polo XInternAtom(d, "ATOM", 0),
799 1d13acf5 2018-10-04 omar.polo 32,
800 1d13acf5 2018-10-04 omar.polo PropModeReplace,
801 1d13acf5 2018-10-04 omar.polo (unsigned char *)&type,
802 1d13acf5 2018-10-04 omar.polo 1
803 1d13acf5 2018-10-04 omar.polo );
804 1d13acf5 2018-10-04 omar.polo
805 1d13acf5 2018-10-04 omar.polo /* some window managers honor this properties */
806 26b541d8 2018-10-04 omar.polo type = XInternAtom(d, "_NET_WM_STATE_ABOVE", 0);
807 1d13acf5 2018-10-04 omar.polo XChangeProperty(d,
808 1d13acf5 2018-10-04 omar.polo w,
809 26b541d8 2018-10-04 omar.polo XInternAtom(d, "_NET_WM_STATE", 0),
810 26b541d8 2018-10-04 omar.polo XInternAtom(d, "ATOM", 0),
811 1d13acf5 2018-10-04 omar.polo 32,
812 1d13acf5 2018-10-04 omar.polo PropModeReplace,
813 1d13acf5 2018-10-04 omar.polo (unsigned char *)&type,
814 1d13acf5 2018-10-04 omar.polo 1
815 1d13acf5 2018-10-04 omar.polo );
816 1d13acf5 2018-10-04 omar.polo
817 26b541d8 2018-10-04 omar.polo type = XInternAtom(d, "_NET_WM_STATE_FOCUSED", 0);
818 1d13acf5 2018-10-04 omar.polo XChangeProperty(d,
819 1d13acf5 2018-10-04 omar.polo w,
820 26b541d8 2018-10-04 omar.polo XInternAtom(d, "_NET_WM_STATE", 0),
821 26b541d8 2018-10-04 omar.polo XInternAtom(d, "ATOM", 0),
822 1d13acf5 2018-10-04 omar.polo 32,
823 1d13acf5 2018-10-04 omar.polo PropModeAppend,
824 1d13acf5 2018-10-04 omar.polo (unsigned char *)&type,
825 1d13acf5 2018-10-04 omar.polo 1
826 1d13acf5 2018-10-04 omar.polo );
827 1d13acf5 2018-10-04 omar.polo
828 1d13acf5 2018-10-04 omar.polo /* Setting window hints */
829 1d13acf5 2018-10-04 omar.polo class_hint = XAllocClassHint();
830 1d13acf5 2018-10-04 omar.polo if (class_hint == NULL) {
831 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Could not allocate memory for class hint\n");
832 1d13acf5 2018-10-04 omar.polo exit(EX_UNAVAILABLE);
833 1d13acf5 2018-10-04 omar.polo }
834 4f769efa 2018-10-06 omar.polo
835 1d13acf5 2018-10-04 omar.polo class_hint->res_name = resname;
836 1d13acf5 2018-10-04 omar.polo class_hint->res_class = resclass;
837 1d13acf5 2018-10-04 omar.polo XSetClassHint(d, w, class_hint);
838 1d13acf5 2018-10-04 omar.polo XFree(class_hint);
839 844addbb 2018-07-15 omar.polo
840 1d13acf5 2018-10-04 omar.polo size_hint = XAllocSizeHints();
841 1d13acf5 2018-10-04 omar.polo if (size_hint == NULL) {
842 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Could not allocate memory for size hint\n");
843 1d13acf5 2018-10-04 omar.polo exit(EX_UNAVAILABLE);
844 1d13acf5 2018-10-04 omar.polo }
845 4f769efa 2018-10-06 omar.polo
846 1d13acf5 2018-10-04 omar.polo size_hint->flags = PMinSize | PBaseSize;
847 1d13acf5 2018-10-04 omar.polo size_hint->min_width = width;
848 1d13acf5 2018-10-04 omar.polo size_hint->base_width = width;
849 1d13acf5 2018-10-04 omar.polo size_hint->min_height = height;
850 1d13acf5 2018-10-04 omar.polo size_hint->base_height = height;
851 f5e234d6 2018-05-18 omar.polo
852 1d13acf5 2018-10-04 omar.polo XFlush(d);
853 f5e234d6 2018-05-18 omar.polo }
854 f5e234d6 2018-05-18 omar.polo
855 1d13acf5 2018-10-04 omar.polo /* Get the width and height of the window `w' */
856 1d13acf5 2018-10-04 omar.polo void
857 1d13acf5 2018-10-04 omar.polo get_wh(Display *d, Window *w, int *width, int *height)
858 1d13acf5 2018-10-04 omar.polo {
859 1d13acf5 2018-10-04 omar.polo XWindowAttributes win_attr;
860 1d13acf5 2018-10-04 omar.polo
861 1d13acf5 2018-10-04 omar.polo XGetWindowAttributes(d, *w, &win_attr);
862 1d13acf5 2018-10-04 omar.polo *height = win_attr.height;
863 1d13acf5 2018-10-04 omar.polo *width = win_attr.width;
864 6bb186a7 2018-09-13 omar.polo }
865 6bb186a7 2018-09-13 omar.polo
866 1d13acf5 2018-10-04 omar.polo int
867 1d13acf5 2018-10-04 omar.polo grabfocus(Display *d, Window w)
868 1d13acf5 2018-10-04 omar.polo {
869 1d13acf5 2018-10-04 omar.polo int i;
870 1d13acf5 2018-10-04 omar.polo for (i = 0; i < 100; ++i) {
871 1d13acf5 2018-10-04 omar.polo Window focuswin;
872 1d13acf5 2018-10-04 omar.polo int revert_to_win;
873 6bb186a7 2018-09-13 omar.polo
874 1d13acf5 2018-10-04 omar.polo XGetInputFocus(d, &focuswin, &revert_to_win);
875 6bb186a7 2018-09-13 omar.polo
876 1d13acf5 2018-10-04 omar.polo if (focuswin == w)
877 26b541d8 2018-10-04 omar.polo return 1;
878 6bb186a7 2018-09-13 omar.polo
879 1d13acf5 2018-10-04 omar.polo XSetInputFocus(d, w, RevertToParent, CurrentTime);
880 1d13acf5 2018-10-04 omar.polo usleep(1000);
881 1d13acf5 2018-10-04 omar.polo }
882 1d13acf5 2018-10-04 omar.polo return 0;
883 1d13acf5 2018-10-04 omar.polo }
884 6bb186a7 2018-09-13 omar.polo
885 1d13acf5 2018-10-04 omar.polo /*
886 1d13acf5 2018-10-04 omar.polo * I know this may seem a little hackish BUT is the only way I managed
887 1d13acf5 2018-10-04 omar.polo * to actually grab that goddam keyboard. Only one call to
888 1d13acf5 2018-10-04 omar.polo * XGrabKeyboard does not always end up with the keyboard grabbed!
889 1d13acf5 2018-10-04 omar.polo */
890 1d13acf5 2018-10-04 omar.polo int
891 1d13acf5 2018-10-04 omar.polo take_keyboard(Display *d, Window w)
892 1d13acf5 2018-10-04 omar.polo {
893 1d13acf5 2018-10-04 omar.polo int i;
894 1d13acf5 2018-10-04 omar.polo for (i = 0; i < 100; i++) {
895 26b541d8 2018-10-04 omar.polo if (XGrabKeyboard(d, w, 1, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess)
896 1d13acf5 2018-10-04 omar.polo return 1;
897 1d13acf5 2018-10-04 omar.polo usleep(1000);
898 1d13acf5 2018-10-04 omar.polo }
899 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Cannot grab keyboard\n");
900 1d13acf5 2018-10-04 omar.polo return 0;
901 f5e234d6 2018-05-18 omar.polo }
902 f5e234d6 2018-05-18 omar.polo
903 1d13acf5 2018-10-04 omar.polo unsigned long
904 1d13acf5 2018-10-04 omar.polo parse_color(const char *str, const char *def)
905 1d13acf5 2018-10-04 omar.polo {
906 1d13acf5 2018-10-04 omar.polo size_t len;
907 1d13acf5 2018-10-04 omar.polo rgba_t tmp;
908 1d13acf5 2018-10-04 omar.polo char *ep;
909 25bf99d2 2018-05-22 omar.polo
910 1d13acf5 2018-10-04 omar.polo if (str == NULL)
911 1d13acf5 2018-10-04 omar.polo goto invc;
912 f5e234d6 2018-05-18 omar.polo
913 1d13acf5 2018-10-04 omar.polo len = strlen(str);
914 f5e234d6 2018-05-18 omar.polo
915 1d13acf5 2018-10-04 omar.polo /* +1 for the # ath the start */
916 1d13acf5 2018-10-04 omar.polo if (*str != '#' || len > 9 || len < 4)
917 1d13acf5 2018-10-04 omar.polo goto invc;
918 1d13acf5 2018-10-04 omar.polo ++str; /* skip the # */
919 42c3f269 2018-07-08 omar.polo
920 1d13acf5 2018-10-04 omar.polo errno = 0;
921 1d13acf5 2018-10-04 omar.polo tmp = (rgba_t)(uint32_t)strtoul(str, &ep, 16);
922 42c3f269 2018-07-08 omar.polo
923 1d13acf5 2018-10-04 omar.polo if (errno)
924 1d13acf5 2018-10-04 omar.polo goto invc;
925 42c3f269 2018-07-08 omar.polo
926 1d13acf5 2018-10-04 omar.polo switch (len-1) {
927 1d13acf5 2018-10-04 omar.polo case 3:
928 1d13acf5 2018-10-04 omar.polo /* expand #rgb -> #rrggbb */
929 4f769efa 2018-10-06 omar.polo tmp.v = (tmp.v & 0xf00) * 0x1100
930 1d13acf5 2018-10-04 omar.polo | (tmp.v & 0x0f0) * 0x0110
931 1d13acf5 2018-10-04 omar.polo | (tmp.v & 0x00f) * 0x0011;
932 1d13acf5 2018-10-04 omar.polo case 6:
933 1d13acf5 2018-10-04 omar.polo /* assume 0xff opacity */
934 4f769efa 2018-10-06 omar.polo tmp.rgba.a = 0xff;
935 1d13acf5 2018-10-04 omar.polo break;
936 1d13acf5 2018-10-04 omar.polo } /* colors in #aarrggbb need no adjustments */
937 42c3f269 2018-07-08 omar.polo
938 1d13acf5 2018-10-04 omar.polo /* premultiply the alpha */
939 4f769efa 2018-10-06 omar.polo if (tmp.rgba.a) {
940 4f769efa 2018-10-06 omar.polo tmp.rgba.r = (tmp.rgba.r * tmp.rgba.a) / 255;
941 4f769efa 2018-10-06 omar.polo tmp.rgba.g = (tmp.rgba.g * tmp.rgba.a) / 255;
942 4f769efa 2018-10-06 omar.polo tmp.rgba.b = (tmp.rgba.b * tmp.rgba.a) / 255;
943 1d13acf5 2018-10-04 omar.polo return tmp.v;
944 1d13acf5 2018-10-04 omar.polo }
945 42c3f269 2018-07-08 omar.polo
946 1d13acf5 2018-10-04 omar.polo return 0U;
947 42c3f269 2018-07-08 omar.polo
948 1d13acf5 2018-10-04 omar.polo invc:
949 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Invalid color: \"%s\".\n", str);
950 1d13acf5 2018-10-04 omar.polo if (def != NULL)
951 1d13acf5 2018-10-04 omar.polo return parse_color(def, NULL);
952 1d13acf5 2018-10-04 omar.polo else
953 1d13acf5 2018-10-04 omar.polo return 0U;
954 1d13acf5 2018-10-04 omar.polo }
955 42c3f269 2018-07-08 omar.polo
956 26b541d8 2018-10-04 omar.polo /*
957 26b541d8 2018-10-04 omar.polo * Given a string try to parse it as a number or return `default_value'.
958 26b541d8 2018-10-04 omar.polo */
959 1d13acf5 2018-10-04 omar.polo int
960 1d13acf5 2018-10-04 omar.polo parse_integer(const char *str, int default_value)
961 1d13acf5 2018-10-04 omar.polo {
962 1d13acf5 2018-10-04 omar.polo long lval;
963 1d13acf5 2018-10-04 omar.polo char *ep;
964 42c3f269 2018-07-08 omar.polo
965 1d13acf5 2018-10-04 omar.polo errno = 0;
966 1d13acf5 2018-10-04 omar.polo lval = strtol(str, &ep, 10);
967 42c3f269 2018-07-08 omar.polo
968 26b541d8 2018-10-04 omar.polo if (str[0] == '\0' || *ep != '\0') { /* NaN */
969 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "'%s' is not a valid number! Using %d as default.\n", str, default_value);
970 1d13acf5 2018-10-04 omar.polo return default_value;
971 1d13acf5 2018-10-04 omar.polo }
972 42c3f269 2018-07-08 omar.polo
973 1d13acf5 2018-10-04 omar.polo if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
974 1d13acf5 2018-10-04 omar.polo (lval > INT_MAX || lval < INT_MIN)) {
975 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "%s out of range! Using %d as default.\n", str, default_value);
976 1d13acf5 2018-10-04 omar.polo return default_value;
977 1d13acf5 2018-10-04 omar.polo }
978 1d13acf5 2018-10-04 omar.polo
979 1d13acf5 2018-10-04 omar.polo return lval;
980 42c3f269 2018-07-08 omar.polo }
981 42c3f269 2018-07-08 omar.polo
982 1d13acf5 2018-10-04 omar.polo /* Like parse_integer but recognize the percentages (i.e. strings ending with `%') */
983 1d13acf5 2018-10-04 omar.polo int
984 1d13acf5 2018-10-04 omar.polo parse_int_with_percentage(const char *str, int default_value, int max)
985 1d13acf5 2018-10-04 omar.polo {
986 1d13acf5 2018-10-04 omar.polo int len = strlen(str);
987 2128b469 2018-06-30 omar.polo
988 1d13acf5 2018-10-04 omar.polo if (len > 0 && str[len-1] == '%') {
989 1d13acf5 2018-10-04 omar.polo int val;
990 1d13acf5 2018-10-04 omar.polo char *cpy;
991 2128b469 2018-06-30 omar.polo
992 1d13acf5 2018-10-04 omar.polo cpy = strdup(str);
993 1d13acf5 2018-10-04 omar.polo check_allocation(cpy);
994 1d13acf5 2018-10-04 omar.polo cpy[len-1] = '\0';
995 1d13acf5 2018-10-04 omar.polo val = parse_integer(cpy, default_value);
996 1d13acf5 2018-10-04 omar.polo free(cpy);
997 1d13acf5 2018-10-04 omar.polo return val * max / 100;
998 1d13acf5 2018-10-04 omar.polo }
999 4f769efa 2018-10-06 omar.polo
1000 1d13acf5 2018-10-04 omar.polo return parse_integer(str, default_value);
1001 2128b469 2018-06-30 omar.polo }
1002 2128b469 2018-06-30 omar.polo
1003 1d13acf5 2018-10-04 omar.polo /*
1004 1d13acf5 2018-10-04 omar.polo * Like parse_int_with_percentage but understands some special values:
1005 1d13acf5 2018-10-04 omar.polo * - middle that is (max-self)/2
1006 1d13acf5 2018-10-04 omar.polo * - start that is 0
1007 1d13acf5 2018-10-04 omar.polo * - end that is (max-self)
1008 1d13acf5 2018-10-04 omar.polo */
1009 1d13acf5 2018-10-04 omar.polo int
1010 1d13acf5 2018-10-04 omar.polo parse_int_with_pos(const char *str, int default_value, int max, int self)
1011 1d13acf5 2018-10-04 omar.polo {
1012 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "start"))
1013 1d13acf5 2018-10-04 omar.polo return 0;
1014 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "middle"))
1015 1d13acf5 2018-10-04 omar.polo return (max - self)/2;
1016 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "end"))
1017 1d13acf5 2018-10-04 omar.polo return max-self;
1018 1d13acf5 2018-10-04 omar.polo return parse_int_with_percentage(str, default_value, max);
1019 991c5d3c 2018-08-13 omar.polo }
1020 991c5d3c 2018-08-13 omar.polo
1021 1d13acf5 2018-10-04 omar.polo /* Parse a string like a CSS value. */
1022 1d13acf5 2018-10-04 omar.polo /* TODO: harden a bit this function */
1023 1d13acf5 2018-10-04 omar.polo char **
1024 1d13acf5 2018-10-04 omar.polo parse_csslike(const char *str)
1025 1d13acf5 2018-10-04 omar.polo {
1026 4f769efa 2018-10-06 omar.polo int i, j;
1027 1d13acf5 2018-10-04 omar.polo char *s, *token, **ret;
1028 26b541d8 2018-10-04 omar.polo short any_null;
1029 991c5d3c 2018-08-13 omar.polo
1030 1d13acf5 2018-10-04 omar.polo s = strdup(str);
1031 1d13acf5 2018-10-04 omar.polo if (s == NULL)
1032 1d13acf5 2018-10-04 omar.polo return NULL;
1033 991c5d3c 2018-08-13 omar.polo
1034 1d13acf5 2018-10-04 omar.polo ret = malloc(4 * sizeof(char*));
1035 1d13acf5 2018-10-04 omar.polo if (ret == NULL) {
1036 1d13acf5 2018-10-04 omar.polo free(s);
1037 1d13acf5 2018-10-04 omar.polo return NULL;
1038 1d13acf5 2018-10-04 omar.polo }
1039 991c5d3c 2018-08-13 omar.polo
1040 4f769efa 2018-10-06 omar.polo for (i = 0; (token = strsep(&s, " ")) != NULL && i < 4; ++i)
1041 1d13acf5 2018-10-04 omar.polo ret[i] = strdup(token);
1042 991c5d3c 2018-08-13 omar.polo
1043 1d13acf5 2018-10-04 omar.polo if (i == 1)
1044 4f769efa 2018-10-06 omar.polo for (j = 1; j < 4; j++)
1045 1d13acf5 2018-10-04 omar.polo ret[j] = strdup(ret[0]);
1046 991c5d3c 2018-08-13 omar.polo
1047 1d13acf5 2018-10-04 omar.polo if (i == 2) {
1048 1d13acf5 2018-10-04 omar.polo ret[2] = strdup(ret[0]);
1049 1d13acf5 2018-10-04 omar.polo ret[3] = strdup(ret[1]);
1050 1d13acf5 2018-10-04 omar.polo }
1051 991c5d3c 2018-08-13 omar.polo
1052 1d13acf5 2018-10-04 omar.polo if (i == 3)
1053 1d13acf5 2018-10-04 omar.polo ret[3] = strdup(ret[1]);
1054 991c5d3c 2018-08-13 omar.polo
1055 1d13acf5 2018-10-04 omar.polo /* before we didn't check for the return type of strdup, here we will */
1056 991c5d3c 2018-08-13 omar.polo
1057 26b541d8 2018-10-04 omar.polo any_null = 0;
1058 1d13acf5 2018-10-04 omar.polo for (i = 0; i < 4; ++i)
1059 1d13acf5 2018-10-04 omar.polo any_null = ret[i] == NULL || any_null;
1060 991c5d3c 2018-08-13 omar.polo
1061 1d13acf5 2018-10-04 omar.polo if (any_null)
1062 1d13acf5 2018-10-04 omar.polo for (i = 0; i < 4; ++i)
1063 1d13acf5 2018-10-04 omar.polo if (ret[i] != NULL)
1064 1d13acf5 2018-10-04 omar.polo free(ret[i]);
1065 991c5d3c 2018-08-13 omar.polo
1066 1d13acf5 2018-10-04 omar.polo if (i == 0 || any_null) {
1067 1d13acf5 2018-10-04 omar.polo free(s);
1068 1d13acf5 2018-10-04 omar.polo free(ret);
1069 1d13acf5 2018-10-04 omar.polo return NULL;
1070 1d13acf5 2018-10-04 omar.polo }
1071 991c5d3c 2018-08-13 omar.polo
1072 1d13acf5 2018-10-04 omar.polo return ret;
1073 1d13acf5 2018-10-04 omar.polo }
1074 991c5d3c 2018-08-13 omar.polo
1075 1d13acf5 2018-10-04 omar.polo /*
1076 1d13acf5 2018-10-04 omar.polo * Given an event, try to understand what the users wants. If the
1077 1d13acf5 2018-10-04 omar.polo * return value is ADD_CHAR then `input' is a pointer to a string that
1078 1d13acf5 2018-10-04 omar.polo * will need to be free'ed later.
1079 1d13acf5 2018-10-04 omar.polo */
1080 1d13acf5 2018-10-04 omar.polo enum
1081 1d13acf5 2018-10-04 omar.polo action parse_event(Display *d, XKeyPressedEvent *ev, XIC xic, char **input)
1082 1d13acf5 2018-10-04 omar.polo {
1083 1d13acf5 2018-10-04 omar.polo char str[SYM_BUF_SIZE] = {0};
1084 1d13acf5 2018-10-04 omar.polo Status s;
1085 991c5d3c 2018-08-13 omar.polo
1086 1d13acf5 2018-10-04 omar.polo if (ev->keycode == XKeysymToKeycode(d, XK_BackSpace))
1087 1d13acf5 2018-10-04 omar.polo return DEL_CHAR;
1088 991c5d3c 2018-08-13 omar.polo
1089 1d13acf5 2018-10-04 omar.polo if (ev->keycode == XKeysymToKeycode(d, XK_Tab))
1090 1d13acf5 2018-10-04 omar.polo return ev->state & ShiftMask ? PREV_COMPL : NEXT_COMPL;
1091 991c5d3c 2018-08-13 omar.polo
1092 1d13acf5 2018-10-04 omar.polo if (ev->keycode == XKeysymToKeycode(d, XK_Return))
1093 1d13acf5 2018-10-04 omar.polo return CONFIRM;
1094 991c5d3c 2018-08-13 omar.polo
1095 1d13acf5 2018-10-04 omar.polo if (ev->keycode == XKeysymToKeycode(d, XK_Escape))
1096 1d13acf5 2018-10-04 omar.polo return EXIT;
1097 991c5d3c 2018-08-13 omar.polo
1098 1d13acf5 2018-10-04 omar.polo /* Try to read what key was pressed */
1099 1d13acf5 2018-10-04 omar.polo s = 0;
1100 1d13acf5 2018-10-04 omar.polo Xutf8LookupString(xic, ev, str, SYM_BUF_SIZE, 0, &s);
1101 1d13acf5 2018-10-04 omar.polo if (s == XBufferOverflow) {
1102 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Buffer overflow when trying to create keyboard symbol map.\n");
1103 1d13acf5 2018-10-04 omar.polo return EXIT;
1104 1d13acf5 2018-10-04 omar.polo }
1105 991c5d3c 2018-08-13 omar.polo
1106 1d13acf5 2018-10-04 omar.polo if (ev->state & ControlMask) {
1107 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "")) /* C-u */
1108 1d13acf5 2018-10-04 omar.polo return DEL_LINE;
1109 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "")) /* C-w */
1110 1d13acf5 2018-10-04 omar.polo return DEL_WORD;
1111 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "")) /* C-h */
1112 1d13acf5 2018-10-04 omar.polo return DEL_CHAR;
1113 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "\r")) /* C-m */
1114 1d13acf5 2018-10-04 omar.polo return CONFIRM_CONTINUE;
1115 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "")) /* C-p */
1116 1d13acf5 2018-10-04 omar.polo return PREV_COMPL;
1117 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "")) /* C-n */
1118 1d13acf5 2018-10-04 omar.polo return NEXT_COMPL;
1119 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "")) /* C-c */
1120 1d13acf5 2018-10-04 omar.polo return EXIT;
1121 1d13acf5 2018-10-04 omar.polo if (!strcmp(str, "\t")) /* C-i */
1122 1d13acf5 2018-10-04 omar.polo return TOGGLE_FIRST_SELECTED;
1123 1d13acf5 2018-10-04 omar.polo }
1124 991c5d3c 2018-08-13 omar.polo
1125 1d13acf5 2018-10-04 omar.polo *input = strdup(str);
1126 1d13acf5 2018-10-04 omar.polo if (*input == NULL) {
1127 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Error while allocating memory for key.\n");
1128 1d13acf5 2018-10-04 omar.polo return EXIT;
1129 1d13acf5 2018-10-04 omar.polo }
1130 991c5d3c 2018-08-13 omar.polo
1131 1d13acf5 2018-10-04 omar.polo return ADD_CHAR;
1132 1d13acf5 2018-10-04 omar.polo }
1133 991c5d3c 2018-08-13 omar.polo
1134 1d13acf5 2018-10-04 omar.polo void
1135 1d13acf5 2018-10-04 omar.polo confirm(enum state *status, struct rendering *r, struct completions *cs, char **text, int *textlen)
1136 1d13acf5 2018-10-04 omar.polo {
1137 1d13acf5 2018-10-04 omar.polo if ((cs->selected != -1) || (cs->length > 0 && r->first_selected)) {
1138 1d13acf5 2018-10-04 omar.polo /* if there is something selected expand it and return */
1139 1d13acf5 2018-10-04 omar.polo int index = cs->selected == -1 ? 0 : cs->selected;
1140 1d13acf5 2018-10-04 omar.polo struct completion *c = cs->completions;
1141 1d13acf5 2018-10-04 omar.polo char *t;
1142 991c5d3c 2018-08-13 omar.polo
1143 26b541d8 2018-10-04 omar.polo while (1) {
1144 1d13acf5 2018-10-04 omar.polo if (index == 0)
1145 1d13acf5 2018-10-04 omar.polo break;
1146 1d13acf5 2018-10-04 omar.polo c++;
1147 1d13acf5 2018-10-04 omar.polo index--;
1148 1d13acf5 2018-10-04 omar.polo }
1149 991c5d3c 2018-08-13 omar.polo
1150 1d13acf5 2018-10-04 omar.polo t = c->rcompletion;
1151 1d13acf5 2018-10-04 omar.polo free(*text);
1152 1d13acf5 2018-10-04 omar.polo *text = strdup(t);
1153 991c5d3c 2018-08-13 omar.polo
1154 1d13acf5 2018-10-04 omar.polo if (*text == NULL) {
1155 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Memory allocation error\n");
1156 1d13acf5 2018-10-04 omar.polo *status = ERR;
1157 1d13acf5 2018-10-04 omar.polo }
1158 991c5d3c 2018-08-13 omar.polo
1159 1d13acf5 2018-10-04 omar.polo *textlen = strlen(*text);
1160 1d13acf5 2018-10-04 omar.polo return;
1161 1d13acf5 2018-10-04 omar.polo }
1162 1d13acf5 2018-10-04 omar.polo
1163 1d13acf5 2018-10-04 omar.polo if (!r->free_text) /* cannot accept arbitrary text */
1164 1d13acf5 2018-10-04 omar.polo *status = LOOPING;
1165 e9f0b467 2018-06-07 omar.polo }
1166 e9f0b467 2018-06-07 omar.polo
1167 1d13acf5 2018-10-04 omar.polo /* event loop */
1168 1d13acf5 2018-10-04 omar.polo enum state
1169 1d13acf5 2018-10-04 omar.polo loop(struct rendering *r, char **text, int *textlen, struct completions *cs, char **lines, char **vlines)
1170 1d13acf5 2018-10-04 omar.polo {
1171 1d13acf5 2018-10-04 omar.polo enum state status = LOOPING;
1172 3518f203 2018-07-21 omar.polo
1173 1d13acf5 2018-10-04 omar.polo while (status == LOOPING) {
1174 1d13acf5 2018-10-04 omar.polo XEvent e;
1175 1d13acf5 2018-10-04 omar.polo XNextEvent(r->d, &e);
1176 1ef91f4e 2018-07-03 omar.polo
1177 1d13acf5 2018-10-04 omar.polo if (XFilterEvent(&e, r->w))
1178 1d13acf5 2018-10-04 omar.polo continue;
1179 e9f0b467 2018-06-07 omar.polo
1180 1d13acf5 2018-10-04 omar.polo switch (e.type) {
1181 1d13acf5 2018-10-04 omar.polo case KeymapNotify:
1182 1d13acf5 2018-10-04 omar.polo XRefreshKeyboardMapping(&e.xmapping);
1183 1d13acf5 2018-10-04 omar.polo break;
1184 844addbb 2018-07-15 omar.polo
1185 1d13acf5 2018-10-04 omar.polo case FocusIn:
1186 1d13acf5 2018-10-04 omar.polo /* Re-grab focus */
1187 1d13acf5 2018-10-04 omar.polo if (e.xfocus.window != r->w)
1188 1d13acf5 2018-10-04 omar.polo grabfocus(r->d, r->w);
1189 1d13acf5 2018-10-04 omar.polo break;
1190 3518f203 2018-07-21 omar.polo
1191 1d13acf5 2018-10-04 omar.polo case VisibilityNotify:
1192 1d13acf5 2018-10-04 omar.polo if (e.xvisibility.state != VisibilityUnobscured)
1193 1d13acf5 2018-10-04 omar.polo XRaiseWindow(r->d, r->w);
1194 1d13acf5 2018-10-04 omar.polo break;
1195 991c5d3c 2018-08-13 omar.polo
1196 1d13acf5 2018-10-04 omar.polo case MapNotify:
1197 1d13acf5 2018-10-04 omar.polo get_wh(r->d, &r->w, &r->width, &r->height);
1198 1d13acf5 2018-10-04 omar.polo draw(r, *text, cs);
1199 1d13acf5 2018-10-04 omar.polo break;
1200 e9f0b467 2018-06-07 omar.polo
1201 1d13acf5 2018-10-04 omar.polo case KeyPress: {
1202 1d13acf5 2018-10-04 omar.polo XKeyPressedEvent *ev = (XKeyPressedEvent*)&e;
1203 1d13acf5 2018-10-04 omar.polo char *input;
1204 1a4491e5 2018-09-19 omar.polo
1205 1d13acf5 2018-10-04 omar.polo switch (parse_event(r->d, ev, r->xic, &input)) {
1206 1d13acf5 2018-10-04 omar.polo case EXIT:
1207 1d13acf5 2018-10-04 omar.polo status = ERR;
1208 1d13acf5 2018-10-04 omar.polo break;
1209 f5e234d6 2018-05-18 omar.polo
1210 1d13acf5 2018-10-04 omar.polo case CONFIRM: {
1211 1d13acf5 2018-10-04 omar.polo status = OK;
1212 1d13acf5 2018-10-04 omar.polo confirm(&status, r, cs, text, textlen);
1213 1d13acf5 2018-10-04 omar.polo break;
1214 1d13acf5 2018-10-04 omar.polo }
1215 3518f203 2018-07-21 omar.polo
1216 1d13acf5 2018-10-04 omar.polo case CONFIRM_CONTINUE: {
1217 1d13acf5 2018-10-04 omar.polo status = OK_LOOP;
1218 1d13acf5 2018-10-04 omar.polo confirm(&status, r, cs, text, textlen);
1219 1d13acf5 2018-10-04 omar.polo break;
1220 1d13acf5 2018-10-04 omar.polo }
1221 f5e234d6 2018-05-18 omar.polo
1222 1d13acf5 2018-10-04 omar.polo case PREV_COMPL: {
1223 26b541d8 2018-10-04 omar.polo complete(cs, r->first_selected, 1, text, textlen, &status);
1224 1d13acf5 2018-10-04 omar.polo r->offset = cs->selected;
1225 1d13acf5 2018-10-04 omar.polo break;
1226 1d13acf5 2018-10-04 omar.polo }
1227 f5e234d6 2018-05-18 omar.polo
1228 1d13acf5 2018-10-04 omar.polo case NEXT_COMPL: {
1229 26b541d8 2018-10-04 omar.polo complete(cs, r->first_selected, 0, text, textlen, &status);
1230 1d13acf5 2018-10-04 omar.polo r->offset = cs->selected;
1231 1d13acf5 2018-10-04 omar.polo break;
1232 1d13acf5 2018-10-04 omar.polo }
1233 f5e234d6 2018-05-18 omar.polo
1234 1d13acf5 2018-10-04 omar.polo case DEL_CHAR:
1235 1d13acf5 2018-10-04 omar.polo popc(*text);
1236 1d13acf5 2018-10-04 omar.polo update_completions(cs, *text, lines, vlines, r->first_selected);
1237 1d13acf5 2018-10-04 omar.polo r->offset = 0;
1238 1d13acf5 2018-10-04 omar.polo break;
1239 f5e234d6 2018-05-18 omar.polo
1240 1d13acf5 2018-10-04 omar.polo case DEL_WORD: {
1241 1d13acf5 2018-10-04 omar.polo popw(*text);
1242 1d13acf5 2018-10-04 omar.polo update_completions(cs, *text, lines, vlines, r->first_selected);
1243 1d13acf5 2018-10-04 omar.polo break;
1244 1d13acf5 2018-10-04 omar.polo }
1245 f5e234d6 2018-05-18 omar.polo
1246 1d13acf5 2018-10-04 omar.polo case DEL_LINE: {
1247 1d13acf5 2018-10-04 omar.polo int i;
1248 1d13acf5 2018-10-04 omar.polo for (i = 0; i < *textlen; ++i)
1249 1d13acf5 2018-10-04 omar.polo *(*text + i) = 0;
1250 1d13acf5 2018-10-04 omar.polo update_completions(cs, *text, lines, vlines, r->first_selected);
1251 1d13acf5 2018-10-04 omar.polo r->offset = 0;
1252 1d13acf5 2018-10-04 omar.polo break;
1253 1d13acf5 2018-10-04 omar.polo }
1254 e5186d6b 2018-05-26 omar.polo
1255 1d13acf5 2018-10-04 omar.polo case ADD_CHAR: {
1256 1d13acf5 2018-10-04 omar.polo int str_len, i;
1257 42c3f269 2018-07-08 omar.polo
1258 1d13acf5 2018-10-04 omar.polo str_len = strlen(input);
1259 8758854a 2018-05-20 omar.polo
1260 1d13acf5 2018-10-04 omar.polo /*
1261 1d13acf5 2018-10-04 omar.polo * sometimes a strange key is pressed
1262 1d13acf5 2018-10-04 omar.polo * i.e. ctrl alone), so input will be
1263 1d13acf5 2018-10-04 omar.polo * empty. Don't need to update
1264 1d13acf5 2018-10-04 omar.polo * completion in that case
1265 1d13acf5 2018-10-04 omar.polo */
1266 1d13acf5 2018-10-04 omar.polo if (str_len == 0)
1267 1d13acf5 2018-10-04 omar.polo break;
1268 f5e234d6 2018-05-18 omar.polo
1269 1d13acf5 2018-10-04 omar.polo for (i = 0; i < str_len; ++i) {
1270 1d13acf5 2018-10-04 omar.polo *textlen = pushc(text, *textlen, input[i]);
1271 1d13acf5 2018-10-04 omar.polo if (*textlen == -1) {
1272 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Memory allocation error\n");
1273 1d13acf5 2018-10-04 omar.polo status = ERR;
1274 1d13acf5 2018-10-04 omar.polo break;
1275 1d13acf5 2018-10-04 omar.polo }
1276 1d13acf5 2018-10-04 omar.polo }
1277 f5e234d6 2018-05-18 omar.polo
1278 1d13acf5 2018-10-04 omar.polo if (status != ERR) {
1279 1d13acf5 2018-10-04 omar.polo update_completions(cs, *text, lines, vlines, r->first_selected);
1280 1d13acf5 2018-10-04 omar.polo free(input);
1281 1d13acf5 2018-10-04 omar.polo }
1282 f5e234d6 2018-05-18 omar.polo
1283 1d13acf5 2018-10-04 omar.polo r->offset = 0;
1284 1d13acf5 2018-10-04 omar.polo break;
1285 1d13acf5 2018-10-04 omar.polo }
1286 f5e234d6 2018-05-18 omar.polo
1287 1d13acf5 2018-10-04 omar.polo case TOGGLE_FIRST_SELECTED:
1288 1d13acf5 2018-10-04 omar.polo r->first_selected = !r->first_selected;
1289 1d13acf5 2018-10-04 omar.polo if (r->first_selected && cs->selected < 0)
1290 1d13acf5 2018-10-04 omar.polo cs->selected = 0;
1291 1d13acf5 2018-10-04 omar.polo if (!r->first_selected && cs->selected == 0)
1292 1d13acf5 2018-10-04 omar.polo cs->selected = -1;
1293 1d13acf5 2018-10-04 omar.polo break;
1294 1d13acf5 2018-10-04 omar.polo }
1295 1d13acf5 2018-10-04 omar.polo }
1296 844addbb 2018-07-15 omar.polo
1297 1d13acf5 2018-10-04 omar.polo case ButtonPress: {
1298 1d13acf5 2018-10-04 omar.polo XButtonPressedEvent *ev = (XButtonPressedEvent*)&e;
1299 1d13acf5 2018-10-04 omar.polo /* if (ev->button == Button1) { /\* click *\/ */
1300 1d13acf5 2018-10-04 omar.polo /* int x = ev->x - r.border_w; */
1301 1d13acf5 2018-10-04 omar.polo /* int y = ev->y - r.border_n; */
1302 1d13acf5 2018-10-04 omar.polo /* fprintf(stderr, "Click @ (%d, %d)\n", x, y); */
1303 1d13acf5 2018-10-04 omar.polo /* } */
1304 f5e234d6 2018-05-18 omar.polo
1305 1d13acf5 2018-10-04 omar.polo if (ev->button == Button4) /* scroll up */
1306 1d13acf5 2018-10-04 omar.polo r->offset = MAX((ssize_t)r->offset - 1, 0);
1307 7ca8829b 2018-05-21 omar.polo
1308 1d13acf5 2018-10-04 omar.polo if (ev->button == Button5) /* scroll down */
1309 1d13acf5 2018-10-04 omar.polo r->offset = MIN(r->offset + 1, cs->length - 1);
1310 f5e234d6 2018-05-18 omar.polo
1311 1d13acf5 2018-10-04 omar.polo break;
1312 1d13acf5 2018-10-04 omar.polo }
1313 1d13acf5 2018-10-04 omar.polo }
1314 f5e234d6 2018-05-18 omar.polo
1315 1d13acf5 2018-10-04 omar.polo draw(r, *text, cs);
1316 1d13acf5 2018-10-04 omar.polo }
1317 6bb186a7 2018-09-13 omar.polo
1318 1d13acf5 2018-10-04 omar.polo return status;
1319 1d13acf5 2018-10-04 omar.polo }
1320 6bb186a7 2018-09-13 omar.polo
1321 1d13acf5 2018-10-04 omar.polo int
1322 1d13acf5 2018-10-04 omar.polo load_font(struct rendering *r, const char *fontname)
1323 1d13acf5 2018-10-04 omar.polo {
1324 1d13acf5 2018-10-04 omar.polo #ifdef USE_XFT
1325 1d13acf5 2018-10-04 omar.polo r->font = XftFontOpenName(r->d, DefaultScreen(r->d), fontname);
1326 1d13acf5 2018-10-04 omar.polo return 0;
1327 1d13acf5 2018-10-04 omar.polo #else
1328 1d13acf5 2018-10-04 omar.polo char **missing_charset_list;
1329 1d13acf5 2018-10-04 omar.polo int missing_charset_count;
1330 6bb186a7 2018-09-13 omar.polo
1331 1d13acf5 2018-10-04 omar.polo r->font = XCreateFontSet(r->d, fontname, &missing_charset_list, &missing_charset_count, NULL);
1332 1d13acf5 2018-10-04 omar.polo if (r->font != NULL)
1333 1d13acf5 2018-10-04 omar.polo return 0;
1334 6bb186a7 2018-09-13 omar.polo
1335 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Unable to load the font(s) %s\n", fontname);
1336 36a15a9f 2018-05-19 omar.polo
1337 1d13acf5 2018-10-04 omar.polo if (!strcmp(fontname, default_fontname))
1338 1d13acf5 2018-10-04 omar.polo return -1;
1339 f5e234d6 2018-05-18 omar.polo
1340 1d13acf5 2018-10-04 omar.polo return load_font(r, default_fontname);
1341 1d13acf5 2018-10-04 omar.polo #endif
1342 1d13acf5 2018-10-04 omar.polo }
1343 36a15a9f 2018-05-19 omar.polo
1344 1d13acf5 2018-10-04 omar.polo void
1345 4f769efa 2018-10-06 omar.polo xim_init(struct rendering *r, XrmDatabase *xdb)
1346 4f769efa 2018-10-06 omar.polo {
1347 4f769efa 2018-10-06 omar.polo XIMStyle best_match_style;
1348 4f769efa 2018-10-06 omar.polo XIMStyles *xis;
1349 4f769efa 2018-10-06 omar.polo int i;
1350 4f769efa 2018-10-06 omar.polo
1351 4f769efa 2018-10-06 omar.polo /* Open the X input method */
1352 43e30577 2018-10-20 omar.polo r->xim = XOpenIM(r->d, *xdb, resname, resclass);
1353 43e30577 2018-10-20 omar.polo check_allocation(r->xim);
1354 4f769efa 2018-10-06 omar.polo
1355 43e30577 2018-10-20 omar.polo if (XGetIMValues(r->xim, XNQueryInputStyle, &xis, NULL) || !xis) {
1356 4f769efa 2018-10-06 omar.polo fprintf(stderr, "Input Styles could not be retrieved\n");
1357 4f769efa 2018-10-06 omar.polo exit(EX_UNAVAILABLE);
1358 4f769efa 2018-10-06 omar.polo }
1359 4f769efa 2018-10-06 omar.polo
1360 4f769efa 2018-10-06 omar.polo best_match_style = 0;
1361 4f769efa 2018-10-06 omar.polo for (i = 0; i < xis->count_styles; ++i) {
1362 4f769efa 2018-10-06 omar.polo XIMStyle ts = xis->supported_styles[i];
1363 4f769efa 2018-10-06 omar.polo if (ts == (XIMPreeditNothing | XIMStatusNothing)) {
1364 4f769efa 2018-10-06 omar.polo best_match_style = ts;
1365 4f769efa 2018-10-06 omar.polo break;
1366 4f769efa 2018-10-06 omar.polo }
1367 4f769efa 2018-10-06 omar.polo }
1368 4f769efa 2018-10-06 omar.polo XFree(xis);
1369 4f769efa 2018-10-06 omar.polo
1370 4f769efa 2018-10-06 omar.polo if (!best_match_style)
1371 4f769efa 2018-10-06 omar.polo fprintf(stderr, "No matching input style could be determined\n");
1372 4f769efa 2018-10-06 omar.polo
1373 43e30577 2018-10-20 omar.polo r->xic = XCreateIC(r->xim, XNInputStyle, best_match_style, XNClientWindow, r->w, XNFocusWindow, r->w, NULL);
1374 4f769efa 2018-10-06 omar.polo check_allocation(r->xic);
1375 4f769efa 2018-10-06 omar.polo }
1376 4f769efa 2018-10-06 omar.polo
1377 4f769efa 2018-10-06 omar.polo void
1378 1f6422bc 2018-10-20 omar.polo create_window(struct rendering *r, Window parent_window, Colormap cmap, XVisualInfo vinfo, int x, int y, int ox, int oy, unsigned long background_pixel)
1379 4f769efa 2018-10-06 omar.polo {
1380 4f769efa 2018-10-06 omar.polo XSetWindowAttributes attr;
1381 4f769efa 2018-10-06 omar.polo
1382 4f769efa 2018-10-06 omar.polo /* Create the window */
1383 4f769efa 2018-10-06 omar.polo attr.colormap = cmap;
1384 4f769efa 2018-10-06 omar.polo attr.override_redirect = 1;
1385 4f769efa 2018-10-06 omar.polo attr.border_pixel = 0;
1386 1f6422bc 2018-10-20 omar.polo attr.background_pixel = background_pixel;
1387 43e30577 2018-10-20 omar.polo attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeymapStateMask | ButtonPress | VisibilityChangeMask;
1388 4f769efa 2018-10-06 omar.polo
1389 4f769efa 2018-10-06 omar.polo r->w = XCreateWindow(r->d,
1390 4f769efa 2018-10-06 omar.polo parent_window,
1391 4f769efa 2018-10-06 omar.polo x + ox, y + oy,
1392 4f769efa 2018-10-06 omar.polo r->width, r->height,
1393 4f769efa 2018-10-06 omar.polo 0,
1394 4f769efa 2018-10-06 omar.polo vinfo.depth,
1395 4f769efa 2018-10-06 omar.polo InputOutput,
1396 4f769efa 2018-10-06 omar.polo vinfo.visual,
1397 4f769efa 2018-10-06 omar.polo CWBorderPixel | CWBackPixel | CWColormap | CWEventMask | CWOverrideRedirect,
1398 4f769efa 2018-10-06 omar.polo &attr);
1399 4f769efa 2018-10-06 omar.polo }
1400 4f769efa 2018-10-06 omar.polo
1401 4f769efa 2018-10-06 omar.polo void
1402 aed48307 2018-10-06 omar.polo ps1extents(struct rendering *r)
1403 aed48307 2018-10-06 omar.polo {
1404 aed48307 2018-10-06 omar.polo char *dup;
1405 aed48307 2018-10-06 omar.polo dup = strdupn(r->ps1);
1406 aed48307 2018-10-06 omar.polo text_extents(dup == NULL ? r->ps1 : dup, r->ps1len, r, &r->ps1w, &r->ps1h);
1407 aed48307 2018-10-06 omar.polo free(dup);
1408 aed48307 2018-10-06 omar.polo }
1409 aed48307 2018-10-06 omar.polo
1410 aed48307 2018-10-06 omar.polo void
1411 1d13acf5 2018-10-04 omar.polo usage(char *prgname)
1412 1d13acf5 2018-10-04 omar.polo {
1413 df29e05e 2018-10-17 omar.polo fprintf(stderr,
1414 df29e05e 2018-10-17 omar.polo "%s [-Aahmv] [-B colors] [-b size] [-C color] [-c color]\n"
1415 df29e05e 2018-10-17 omar.polo " [-d separator] [-e window] [-f font] [-G color] [-g size]\n"
1416 df29e05e 2018-10-17 omar.polo " [-H height] [-I color] [-i size] [-J color] [-j size] [-l layout]\n"
1417 df29e05e 2018-10-17 omar.polo " [-P padding] [-p prompt] [-S color] [-s color] [-T color]\n"
1418 df29e05e 2018-10-17 omar.polo " [-t color] [-W width] [-x coord] [-y coord]\n", prgname);
1419 1d13acf5 2018-10-04 omar.polo }
1420 f5e234d6 2018-05-18 omar.polo
1421 1d13acf5 2018-10-04 omar.polo int
1422 1d13acf5 2018-10-04 omar.polo main(int argc, char **argv)
1423 1d13acf5 2018-10-04 omar.polo {
1424 4f769efa 2018-10-06 omar.polo struct completions *cs;
1425 4f769efa 2018-10-06 omar.polo struct rendering r;
1426 4f769efa 2018-10-06 omar.polo XVisualInfo vinfo;
1427 4f769efa 2018-10-06 omar.polo Colormap cmap;
1428 4f769efa 2018-10-06 omar.polo size_t nlines, i;
1429 4f769efa 2018-10-06 omar.polo Window parent_window;
1430 4f769efa 2018-10-06 omar.polo XrmDatabase xdb;
1431 4c0d79a0 2018-10-09 omar.polo unsigned long fgs[3], bgs[3]; /* prompt, compl, compl_highlighted */
1432 df29e05e 2018-10-17 omar.polo unsigned long borders_bg[4], p_borders_bg[4], c_borders_bg[4], ch_borders_bg[4]; /* N E S W */
1433 4f769efa 2018-10-06 omar.polo enum state status;
1434 4f769efa 2018-10-06 omar.polo int ch;
1435 4f769efa 2018-10-06 omar.polo int offset_x, offset_y, x, y;
1436 4f769efa 2018-10-06 omar.polo int textlen, d_width, d_height;
1437 4f769efa 2018-10-06 omar.polo short embed;
1438 4f769efa 2018-10-06 omar.polo char *sep, *parent_window_id;
1439 4f769efa 2018-10-06 omar.polo char **lines, *buf, **vlines;
1440 4f769efa 2018-10-06 omar.polo char *fontname, *text, *xrm;
1441 f5e234d6 2018-05-18 omar.polo
1442 1d13acf5 2018-10-04 omar.polo #ifdef __OpenBSD__
1443 1d13acf5 2018-10-04 omar.polo /* stdio & rpath: to read/write stdio/stdout/stderr */
1444 1d13acf5 2018-10-04 omar.polo /* unix: to connect to XOrg */
1445 1d13acf5 2018-10-04 omar.polo pledge("stdio rpath unix", "");
1446 1d13acf5 2018-10-04 omar.polo #endif
1447 f5e234d6 2018-05-18 omar.polo
1448 1d13acf5 2018-10-04 omar.polo sep = NULL;
1449 1d13acf5 2018-10-04 omar.polo parent_window_id = NULL;
1450 f5e234d6 2018-05-18 omar.polo
1451 4f769efa 2018-10-06 omar.polo r.first_selected = 0;
1452 4f769efa 2018-10-06 omar.polo r.free_text = 1;
1453 4f769efa 2018-10-06 omar.polo r.multiple_select = 0;
1454 4f769efa 2018-10-06 omar.polo r.offset = 0;
1455 4f769efa 2018-10-06 omar.polo
1456 1d13acf5 2018-10-04 omar.polo while ((ch = getopt(argc, argv, ARGS)) != -1) {
1457 1d13acf5 2018-10-04 omar.polo switch (ch) {
1458 1d13acf5 2018-10-04 omar.polo case 'h': /* help */
1459 1d13acf5 2018-10-04 omar.polo usage(*argv);
1460 1d13acf5 2018-10-04 omar.polo return 0;
1461 1d13acf5 2018-10-04 omar.polo case 'v': /* version */
1462 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "%s version: %s\n", *argv, VERSION);
1463 1d13acf5 2018-10-04 omar.polo return 0;
1464 1d13acf5 2018-10-04 omar.polo case 'e': /* embed */
1465 1d13acf5 2018-10-04 omar.polo parent_window_id = strdup(optarg);
1466 1d13acf5 2018-10-04 omar.polo check_allocation(parent_window_id);
1467 1d13acf5 2018-10-04 omar.polo break;
1468 4c0d79a0 2018-10-09 omar.polo case 'd':
1469 1d13acf5 2018-10-04 omar.polo sep = strdup(optarg);
1470 1d13acf5 2018-10-04 omar.polo check_allocation(sep);
1471 4c0d79a0 2018-10-09 omar.polo case 'A':
1472 4f769efa 2018-10-06 omar.polo r.free_text = 0;
1473 1d13acf5 2018-10-04 omar.polo break;
1474 4c0d79a0 2018-10-09 omar.polo case 'm':
1475 4f769efa 2018-10-06 omar.polo r.multiple_select = 1;
1476 1d13acf5 2018-10-04 omar.polo break;
1477 1d13acf5 2018-10-04 omar.polo default:
1478 1d13acf5 2018-10-04 omar.polo break;
1479 1d13acf5 2018-10-04 omar.polo }
1480 1d13acf5 2018-10-04 omar.polo }
1481 e5186d6b 2018-05-26 omar.polo
1482 1d13acf5 2018-10-04 omar.polo /* Read the completions */
1483 1d13acf5 2018-10-04 omar.polo lines = NULL;
1484 1d13acf5 2018-10-04 omar.polo buf = NULL;
1485 1d13acf5 2018-10-04 omar.polo nlines = readlines(&lines, &buf);
1486 42c3f269 2018-07-08 omar.polo
1487 1d13acf5 2018-10-04 omar.polo vlines = NULL;
1488 1d13acf5 2018-10-04 omar.polo if (sep != NULL) {
1489 1d13acf5 2018-10-04 omar.polo int l;
1490 1d13acf5 2018-10-04 omar.polo l = strlen(sep);
1491 1d13acf5 2018-10-04 omar.polo vlines = calloc(nlines, sizeof(char*));
1492 1d13acf5 2018-10-04 omar.polo check_allocation(vlines);
1493 f5e234d6 2018-05-18 omar.polo
1494 1d13acf5 2018-10-04 omar.polo for (i = 0; i < nlines; i++) {
1495 1d13acf5 2018-10-04 omar.polo char *t;
1496 1d13acf5 2018-10-04 omar.polo t = strstr(lines[i], sep);
1497 1d13acf5 2018-10-04 omar.polo if (t == NULL)
1498 1d13acf5 2018-10-04 omar.polo vlines[i] = lines[i];
1499 1d13acf5 2018-10-04 omar.polo else
1500 1d13acf5 2018-10-04 omar.polo vlines[i] = t + l;
1501 1d13acf5 2018-10-04 omar.polo }
1502 1d13acf5 2018-10-04 omar.polo }
1503 f5e234d6 2018-05-18 omar.polo
1504 1d13acf5 2018-10-04 omar.polo setlocale(LC_ALL, getenv("LANG"));
1505 f5e234d6 2018-05-18 omar.polo
1506 1d13acf5 2018-10-04 omar.polo status = LOOPING;
1507 f5e234d6 2018-05-18 omar.polo
1508 1d13acf5 2018-10-04 omar.polo /* where the monitor start (used only with xinerama) */
1509 1d13acf5 2018-10-04 omar.polo offset_x = offset_y = 0;
1510 f5e234d6 2018-05-18 omar.polo
1511 1d13acf5 2018-10-04 omar.polo /* default width and height */
1512 4f769efa 2018-10-06 omar.polo r.width = 400;
1513 4f769efa 2018-10-06 omar.polo r.height = 20;
1514 f5e234d6 2018-05-18 omar.polo
1515 1d13acf5 2018-10-04 omar.polo /* default position on the screen */
1516 1d13acf5 2018-10-04 omar.polo x = y = 0;
1517 42c3f269 2018-07-08 omar.polo
1518 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i) {
1519 df29e05e 2018-10-17 omar.polo /* default paddings */
1520 df29e05e 2018-10-17 omar.polo r.p_padding[i] = 10;
1521 df29e05e 2018-10-17 omar.polo r.c_padding[i] = 10;
1522 df29e05e 2018-10-17 omar.polo r.ch_padding[i] = 10;
1523 f5e234d6 2018-05-18 omar.polo
1524 df29e05e 2018-10-17 omar.polo /* default borders */
1525 df29e05e 2018-10-17 omar.polo r.borders[i] = 0;
1526 df29e05e 2018-10-17 omar.polo r.p_borders[i] = 0;
1527 df29e05e 2018-10-17 omar.polo r.c_borders[i] = 0;
1528 df29e05e 2018-10-17 omar.polo r.ch_borders[i] = 0;
1529 df29e05e 2018-10-17 omar.polo }
1530 ae801529 2018-07-13 omar.polo
1531 1d13acf5 2018-10-04 omar.polo /* the prompt. We duplicate the string so later is easy to
1532 1d13acf5 2018-10-04 omar.polo * free (in the case it's been overwritten by the user) */
1533 4f769efa 2018-10-06 omar.polo r.ps1 = strdup("$ ");
1534 4f769efa 2018-10-06 omar.polo check_allocation(r.ps1);
1535 ae801529 2018-07-13 omar.polo
1536 1d13acf5 2018-10-04 omar.polo /* same for the font name */
1537 1d13acf5 2018-10-04 omar.polo fontname = strdup(default_fontname);
1538 1d13acf5 2018-10-04 omar.polo check_allocation(fontname);
1539 f5e234d6 2018-05-18 omar.polo
1540 1d13acf5 2018-10-04 omar.polo textlen = 10;
1541 1d13acf5 2018-10-04 omar.polo text = malloc(textlen * sizeof(char));
1542 1d13acf5 2018-10-04 omar.polo check_allocation(text);
1543 f5e234d6 2018-05-18 omar.polo
1544 1d13acf5 2018-10-04 omar.polo /* struct completions *cs = filter(text, lines); */
1545 1d13acf5 2018-10-04 omar.polo cs = compls_new(nlines);
1546 1d13acf5 2018-10-04 omar.polo check_allocation(cs);
1547 f5e234d6 2018-05-18 omar.polo
1548 1d13acf5 2018-10-04 omar.polo /* start talking to xorg */
1549 4f769efa 2018-10-06 omar.polo r.d = XOpenDisplay(NULL);
1550 4f769efa 2018-10-06 omar.polo if (r.d == NULL) {
1551 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Could not open display!\n");
1552 1d13acf5 2018-10-04 omar.polo return EX_UNAVAILABLE;
1553 1d13acf5 2018-10-04 omar.polo }
1554 f5e234d6 2018-05-18 omar.polo
1555 26b541d8 2018-10-04 omar.polo embed = 1;
1556 1d13acf5 2018-10-04 omar.polo if (! (parent_window_id && (parent_window = strtol(parent_window_id, NULL, 0)))) {
1557 4f769efa 2018-10-06 omar.polo parent_window = DefaultRootWindow(r.d);
1558 26b541d8 2018-10-04 omar.polo embed = 0;
1559 1d13acf5 2018-10-04 omar.polo }
1560 f5e234d6 2018-05-18 omar.polo
1561 1d13acf5 2018-10-04 omar.polo /* get display size */
1562 4f769efa 2018-10-06 omar.polo get_wh(r.d, &parent_window, &d_width, &d_height);
1563 f5e234d6 2018-05-18 omar.polo
1564 1d13acf5 2018-10-04 omar.polo #ifdef USE_XINERAMA
1565 4f769efa 2018-10-06 omar.polo if (!embed && XineramaIsActive(r.d)) { /* find the mice */
1566 1d13acf5 2018-10-04 omar.polo XineramaScreenInfo *info;
1567 4f769efa 2018-10-06 omar.polo Window rr;
1568 1d13acf5 2018-10-04 omar.polo Window root;
1569 1d13acf5 2018-10-04 omar.polo int number_of_screens, monitors, i;
1570 1d13acf5 2018-10-04 omar.polo int root_x, root_y, win_x, win_y;
1571 1d13acf5 2018-10-04 omar.polo unsigned int mask;
1572 26b541d8 2018-10-04 omar.polo short res;
1573 f5e234d6 2018-05-18 omar.polo
1574 4f769efa 2018-10-06 omar.polo number_of_screens = XScreenCount(r.d);
1575 1d13acf5 2018-10-04 omar.polo for (i = 0; i < number_of_screens; ++i) {
1576 4f769efa 2018-10-06 omar.polo root = XRootWindow(r.d, i);
1577 4f769efa 2018-10-06 omar.polo res = XQueryPointer(r.d, root, &rr, &rr, &root_x, &root_y, &win_x, &win_y, &mask);
1578 4f769efa 2018-10-06 omar.polo if (res)
1579 4f769efa 2018-10-06 omar.polo break;
1580 1d13acf5 2018-10-04 omar.polo }
1581 4f769efa 2018-10-06 omar.polo
1582 1d13acf5 2018-10-04 omar.polo if (!res) {
1583 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "No mouse found.\n");
1584 1d13acf5 2018-10-04 omar.polo root_x = 0;
1585 1d13acf5 2018-10-04 omar.polo root_y = 0;
1586 1d13acf5 2018-10-04 omar.polo }
1587 f5e234d6 2018-05-18 omar.polo
1588 26b541d8 2018-10-04 omar.polo /* Now find in which monitor the mice is */
1589 4f769efa 2018-10-06 omar.polo info = XineramaQueryScreens(r.d, &monitors);
1590 1d13acf5 2018-10-04 omar.polo if (info) {
1591 1d13acf5 2018-10-04 omar.polo for (i = 0; i < monitors; ++i) {
1592 1d13acf5 2018-10-04 omar.polo if (info[i].x_org <= root_x && root_x <= (info[i].x_org + info[i].width)
1593 1d13acf5 2018-10-04 omar.polo && info[i].y_org <= root_y && root_y <= (info[i].y_org + info[i].height)) {
1594 1d13acf5 2018-10-04 omar.polo offset_x = info[i].x_org;
1595 1d13acf5 2018-10-04 omar.polo offset_y = info[i].y_org;
1596 1d13acf5 2018-10-04 omar.polo d_width = info[i].width;
1597 1d13acf5 2018-10-04 omar.polo d_height = info[i].height;
1598 1d13acf5 2018-10-04 omar.polo break;
1599 1d13acf5 2018-10-04 omar.polo }
1600 1d13acf5 2018-10-04 omar.polo }
1601 1d13acf5 2018-10-04 omar.polo }
1602 1d13acf5 2018-10-04 omar.polo XFree(info);
1603 1d13acf5 2018-10-04 omar.polo }
1604 42c3f269 2018-07-08 omar.polo #endif
1605 f5e234d6 2018-05-18 omar.polo
1606 4f769efa 2018-10-06 omar.polo XMatchVisualInfo(r.d, DefaultScreen(r.d), 32, TrueColor, &vinfo);
1607 4f769efa 2018-10-06 omar.polo cmap = XCreateColormap(r.d, XDefaultRootWindow(r.d), vinfo.visual, AllocNone);
1608 c9a3bfaa 2018-05-21 omar.polo
1609 4c0d79a0 2018-10-09 omar.polo fgs[0] = fgs[1] = parse_color("#fff", NULL);
1610 4c0d79a0 2018-10-09 omar.polo fgs[2] = parse_color("#000", NULL);
1611 c9a3bfaa 2018-05-21 omar.polo
1612 4c0d79a0 2018-10-09 omar.polo bgs[0] = bgs[1] = parse_color("#000", NULL);
1613 4c0d79a0 2018-10-09 omar.polo bgs[2] = parse_color("#fff", NULL);
1614 7ca8829b 2018-05-21 omar.polo
1615 4c0d79a0 2018-10-09 omar.polo borders_bg[0] = borders_bg[1] = borders_bg[2] = borders_bg[3] = parse_color("#000", NULL);
1616 6bb186a7 2018-09-13 omar.polo
1617 df29e05e 2018-10-17 omar.polo p_borders_bg[0] = p_borders_bg[1] = p_borders_bg[2] = p_borders_bg[3] = parse_color("#000", NULL);
1618 df29e05e 2018-10-17 omar.polo c_borders_bg[0] = c_borders_bg[1] = c_borders_bg[2] = c_borders_bg[3] = parse_color("#000", NULL);
1619 df29e05e 2018-10-17 omar.polo ch_borders_bg[0] = ch_borders_bg[1] = ch_borders_bg[2] = ch_borders_bg[3] = parse_color("#000", NULL);
1620 df29e05e 2018-10-17 omar.polo
1621 4f769efa 2018-10-06 omar.polo r.horizontal_layout = 1;
1622 6bb186a7 2018-09-13 omar.polo
1623 1d13acf5 2018-10-04 omar.polo /* Read the resources */
1624 1d13acf5 2018-10-04 omar.polo XrmInitialize();
1625 4f769efa 2018-10-06 omar.polo xrm = XResourceManagerString(r.d);
1626 1d13acf5 2018-10-04 omar.polo xdb = NULL;
1627 1d13acf5 2018-10-04 omar.polo if (xrm != NULL) {
1628 1d13acf5 2018-10-04 omar.polo XrmValue value;
1629 1d13acf5 2018-10-04 omar.polo char *datatype[20];
1630 1d13acf5 2018-10-04 omar.polo
1631 1d13acf5 2018-10-04 omar.polo xdb = XrmGetStringDatabase(xrm);
1632 1d13acf5 2018-10-04 omar.polo
1633 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.font", "*", datatype, &value) == 1) {
1634 1d13acf5 2018-10-04 omar.polo free(fontname);
1635 1d13acf5 2018-10-04 omar.polo fontname = strdup(value.addr);
1636 1d13acf5 2018-10-04 omar.polo check_allocation(fontname);
1637 1d13acf5 2018-10-04 omar.polo } else {
1638 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "no font defined, using %s\n", fontname);
1639 1d13acf5 2018-10-04 omar.polo }
1640 1d13acf5 2018-10-04 omar.polo
1641 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.layout", "*", datatype, &value) == 1)
1642 4f769efa 2018-10-06 omar.polo r.horizontal_layout = !strcmp(value.addr, "horizontal");
1643 1d13acf5 2018-10-04 omar.polo else
1644 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "no layout defined, using horizontal\n");
1645 1d13acf5 2018-10-04 omar.polo
1646 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.prompt", "*", datatype, &value) == 1) {
1647 4f769efa 2018-10-06 omar.polo free(r.ps1);
1648 4f769efa 2018-10-06 omar.polo r.ps1 = normalize_str(value.addr);
1649 1d13acf5 2018-10-04 omar.polo } else {
1650 4f769efa 2018-10-06 omar.polo fprintf(stderr, "no prompt defined, using \"%s\" as default\n", r.ps1);
1651 1d13acf5 2018-10-04 omar.polo }
1652 1d13acf5 2018-10-04 omar.polo
1653 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.prompt.border.size", "*", datatype, &value) == 1) {
1654 df29e05e 2018-10-17 omar.polo char **sizes;
1655 df29e05e 2018-10-17 omar.polo sizes = parse_csslike(value.addr);
1656 df29e05e 2018-10-17 omar.polo if (sizes != NULL)
1657 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1658 df29e05e 2018-10-17 omar.polo r.p_borders[i] = parse_integer(sizes[i], 0);
1659 df29e05e 2018-10-17 omar.polo else
1660 df29e05e 2018-10-17 omar.polo fprintf(stderr, "error while parsing MyMenu.prompt.border.size");
1661 df29e05e 2018-10-17 omar.polo }
1662 df29e05e 2018-10-17 omar.polo
1663 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.prompt.border.color", "*", datatype, &value) == 1) {
1664 df29e05e 2018-10-17 omar.polo char **colors;
1665 df29e05e 2018-10-17 omar.polo colors = parse_csslike(value.addr);
1666 df29e05e 2018-10-17 omar.polo if (colors != NULL)
1667 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1668 df29e05e 2018-10-17 omar.polo p_borders_bg[i] = parse_color(colors[i], "#000");
1669 df29e05e 2018-10-17 omar.polo else
1670 df29e05e 2018-10-17 omar.polo fprintf(stderr, "error while parsing MyMenu.prompt.border.color");
1671 df29e05e 2018-10-17 omar.polo }
1672 df29e05e 2018-10-17 omar.polo
1673 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.prompt.padding", "*", datatype, &value) == 1) {
1674 df29e05e 2018-10-17 omar.polo char **colors;
1675 df29e05e 2018-10-17 omar.polo colors = parse_csslike(value.addr);
1676 df29e05e 2018-10-17 omar.polo if (colors != NULL)
1677 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1678 df29e05e 2018-10-17 omar.polo r.p_padding[i] = parse_integer(colors[i], 0);
1679 df29e05e 2018-10-17 omar.polo else
1680 df29e05e 2018-10-17 omar.polo fprintf(stderr, "error while parsing MyMenu.prompt.padding");
1681 df29e05e 2018-10-17 omar.polo }
1682 df29e05e 2018-10-17 omar.polo
1683 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.width", "*", datatype, &value) == 1)
1684 4f769efa 2018-10-06 omar.polo r.width = parse_int_with_percentage(value.addr, r.width, d_width);
1685 1d13acf5 2018-10-04 omar.polo else
1686 4f769efa 2018-10-06 omar.polo fprintf(stderr, "no width defined, using %d\n", r.width);
1687 1d13acf5 2018-10-04 omar.polo
1688 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.height", "*", datatype, &value) == 1)
1689 4f769efa 2018-10-06 omar.polo r.height = parse_int_with_percentage(value.addr, r.height, d_height);
1690 1d13acf5 2018-10-04 omar.polo else
1691 4f769efa 2018-10-06 omar.polo fprintf(stderr, "no height defined, using %d\n", r.height);
1692 1d13acf5 2018-10-04 omar.polo
1693 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.x", "*", datatype, &value) == 1)
1694 4f769efa 2018-10-06 omar.polo x = parse_int_with_pos(value.addr, x, d_width, r.width);
1695 1d13acf5 2018-10-04 omar.polo
1696 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.y", "*", datatype, &value) == 1)
1697 4f769efa 2018-10-06 omar.polo y = parse_int_with_pos(value.addr, y, d_height, r.height);
1698 1d13acf5 2018-10-04 omar.polo
1699 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.border.size", "*", datatype, &value) == 1) {
1700 1d13acf5 2018-10-04 omar.polo char **borders;
1701 1d13acf5 2018-10-04 omar.polo borders = parse_csslike(value.addr);
1702 df29e05e 2018-10-17 omar.polo if (borders != NULL)
1703 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1704 4b09b4b1 2018-10-17 omar.polo r.borders[i] = parse_int_with_percentage(borders[i], 0, (i % 2) == 0 ? d_height : d_width);
1705 df29e05e 2018-10-17 omar.polo else
1706 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "error while parsing MyMenu.border.size\n");
1707 df29e05e 2018-10-17 omar.polo }
1708 1d13acf5 2018-10-04 omar.polo
1709 1d13acf5 2018-10-04 omar.polo /* Prompt */
1710 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.prompt.foreground", "*", datatype, &value) == 1)
1711 4c0d79a0 2018-10-09 omar.polo fgs[0] = parse_color(value.addr, "#fff");
1712 1d13acf5 2018-10-04 omar.polo
1713 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.prompt.background", "*", datatype, &value) == 1)
1714 4c0d79a0 2018-10-09 omar.polo bgs[0] = parse_color(value.addr, "#000");
1715 1d13acf5 2018-10-04 omar.polo
1716 1d13acf5 2018-10-04 omar.polo /* Completions */
1717 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.completion.foreground", "*", datatype, &value) == 1)
1718 4c0d79a0 2018-10-09 omar.polo fgs[1] = parse_color(value.addr, "#fff");
1719 1d13acf5 2018-10-04 omar.polo
1720 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.completion.background", "*", datatype, &value) == 1)
1721 4c0d79a0 2018-10-09 omar.polo bgs[1] = parse_color(value.addr, "#000");
1722 1d13acf5 2018-10-04 omar.polo
1723 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.completion.padding", "*", datatype, &value) == 1) {
1724 df29e05e 2018-10-17 omar.polo char **paddings;
1725 df29e05e 2018-10-17 omar.polo paddings = parse_csslike(value.addr);
1726 df29e05e 2018-10-17 omar.polo if (paddings != NULL)
1727 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1728 df29e05e 2018-10-17 omar.polo r.c_padding[i] = parse_integer(paddings[i], 0);
1729 df29e05e 2018-10-17 omar.polo else
1730 df29e05e 2018-10-17 omar.polo fprintf(stderr, "Error while parsing MyMenu.completion.padding");
1731 df29e05e 2018-10-17 omar.polo }
1732 df29e05e 2018-10-17 omar.polo
1733 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.completion.border.size", "*", datatype, &value) == 1) {
1734 df29e05e 2018-10-17 omar.polo char **sizes;
1735 df29e05e 2018-10-17 omar.polo sizes = parse_csslike(value.addr);
1736 df29e05e 2018-10-17 omar.polo if (sizes != NULL)
1737 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1738 df29e05e 2018-10-17 omar.polo r.c_borders[i] = parse_integer(sizes[i], 0);
1739 df29e05e 2018-10-17 omar.polo else
1740 df29e05e 2018-10-17 omar.polo fprintf(stderr, "Error while parsing MyMenu.completion.border.size");
1741 df29e05e 2018-10-17 omar.polo }
1742 df29e05e 2018-10-17 omar.polo
1743 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.completion.border.color", "*", datatype, &value) == 1) {
1744 df29e05e 2018-10-17 omar.polo char **sizes;
1745 df29e05e 2018-10-17 omar.polo sizes = parse_csslike(value.addr);
1746 df29e05e 2018-10-17 omar.polo if (sizes != NULL)
1747 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1748 df29e05e 2018-10-17 omar.polo c_borders_bg[i] = parse_color(sizes[i], "#000");
1749 df29e05e 2018-10-17 omar.polo else
1750 df29e05e 2018-10-17 omar.polo fprintf(stderr, "Error while parsing MyMenu.completion.border.color");
1751 df29e05e 2018-10-17 omar.polo }
1752 df29e05e 2018-10-17 omar.polo
1753 1d13acf5 2018-10-04 omar.polo /* Completion Highlighted */
1754 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.completion_highlighted.foreground", "*", datatype, &value) == 1)
1755 4c0d79a0 2018-10-09 omar.polo fgs[2] = parse_color(value.addr, "#000");
1756 1d13acf5 2018-10-04 omar.polo
1757 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.completion_highlighted.background", "*", datatype, &value) == 1)
1758 4c0d79a0 2018-10-09 omar.polo bgs[2] = parse_color(value.addr, "#fff");
1759 1d13acf5 2018-10-04 omar.polo
1760 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.completion_highlighted.padding", "*", datatype, &value) == 1) {
1761 df29e05e 2018-10-17 omar.polo char **paddings;
1762 df29e05e 2018-10-17 omar.polo paddings = parse_csslike(value.addr);
1763 df29e05e 2018-10-17 omar.polo if (paddings != NULL)
1764 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1765 df29e05e 2018-10-17 omar.polo r.ch_padding[i] = parse_integer(paddings[i], 0);
1766 df29e05e 2018-10-17 omar.polo else
1767 df29e05e 2018-10-17 omar.polo fprintf(stderr, "Error while parsing MyMenu.completion_highlighted.padding");
1768 df29e05e 2018-10-17 omar.polo }
1769 df29e05e 2018-10-17 omar.polo
1770 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.completion_highlighted.border.size", "*", datatype, &value) == 1) {
1771 df29e05e 2018-10-17 omar.polo char **sizes;
1772 df29e05e 2018-10-17 omar.polo sizes = parse_csslike(value.addr);
1773 df29e05e 2018-10-17 omar.polo if (sizes != NULL)
1774 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1775 df29e05e 2018-10-17 omar.polo r.ch_borders[i] = parse_integer(sizes[i], 0);
1776 df29e05e 2018-10-17 omar.polo else
1777 df29e05e 2018-10-17 omar.polo fprintf(stderr, "Error while parsing MyMenu.completion_highlighted.border.size");
1778 df29e05e 2018-10-17 omar.polo }
1779 df29e05e 2018-10-17 omar.polo
1780 df29e05e 2018-10-17 omar.polo if (XrmGetResource(xdb, "MyMenu.completion_highlighted.border.color", "*", datatype, &value) == 1) {
1781 df29e05e 2018-10-17 omar.polo char **colors;
1782 df29e05e 2018-10-17 omar.polo colors = parse_csslike(value.addr);
1783 df29e05e 2018-10-17 omar.polo if (colors != NULL)
1784 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1785 df29e05e 2018-10-17 omar.polo ch_borders_bg[i] = parse_color(colors[i], "#000");
1786 df29e05e 2018-10-17 omar.polo else
1787 df29e05e 2018-10-17 omar.polo fprintf(stderr, "Error while parsing MyMenu.completion_highlighted.border.color");
1788 df29e05e 2018-10-17 omar.polo }
1789 df29e05e 2018-10-17 omar.polo
1790 26b541d8 2018-10-04 omar.polo /* Border */
1791 26b541d8 2018-10-04 omar.polo if (XrmGetResource(xdb, "MyMenu.border.color", "*", datatype, &value) == 1) {
1792 1d13acf5 2018-10-04 omar.polo char **colors;
1793 1d13acf5 2018-10-04 omar.polo colors = parse_csslike(value.addr);
1794 df29e05e 2018-10-17 omar.polo if (colors != NULL)
1795 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1796 df29e05e 2018-10-17 omar.polo borders_bg[i] = parse_color(colors[i], "#000");
1797 df29e05e 2018-10-17 omar.polo else
1798 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "error while parsing MyMenu.border.color\n");
1799 1d13acf5 2018-10-04 omar.polo }
1800 1d13acf5 2018-10-04 omar.polo }
1801 1d13acf5 2018-10-04 omar.polo
1802 26b541d8 2018-10-04 omar.polo /* Second round of args parsing */
1803 26b541d8 2018-10-04 omar.polo optind = 0; /* reset the option index */
1804 1d13acf5 2018-10-04 omar.polo while ((ch = getopt(argc, argv, ARGS)) != -1) {
1805 1d13acf5 2018-10-04 omar.polo switch (ch) {
1806 1d13acf5 2018-10-04 omar.polo case 'a':
1807 4f769efa 2018-10-06 omar.polo r.first_selected = 1;
1808 1d13acf5 2018-10-04 omar.polo break;
1809 1d13acf5 2018-10-04 omar.polo case 'A':
1810 1d13acf5 2018-10-04 omar.polo /* free_text -- already catched */
1811 1d13acf5 2018-10-04 omar.polo case 'd':
1812 1d13acf5 2018-10-04 omar.polo /* separator -- this case was already catched */
1813 1d13acf5 2018-10-04 omar.polo case 'e':
1814 1d13acf5 2018-10-04 omar.polo /* embedding mymenu this case was already catched. */
1815 1d13acf5 2018-10-04 omar.polo case 'm':
1816 1d13acf5 2018-10-04 omar.polo /* multiple selection this case was already catched. */
1817 1d13acf5 2018-10-04 omar.polo break;
1818 1d13acf5 2018-10-04 omar.polo case 'p': {
1819 1d13acf5 2018-10-04 omar.polo char *newprompt;
1820 1d13acf5 2018-10-04 omar.polo newprompt = strdup(optarg);
1821 1d13acf5 2018-10-04 omar.polo if (newprompt != NULL) {
1822 4f769efa 2018-10-06 omar.polo free(r.ps1);
1823 4f769efa 2018-10-06 omar.polo r.ps1 = newprompt;
1824 1d13acf5 2018-10-04 omar.polo }
1825 1d13acf5 2018-10-04 omar.polo break;
1826 1d13acf5 2018-10-04 omar.polo }
1827 1d13acf5 2018-10-04 omar.polo case 'x':
1828 4f769efa 2018-10-06 omar.polo x = parse_int_with_pos(optarg, x, d_width, r.width);
1829 1d13acf5 2018-10-04 omar.polo break;
1830 1d13acf5 2018-10-04 omar.polo case 'y':
1831 4f769efa 2018-10-06 omar.polo y = parse_int_with_pos(optarg, y, d_height, r.height);
1832 1d13acf5 2018-10-04 omar.polo break;
1833 df29e05e 2018-10-17 omar.polo case 'P': {
1834 df29e05e 2018-10-17 omar.polo char **paddings;
1835 df29e05e 2018-10-17 omar.polo if ((paddings = parse_csslike(optarg)) != NULL)
1836 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1837 df29e05e 2018-10-17 omar.polo r.p_padding[i] = parse_integer(paddings[i], 0);
1838 1d13acf5 2018-10-04 omar.polo break;
1839 df29e05e 2018-10-17 omar.polo }
1840 df29e05e 2018-10-17 omar.polo case 'G': {
1841 df29e05e 2018-10-17 omar.polo char **colors;
1842 df29e05e 2018-10-17 omar.polo if ((colors = parse_csslike(optarg)) != NULL)
1843 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1844 df29e05e 2018-10-17 omar.polo p_borders_bg[i] = parse_color(colors[i], "#000");
1845 df29e05e 2018-10-17 omar.polo break;
1846 df29e05e 2018-10-17 omar.polo }
1847 df29e05e 2018-10-17 omar.polo case 'g': {
1848 df29e05e 2018-10-17 omar.polo char **sizes;
1849 df29e05e 2018-10-17 omar.polo if ((sizes = parse_csslike(optarg)) != NULL)
1850 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1851 df29e05e 2018-10-17 omar.polo r.p_borders[i] = parse_integer(sizes[i], 0);
1852 df29e05e 2018-10-17 omar.polo break;
1853 df29e05e 2018-10-17 omar.polo }
1854 df29e05e 2018-10-17 omar.polo case 'I': {
1855 df29e05e 2018-10-17 omar.polo char **colors;
1856 df29e05e 2018-10-17 omar.polo if ((colors = parse_csslike(optarg)) != NULL)
1857 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1858 df29e05e 2018-10-17 omar.polo c_borders_bg[i] = parse_color(colors[i], "#000");
1859 df29e05e 2018-10-17 omar.polo break;
1860 df29e05e 2018-10-17 omar.polo }
1861 df29e05e 2018-10-17 omar.polo case 'i': {
1862 df29e05e 2018-10-17 omar.polo char **sizes;
1863 df29e05e 2018-10-17 omar.polo if ((sizes = parse_csslike(optarg)) != NULL)
1864 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1865 df29e05e 2018-10-17 omar.polo r.c_borders[i] = parse_integer(sizes[i], 0);
1866 df29e05e 2018-10-17 omar.polo break;
1867 df29e05e 2018-10-17 omar.polo }
1868 df29e05e 2018-10-17 omar.polo case 'J': {
1869 df29e05e 2018-10-17 omar.polo char **colors;
1870 df29e05e 2018-10-17 omar.polo if ((colors = parse_csslike(optarg)) != NULL)
1871 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1872 df29e05e 2018-10-17 omar.polo ch_borders_bg[i] = parse_color(colors[i], "#000");
1873 df29e05e 2018-10-17 omar.polo break;
1874 df29e05e 2018-10-17 omar.polo }
1875 df29e05e 2018-10-17 omar.polo case 'j': {
1876 df29e05e 2018-10-17 omar.polo char **sizes;
1877 df29e05e 2018-10-17 omar.polo if ((sizes = parse_csslike(optarg)) != NULL)
1878 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1879 df29e05e 2018-10-17 omar.polo r.ch_borders[i] = parse_integer(sizes[i], 0);
1880 df29e05e 2018-10-17 omar.polo break;
1881 df29e05e 2018-10-17 omar.polo }
1882 1d13acf5 2018-10-04 omar.polo case 'l':
1883 4f769efa 2018-10-06 omar.polo r.horizontal_layout = !strcmp(optarg, "horizontal");
1884 1d13acf5 2018-10-04 omar.polo break;
1885 1d13acf5 2018-10-04 omar.polo case 'f': {
1886 1d13acf5 2018-10-04 omar.polo char *newfont;
1887 1d13acf5 2018-10-04 omar.polo if ((newfont = strdup(optarg)) != NULL) {
1888 1d13acf5 2018-10-04 omar.polo free(fontname);
1889 1d13acf5 2018-10-04 omar.polo fontname = newfont;
1890 1d13acf5 2018-10-04 omar.polo }
1891 1d13acf5 2018-10-04 omar.polo break;
1892 1d13acf5 2018-10-04 omar.polo }
1893 1d13acf5 2018-10-04 omar.polo case 'W':
1894 4f769efa 2018-10-06 omar.polo r.width = parse_int_with_percentage(optarg, r.width, d_width);
1895 1d13acf5 2018-10-04 omar.polo break;
1896 1d13acf5 2018-10-04 omar.polo case 'H':
1897 4f769efa 2018-10-06 omar.polo r.height = parse_int_with_percentage(optarg, r.height, d_height);
1898 1d13acf5 2018-10-04 omar.polo break;
1899 1d13acf5 2018-10-04 omar.polo case 'b': {
1900 1d13acf5 2018-10-04 omar.polo char **borders;
1901 1d13acf5 2018-10-04 omar.polo if ((borders = parse_csslike(optarg)) != NULL) {
1902 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1903 df29e05e 2018-10-17 omar.polo r.borders[i] = parse_integer(borders[i], 0);
1904 1d13acf5 2018-10-04 omar.polo } else
1905 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Error parsing b option\n");
1906 1d13acf5 2018-10-04 omar.polo break;
1907 1d13acf5 2018-10-04 omar.polo }
1908 1d13acf5 2018-10-04 omar.polo case 'B': {
1909 1d13acf5 2018-10-04 omar.polo char **colors;
1910 1d13acf5 2018-10-04 omar.polo if ((colors = parse_csslike(optarg)) != NULL) {
1911 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i)
1912 df29e05e 2018-10-17 omar.polo borders_bg[i] = parse_color(colors[i], "#000");
1913 1d13acf5 2018-10-04 omar.polo } else
1914 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "error while parsing B option\n");
1915 1d13acf5 2018-10-04 omar.polo break;
1916 1d13acf5 2018-10-04 omar.polo }
1917 4f769efa 2018-10-06 omar.polo case 't':
1918 4c0d79a0 2018-10-09 omar.polo fgs[0] = parse_color(optarg, NULL);
1919 1d13acf5 2018-10-04 omar.polo break;
1920 4f769efa 2018-10-06 omar.polo case 'T':
1921 4c0d79a0 2018-10-09 omar.polo bgs[0] = parse_color(optarg, NULL);
1922 1d13acf5 2018-10-04 omar.polo break;
1923 4f769efa 2018-10-06 omar.polo case 'c':
1924 4c0d79a0 2018-10-09 omar.polo fgs[1] = parse_color(optarg, NULL);
1925 1d13acf5 2018-10-04 omar.polo break;
1926 4f769efa 2018-10-06 omar.polo case 'C':
1927 4c0d79a0 2018-10-09 omar.polo bgs[1] = parse_color(optarg, NULL);
1928 1d13acf5 2018-10-04 omar.polo break;
1929 4f769efa 2018-10-06 omar.polo case 's':
1930 4c0d79a0 2018-10-09 omar.polo fgs[2] = parse_color(optarg, NULL);
1931 1d13acf5 2018-10-04 omar.polo break;
1932 4f769efa 2018-10-06 omar.polo case 'S':
1933 4c0d79a0 2018-10-09 omar.polo fgs[2] = parse_color(optarg, NULL);
1934 1d13acf5 2018-10-04 omar.polo break;
1935 1d13acf5 2018-10-04 omar.polo default:
1936 1d13acf5 2018-10-04 omar.polo fprintf(stderr, "Unrecognized option %c\n", ch);
1937 1d13acf5 2018-10-04 omar.polo status = ERR;
1938 1d13acf5 2018-10-04 omar.polo break;
1939 1d13acf5 2018-10-04 omar.polo }
1940 1d13acf5 2018-10-04 omar.polo }
1941 1d13acf5 2018-10-04 omar.polo
1942 df29e05e 2018-10-17 omar.polo if (r.height < 0 || r.width < 0 || x < 0 || y < 0) {
1943 df29e05e 2018-10-17 omar.polo fprintf(stderr, "height, width, x or y are lesser than 0.");
1944 df29e05e 2018-10-17 omar.polo status = ERR;
1945 df29e05e 2018-10-17 omar.polo }
1946 df29e05e 2018-10-17 omar.polo
1947 1d13acf5 2018-10-04 omar.polo /* since only now we know if the first should be selected,
1948 1d13acf5 2018-10-04 omar.polo * update the completion here */
1949 4f769efa 2018-10-06 omar.polo update_completions(cs, text, lines, vlines, r.first_selected);
1950 1d13acf5 2018-10-04 omar.polo
1951 4f769efa 2018-10-06 omar.polo /* update the prompt lenght, only now we surely know the length of it */
1952 4f769efa 2018-10-06 omar.polo r.ps1len = strlen(r.ps1);
1953 4f769efa 2018-10-06 omar.polo
1954 26b541d8 2018-10-04 omar.polo /* Create the window */
1955 1f6422bc 2018-10-20 omar.polo create_window(&r, parent_window, cmap, vinfo, x, y, offset_x, offset_y, bgs[1]);
1956 4f769efa 2018-10-06 omar.polo set_win_atoms_hints(r.d, r.w, r.width, r.height);
1957 4f769efa 2018-10-06 omar.polo XMapRaised(r.d, r.w);
1958 1d13acf5 2018-10-04 omar.polo
1959 1d13acf5 2018-10-04 omar.polo /* If embed, listen for other events as well */
1960 1d13acf5 2018-10-04 omar.polo if (embed) {
1961 1d13acf5 2018-10-04 omar.polo Window *children, parent, root;
1962 1d13acf5 2018-10-04 omar.polo unsigned int children_no;
1963 1d13acf5 2018-10-04 omar.polo
1964 4f769efa 2018-10-06 omar.polo XSelectInput(r.d, parent_window, FocusChangeMask);
1965 4f769efa 2018-10-06 omar.polo if (XQueryTree(r.d, parent_window, &root, &parent, &children, &children_no) && children) {
1966 4f769efa 2018-10-06 omar.polo for (i = 0; i < children_no && children[i] != r.w; ++i)
1967 4f769efa 2018-10-06 omar.polo XSelectInput(r.d, children[i], FocusChangeMask);
1968 1d13acf5 2018-10-04 omar.polo XFree(children);
1969 1d13acf5 2018-10-04 omar.polo }
1970 4f769efa 2018-10-06 omar.polo grabfocus(r.d, r.w);
1971 1d13acf5 2018-10-04 omar.polo }
1972 1d13acf5 2018-10-04 omar.polo
1973 4f769efa 2018-10-06 omar.polo take_keyboard(r.d, r.w);
1974 1d13acf5 2018-10-04 omar.polo
1975 4c0d79a0 2018-10-09 omar.polo r.x_zero = r.borders[3];
1976 4c0d79a0 2018-10-09 omar.polo r.y_zero = r.borders[0];
1977 1d13acf5 2018-10-04 omar.polo
1978 4f769efa 2018-10-06 omar.polo {
1979 4f769efa 2018-10-06 omar.polo XGCValues values;
1980 4f769efa 2018-10-06 omar.polo
1981 df29e05e 2018-10-17 omar.polo for (i = 0; i < 3; ++i) {
1982 df29e05e 2018-10-17 omar.polo r.fgs[i] = XCreateGC(r.d, r.w, 0, &values);
1983 df29e05e 2018-10-17 omar.polo r.bgs[i] = XCreateGC(r.d, r.w, 0, &values);
1984 df29e05e 2018-10-17 omar.polo }
1985 df29e05e 2018-10-17 omar.polo
1986 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i) {
1987 df29e05e 2018-10-17 omar.polo r.borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
1988 df29e05e 2018-10-17 omar.polo r.p_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
1989 df29e05e 2018-10-17 omar.polo r.c_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
1990 df29e05e 2018-10-17 omar.polo r.ch_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
1991 df29e05e 2018-10-17 omar.polo }
1992 4f769efa 2018-10-06 omar.polo }
1993 4f769efa 2018-10-06 omar.polo
1994 df29e05e 2018-10-17 omar.polo /* Load the colors in our GCs */
1995 df29e05e 2018-10-17 omar.polo for (i = 0; i < 3; ++i) {
1996 df29e05e 2018-10-17 omar.polo XSetForeground(r.d, r.fgs[i], fgs[i]);
1997 df29e05e 2018-10-17 omar.polo XSetForeground(r.d, r.bgs[i], bgs[i]);
1998 df29e05e 2018-10-17 omar.polo }
1999 df29e05e 2018-10-17 omar.polo
2000 df29e05e 2018-10-17 omar.polo for (i = 0; i < 4; ++i) {
2001 df29e05e 2018-10-17 omar.polo XSetForeground(r.d, r.borders_bg[i], borders_bg[i]);
2002 df29e05e 2018-10-17 omar.polo XSetForeground(r.d, r.p_borders_bg[i], p_borders_bg[i]);
2003 df29e05e 2018-10-17 omar.polo XSetForeground(r.d, r.c_borders_bg[i], c_borders_bg[i]);
2004 df29e05e 2018-10-17 omar.polo XSetForeground(r.d, r.ch_borders_bg[i], ch_borders_bg[i]);
2005 df29e05e 2018-10-17 omar.polo }
2006 df29e05e 2018-10-17 omar.polo
2007 1d13acf5 2018-10-04 omar.polo if (load_font(&r, fontname) == -1)
2008 1d13acf5 2018-10-04 omar.polo status = ERR;
2009 1d13acf5 2018-10-04 omar.polo
2010 1d13acf5 2018-10-04 omar.polo #ifdef USE_XFT
2011 df29e05e 2018-10-17 omar.polo r.xftdraw = XftDrawCreate(r.d, r.w, vinfo.visual, cmap);
2012 1d13acf5 2018-10-04 omar.polo
2013 3d95a42e 2018-10-19 omar.polo for (i = 0; i < 3; ++i) {
2014 3d95a42e 2018-10-19 omar.polo rgba_t c;
2015 3d95a42e 2018-10-19 omar.polo XRenderColor xrcolor;
2016 1d13acf5 2018-10-04 omar.polo
2017 3d95a42e 2018-10-19 omar.polo c = *(rgba_t*)&fgs[i];
2018 4f769efa 2018-10-06 omar.polo xrcolor.red = EXPANDBITS(c.rgba.r);
2019 4f769efa 2018-10-06 omar.polo xrcolor.green = EXPANDBITS(c.rgba.g);
2020 4f769efa 2018-10-06 omar.polo xrcolor.blue = EXPANDBITS(c.rgba.b);
2021 4f769efa 2018-10-06 omar.polo xrcolor.alpha = EXPANDBITS(c.rgba.a);
2022 3d95a42e 2018-10-19 omar.polo XftColorAllocValue(r.d, vinfo.visual, cmap, &xrcolor, &r.xft_colors[i]);
2023 1d13acf5 2018-10-04 omar.polo }
2024 c9a3bfaa 2018-05-21 omar.polo #endif
2025 7ca8829b 2018-05-21 omar.polo
2026 aed48307 2018-10-06 omar.polo /* compute prompt dimensions */
2027 aed48307 2018-10-06 omar.polo ps1extents(&r);
2028 347d23da 2018-05-19 omar.polo
2029 4f769efa 2018-10-06 omar.polo xim_init(&r, &xdb);
2030 f5e234d6 2018-05-18 omar.polo
2031 aed48307 2018-10-06 omar.polo #ifdef __OpenBSD__
2032 aed48307 2018-10-06 omar.polo /* Now we need only the ability to write */
2033 aed48307 2018-10-06 omar.polo pledge("stdio", "");
2034 aed48307 2018-10-06 omar.polo #endif
2035 aed48307 2018-10-06 omar.polo
2036 df29e05e 2018-10-17 omar.polo /* Cache text height */
2037 df29e05e 2018-10-17 omar.polo text_extents("fyjpgl", 6, &r, NULL, &r.text_height);
2038 df29e05e 2018-10-17 omar.polo
2039 5e448381 2018-10-09 omar.polo /* Draw the window for the first time */
2040 5e448381 2018-10-09 omar.polo draw(&r, text, cs);
2041 5e448381 2018-10-09 omar.polo
2042 1d13acf5 2018-10-04 omar.polo /* Main loop */
2043 1d13acf5 2018-10-04 omar.polo while (status == LOOPING || status == OK_LOOP) {
2044 1d13acf5 2018-10-04 omar.polo status = loop(&r, &text, &textlen, cs, lines, vlines);
2045 f5e234d6 2018-05-18 omar.polo
2046 1d13acf5 2018-10-04 omar.polo if (status != ERR)
2047 1d13acf5 2018-10-04 omar.polo printf("%s\n", text);
2048 844addbb 2018-07-15 omar.polo
2049 4f769efa 2018-10-06 omar.polo if (!r.multiple_select && status == OK_LOOP)
2050 1d13acf5 2018-10-04 omar.polo status = OK;
2051 1d13acf5 2018-10-04 omar.polo }
2052 f5e234d6 2018-05-18 omar.polo
2053 4f769efa 2018-10-06 omar.polo XUngrabKeyboard(r.d, CurrentTime);
2054 43e30577 2018-10-20 omar.polo
2055 43e30577 2018-10-20 omar.polo #ifdef USE_XFT
2056 43e30577 2018-10-20 omar.polo for (i = 0; i < 3; ++i)
2057 43e30577 2018-10-20 omar.polo XftColorFree(r.d, vinfo.visual, cmap, &r.xft_colors[i]);
2058 43e30577 2018-10-20 omar.polo #endif
2059 43e30577 2018-10-20 omar.polo
2060 43e30577 2018-10-20 omar.polo for (i = 0; i < 3; ++i) {
2061 43e30577 2018-10-20 omar.polo XFreeGC(r.d, r.fgs[i]);
2062 43e30577 2018-10-20 omar.polo XFreeGC(r.d, r.bgs[i]);
2063 43e30577 2018-10-20 omar.polo }
2064 b5d751bd 2018-07-07 omar.polo
2065 43e30577 2018-10-20 omar.polo for (i = 0; i < 4; ++i) {
2066 43e30577 2018-10-20 omar.polo XFreeGC(r.d, r.borders_bg[i]);
2067 43e30577 2018-10-20 omar.polo XFreeGC(r.d, r.p_borders_bg[i]);
2068 43e30577 2018-10-20 omar.polo XFreeGC(r.d, r.c_borders_bg[i]);
2069 43e30577 2018-10-20 omar.polo XFreeGC(r.d, r.ch_borders_bg[i]);
2070 43e30577 2018-10-20 omar.polo }
2071 43e30577 2018-10-20 omar.polo
2072 43e30577 2018-10-20 omar.polo XDestroyIC(r.xic);
2073 43e30577 2018-10-20 omar.polo XCloseIM(r.xim);
2074 43e30577 2018-10-20 omar.polo
2075 b5d751bd 2018-07-07 omar.polo #ifdef USE_XFT
2076 043d71ef 2018-10-19 omar.polo for (i = 0; i < 3; ++i)
2077 043d71ef 2018-10-19 omar.polo XftColorFree(r.d, vinfo.visual, cmap, &r.xft_colors[i]);
2078 43e30577 2018-10-20 omar.polo XftFontClose(r.d, r.font);
2079 43e30577 2018-10-20 omar.polo XftDrawDestroy(r.xftdraw);
2080 43e30577 2018-10-20 omar.polo #else
2081 43e30577 2018-10-20 omar.polo XFreeFontSet(r.d, r.font);
2082 b5d751bd 2018-07-07 omar.polo #endif
2083 b5d751bd 2018-07-07 omar.polo
2084 4f769efa 2018-10-06 omar.polo free(r.ps1);
2085 1d13acf5 2018-10-04 omar.polo free(fontname);
2086 1d13acf5 2018-10-04 omar.polo free(text);
2087 b5d751bd 2018-07-07 omar.polo
2088 1d13acf5 2018-10-04 omar.polo free(buf);
2089 1d13acf5 2018-10-04 omar.polo free(lines);
2090 1d13acf5 2018-10-04 omar.polo free(vlines);
2091 1d13acf5 2018-10-04 omar.polo compls_delete(cs);
2092 b5d751bd 2018-07-07 omar.polo
2093 43e30577 2018-10-20 omar.polo XFreeColormap(r.d, cmap);
2094 43e30577 2018-10-20 omar.polo
2095 1d13acf5 2018-10-04 omar.polo XDestroyWindow(r.d, r.w);
2096 1d13acf5 2018-10-04 omar.polo XCloseDisplay(r.d);
2097 b5d751bd 2018-07-07 omar.polo
2098 1d13acf5 2018-10-04 omar.polo return status != OK;
2099 f5e234d6 2018-05-18 omar.polo }