Blame
Date:
Sat Jul 2 07:58:26 2022 UTC
Message:
it's spelled fallthrough, not fallback

reminded by N-R-K on GitHub (issue #1).
0001
2022-05-21
op
/*
0002
2022-05-21
op
* Copyright (c) 2018, 2019, 2020, 2022 Omar Polo <op@omarpolo.com>
0003
2022-05-21
op
*
0004
2022-05-21
op
* Permission to use, copy, modify, and distribute this software for any
0005
2022-05-21
op
* purpose with or without fee is hereby granted, provided that the above
0006
2022-05-21
op
* copyright notice and this permission notice appear in all copies.
0007
2022-05-21
op
*
0008
2022-05-21
op
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009
2022-05-21
op
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010
2022-05-21
op
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0011
2022-05-21
op
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012
2022-05-21
op
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0013
2022-05-21
op
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0014
2022-05-21
op
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0015
2022-05-21
op
*/
0016
2022-07-01
op
0017
2022-07-01
op
#include "config.h"
0018
2022-05-21
op
0019
2019-10-18
omar.pol
#include <ctype.h> /* isalnum */
0020
2019-10-19
omar.pol
#include <err.h>
0021
2019-10-18
omar.pol
#include <errno.h>
0022
2019-10-18
omar.pol
#include <limits.h>
0023
2019-10-18
omar.pol
#include <locale.h> /* setlocale */
0024
2019-10-18
omar.pol
#include <stdint.h>
0025
2018-05-18
omar.pol
#include <stdio.h>
0026
2018-05-18
omar.pol
#include <stdlib.h>
0027
2019-10-18
omar.pol
#include <string.h> /* strdup, strlen */
0028
2018-05-18
omar.pol
#include <sysexits.h>
0029
2018-09-19
omar.pol
#include <unistd.h>
0030
2018-05-18
omar.pol
0031
2019-10-18
omar.pol
#include <X11/Xcms.h>
0032
2018-05-18
omar.pol
#include <X11/Xlib.h>
0033
2018-05-18
omar.pol
#include <X11/Xresource.h>
0034
2019-10-18
omar.pol
#include <X11/Xutil.h>
0035
2018-05-19
omar.pol
#include <X11/keysym.h>
0036
2022-05-16
op
#include <X11/Xft/Xft.h>
0037
2018-05-18
omar.pol
0038
2019-10-18
omar.pol
#include <X11/extensions/Xinerama.h>
0039
2018-05-18
omar.pol
0040
2022-05-16
op
#define RESNAME "MyMenu"
0041
2022-05-16
op
#define RESCLASS "mymenu"
0042
2018-05-21
omar.pol
0043
2018-07-07
omar.pol
#define SYM_BUF_SIZE 4
0044
2018-07-07
omar.pol
0045
2022-05-16
op
#define DEFFONT "monospace"
0046
2018-07-13
omar.pol
0047
2018-10-17
omar.pol
#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:"
0048
2018-05-22
omar.pol
0049
2018-05-22
omar.pol
#define MIN(a, b) ((a) < (b) ? (a) : (b))
0050
2018-05-18
omar.pol
#define MAX(a, b) ((a) > (b) ? (a) : (b))
0051
2018-05-22
omar.pol
0052
2018-10-09
omar.pol
#define EXPANDBITS(x) (((x & 0xf0) * 0x100) | (x & 0x0f) * 0x10)
0053
2018-05-18
omar.pol
0054
2022-05-16
op
#define INNER_HEIGHT(r) (r->height - r->borders[0] - r->borders[2])
0055
2022-05-16
op
#define INNER_WIDTH(r) (r->width - r->borders[1] - r->borders[3])
0056
2018-07-08
omar.pol
0057
2018-10-04
omar.pol
/* The states of the event loop */
0058
2019-10-18
omar.pol
enum state { LOOPING, OK_LOOP, OK, ERR };
0059
2018-05-18
omar.pol
0060
2019-10-18
omar.pol
/*
0061
2018-10-04
omar.pol
* For the drawing-related function. The text to be rendere could be
0062
2018-10-04
omar.pol
* the prompt, a completion or a highlighted completion
0063
2018-10-04
omar.pol
*/
0064
2019-10-18
omar.pol
enum obj_type { PROMPT, COMPL, COMPL_HIGH };
0065
2018-05-21
omar.pol
0066
2018-10-04
omar.pol
/* These are the possible action to be performed after user input. */
0067
2018-06-30
omar.pol
enum action {
0068
2019-10-19
omar.pol
NO_OP,
0069
2018-10-04
omar.pol
EXIT,
0070
2018-10-04
omar.pol
CONFIRM,
0071
2018-10-04
omar.pol
CONFIRM_CONTINUE,
0072
2018-10-04
omar.pol
NEXT_COMPL,
0073
2018-10-04
omar.pol
PREV_COMPL,
0074
2018-10-04
omar.pol
DEL_CHAR,
0075
2018-10-04
omar.pol
DEL_WORD,
0076
2018-10-04
omar.pol
DEL_LINE,
0077
2018-10-04
omar.pol
ADD_CHAR,
0078
2019-10-19
omar.pol
TOGGLE_FIRST_SELECTED,
0079
2019-10-19
omar.pol
SCROLL_DOWN,
0080
2019-10-19
omar.pol
SCROLL_UP,
0081
2018-06-30
omar.pol
};
0082
2018-06-30
omar.pol
0083
2018-10-04
omar.pol
/* A big set of values that needs to be carried around for drawing. A
0084
2019-10-19
omar.pol
* big struct to rule them all */
0085
2018-05-18
omar.pol
struct rendering {
0086
2019-10-18
omar.pol
Display *d; /* Connection to xorg */
0087
2019-10-18
omar.pol
Window w;
0088
2019-10-18
omar.pol
XIM xim;
0089
2019-10-18
omar.pol
int width;
0090
2019-10-18
omar.pol
int height;
0091
2019-10-18
omar.pol
int p_padding[4];
0092
2019-10-18
omar.pol
int c_padding[4];
0093
2019-10-18
omar.pol
int ch_padding[4];
0094
2019-10-18
omar.pol
int x_zero; /* the "zero" on the x axis (may not be exactly 0 'cause
0095
2019-10-18
omar.pol
the borders) */
0096
2019-10-18
omar.pol
int y_zero; /* like x_zero but for the y axis */
0097
2018-08-11
omar.pol
0098
2022-07-01
op
size_t offset; /* scroll offset */
0099
2018-07-08
omar.pol
0100
2019-10-18
omar.pol
short free_text;
0101
2019-10-18
omar.pol
short first_selected;
0102
2019-10-18
omar.pol
short multiple_select;
0103
2018-08-13
omar.pol
0104
2018-10-04
omar.pol
/* four border width */
0105
2019-10-18
omar.pol
int borders[4];
0106
2019-10-18
omar.pol
int p_borders[4];
0107
2019-10-18
omar.pol
int c_borders[4];
0108
2019-10-18
omar.pol
int ch_borders[4];
0109
2018-07-08
omar.pol
0110
2019-10-18
omar.pol
short horizontal_layout;
0111
2018-07-08
omar.pol
0112
2018-10-04
omar.pol
/* prompt */
0113
2019-10-18
omar.pol
char *ps1;
0114
2019-10-18
omar.pol
int ps1len;
0115
2019-10-18
omar.pol
int ps1w; /* ps1 width */
0116
2019-10-18
omar.pol
int ps1h; /* ps1 height */
0117
2018-07-08
omar.pol
0118
2019-10-18
omar.pol
int text_height; /* cache for the vertical layout */
0119
2018-10-17
omar.pol
0120
2019-10-18
omar.pol
XIC xic;
0121
2018-08-13
omar.pol
0122
2018-10-04
omar.pol
/* colors */
0123
2019-10-18
omar.pol
GC fgs[4];
0124
2019-10-18
omar.pol
GC bgs[4];
0125
2019-10-18
omar.pol
GC borders_bg[4];
0126
2019-10-18
omar.pol
GC p_borders_bg[4];
0127
2019-10-18
omar.pol
GC c_borders_bg[4];
0128
2019-10-18
omar.pol
GC ch_borders_bg[4];
0129
2019-10-18
omar.pol
XftFont *font;
0130
2019-10-18
omar.pol
XftDraw *xftdraw;
0131
2019-10-18
omar.pol
XftColor xft_colors[3];
0132
2018-05-18
omar.pol
};
0133
2018-05-18
omar.pol
0134
2018-07-07
omar.pol
struct completion {
0135
2019-10-18
omar.pol
char *completion;
0136
2019-10-18
omar.pol
char *rcompletion;
0137
2022-05-21
op
0138
2022-05-21
op
/*
0139
2022-05-21
op
* The X (or Y, depending on the layour) at which the item is
0140
2022-05-21
op
* rendered
0141
2022-05-21
op
*/
0142
2022-07-01
op
ssize_t offset;
0143
2018-05-18
omar.pol
};
0144
2018-05-18
omar.pol
0145
2018-10-04
omar.pol
/* Wrap the linked list of completions */
0146
2018-07-07
omar.pol
struct completions {
0147
2019-10-18
omar.pol
struct completion *completions;
0148
2019-10-18
omar.pol
ssize_t selected;
0149
2019-10-18
omar.pol
size_t length;
0150
2018-07-07
omar.pol
};
0151
2018-07-07
omar.pol
0152
2022-05-21
op
/* idea stolen from lemonbar; ty lemonboy */
0153
2018-09-13
omar.pol
typedef union {
0154
2018-10-04
omar.pol
struct {
0155
2019-10-18
omar.pol
uint8_t b;
0156
2019-10-18
omar.pol
uint8_t g;
0157
2019-10-18
omar.pol
uint8_t r;
0158
2019-10-18
omar.pol
uint8_t a;
0159
2018-10-06
omar.pol
} rgba;
0160
2019-10-18
omar.pol
uint32_t v;
0161
2018-09-13
omar.pol
} rgba_t;
0162
2018-09-13
omar.pol
0163
2018-10-04
omar.pol
/* Return a newly allocated (and empty) completion list */
0164
2022-07-01
op
static struct completions *
0165
2018-10-04
omar.pol
compls_new(size_t length)
0166
2018-10-04
omar.pol
{
0167
2018-10-04
omar.pol
struct completions *cs = malloc(sizeof(struct completions));
0168
2018-05-19
omar.pol
0169
2018-10-04
omar.pol
if (cs == NULL)
0170
2018-10-04
omar.pol
return cs;
0171
2018-05-19
omar.pol
0172
2018-10-04
omar.pol
cs->completions = calloc(length, sizeof(struct completion));
0173
2018-10-04
omar.pol
if (cs->completions == NULL) {
0174
2018-10-04
omar.pol
free(cs);
0175
2018-10-04
omar.pol
return NULL;
0176
2018-10-04
omar.pol
}
0177
2018-07-01
omar.pol
0178
2018-10-04
omar.pol
cs->selected = -1;
0179
2018-10-04
omar.pol
cs->length = length;
0180
2018-10-04
omar.pol
return cs;
0181
2018-10-04
omar.pol
}
0182
2018-07-21
omar.pol
0183
2018-10-04
omar.pol
/* Delete the wrapper and the whole list */
0184
2022-07-01
op
static void
0185
2018-10-04
omar.pol
compls_delete(struct completions *cs)
0186
2018-10-04
omar.pol
{
0187
2018-10-04
omar.pol
if (cs == NULL)
0188
2018-10-04
omar.pol
return;
0189
2018-09-24
omar.pol
0190
2018-10-04
omar.pol
free(cs->completions);
0191
2018-10-04
omar.pol
free(cs);
0192
2018-10-04
omar.pol
}
0193
2018-05-18
omar.pol
0194
2019-10-18
omar.pol
/*
0195
2018-10-04
omar.pol
* Create a completion list from a text and the list of possible
0196
2018-10-04
omar.pol
* completions (null terminated). Expects a non-null `cs'. `lines' and
0197
2018-10-04
omar.pol
* `vlines' should have the same length OR `vlines' is NULL.
0198
2018-10-04
omar.pol
*/
0199
2022-07-01
op
static void
0200
2018-10-04
omar.pol
filter(struct completions *cs, char *text, char **lines, char **vlines)
0201
2018-10-04
omar.pol
{
0202
2019-10-18
omar.pol
size_t index = 0;
0203
2019-10-18
omar.pol
size_t matching = 0;
0204
2019-10-18
omar.pol
char *l;
0205
2018-05-18
omar.pol
0206
2018-10-04
omar.pol
if (vlines == NULL)
0207
2018-10-04
omar.pol
vlines = lines;
0208
2018-05-18
omar.pol
0209
2018-10-04
omar.pol
while (1) {
0210
2018-10-04
omar.pol
if (lines[index] == NULL)
0211
2018-10-04
omar.pol
break;
0212
2018-06-30
omar.pol
0213
2018-10-06
omar.pol
l = vlines[index] != NULL ? vlines[index] : lines[index];
0214
2018-07-07
omar.pol
0215
2018-10-04
omar.pol
if (strcasestr(l, text) != NULL) {
0216
2018-10-04
omar.pol
struct completion *c = &cs->completions[matching];
0217
2019-10-18
omar.pol
c->completion = l;
0218
2018-10-04
omar.pol
c->rcompletion = lines[index];
0219
2018-10-04
omar.pol
matching++;
0220
2018-10-04
omar.pol
}
0221
2018-07-01
omar.pol
0222
2018-10-04
omar.pol
index++;
0223
2018-10-04
omar.pol
}
0224
2018-10-04
omar.pol
cs->length = matching;
0225
2018-10-04
omar.pol
cs->selected = -1;
0226
2018-10-04
omar.pol
}
0227
2018-06-30
omar.pol
0228
2018-10-04
omar.pol
/* Update the given completion */
0229
2022-07-01
op
static void
0230
2022-05-21
op
update_completions(struct completions *cs, char *text, char **lines,
0231
2022-05-21
op
char **vlines, short first_selected)
0232
2018-10-04
omar.pol
{
0233
2018-10-04
omar.pol
filter(cs, text, lines, vlines);
0234
2018-10-04
omar.pol
if (first_selected && cs->length > 0)
0235
2018-10-04
omar.pol
cs->selected = 0;
0236
2018-10-04
omar.pol
}
0237
2018-07-07
omar.pol
0238
2018-10-04
omar.pol
/*
0239
2018-10-04
omar.pol
* Select the next or previous selection and update some state. `text'
0240
2018-10-04
omar.pol
* will be updated with the text of the completion and `textlen' with
0241
2018-10-04
omar.pol
* the new length. If the memory cannot be allocated `status' will be
0242
2018-10-04
omar.pol
* set to `ERR'.
0243
2018-10-04
omar.pol
*/
0244
2022-07-01
op
static void
0245
2022-05-21
op
complete(struct completions *cs, short first_selected, short p,
0246
2022-05-21
op
char **text, int *textlen, enum state *status)
0247
2018-10-04
omar.pol
{
0248
2019-10-18
omar.pol
struct completion *n;
0249
2019-10-18
omar.pol
int index;
0250
2018-07-07
omar.pol
0251
2018-10-04
omar.pol
if (cs == NULL || cs->length == 0)
0252
2018-10-04
omar.pol
return;
0253
2018-06-30
omar.pol
0254
2018-10-04
omar.pol
/*
0255
2018-10-04
omar.pol
* If the first is always selected and the first entry is
0256
2018-10-04
omar.pol
* different from the text, expand the text and return
0257
2018-10-04
omar.pol
*/
0258
2022-05-21
op
if (first_selected &&
0259
2022-05-21
op
cs->selected == 0 &&
0260
2022-05-21
op
strcmp(cs->completions->completion, *text) != 0 &&
0261
2022-05-21
op
!p) {
0262
2018-10-04
omar.pol
free(*text);
0263
2018-10-04
omar.pol
*text = strdup(cs->completions->completion);
0264
2018-10-04
omar.pol
if (text == NULL) {
0265
2018-10-04
omar.pol
*status = ERR;
0266
2018-10-04
omar.pol
return;
0267
2018-10-04
omar.pol
}
0268
2018-10-04
omar.pol
*textlen = strlen(*text);
0269
2018-10-04
omar.pol
return;
0270
2018-10-04
omar.pol
}
0271
2018-05-18
omar.pol
0272
2018-10-04
omar.pol
index = cs->selected;
0273
2018-05-18
omar.pol
0274
2018-10-04
omar.pol
if (index == -1 && p)
0275
2018-10-04
omar.pol
index = 0;
0276
2022-05-21
op
index = cs->selected = (cs->length + (p ? index - 1 : index + 1))
0277
2022-05-21
op
% cs->length;
0278
2018-05-19
omar.pol
0279
2018-10-04
omar.pol
n = &cs->completions[cs->selected];
0280
2018-05-19
omar.pol
0281
2018-10-04
omar.pol
free(*text);
0282
2018-10-04
omar.pol
*text = strdup(n->completion);
0283
2018-10-04
omar.pol
if (text == NULL) {
0284
2018-10-04
omar.pol
fprintf(stderr, "Memory allocation error!\n");
0285
2018-10-04
omar.pol
*status = ERR;
0286
2018-10-04
omar.pol
return;
0287
2018-10-04
omar.pol
}
0288
2018-10-04
omar.pol
*textlen = strlen(*text);
0289
2018-05-18
omar.pol
}
0290
2018-05-18
omar.pol
0291
2018-10-04
omar.pol
/* Push the character c at the end of the string pointed by p */
0292
2022-07-01
op
static int
0293
2018-10-04
omar.pol
pushc(char **p, int maxlen, char c)
0294
2018-10-04
omar.pol
{
0295
2019-10-18
omar.pol
int len;
0296
2018-07-15
omar.pol
0297
2018-10-06
omar.pol
len = strnlen(*p, maxlen);
0298
2019-10-18
omar.pol
if (!(len < maxlen - 2)) {
0299
2018-10-04
omar.pol
char *newptr;
0300
2018-07-15
omar.pol
0301
2018-10-04
omar.pol
maxlen += maxlen >> 1;
0302
2018-10-04
omar.pol
newptr = realloc(*p, maxlen);
0303
2018-10-04
omar.pol
if (newptr == NULL) /* bad */
0304
2018-10-04
omar.pol
return -1;
0305
2018-10-04
omar.pol
*p = newptr;
0306
2018-10-04
omar.pol
}
0307
2018-07-15
omar.pol
0308
2018-10-04
omar.pol
(*p)[len] = c;
0309
2019-10-18
omar.pol
(*p)[len + 1] = '\0';
0310
2018-10-04
omar.pol
return maxlen;
0311
2018-07-15
omar.pol
}
0312
2018-07-15
omar.pol
0313
2019-10-18
omar.pol
/*
0314
2018-10-04
omar.pol
* Remove the last rune from the *UTF-8* string! This is different
0315
2018-10-04
omar.pol
* from just setting the last byte to 0 (in some cases ofc). Return a
0316
2018-10-04
omar.pol
* pointer (e) to the last nonzero char. If e < p then p is empty!
0317
2018-10-04
omar.pol
*/
0318
2022-07-01
op
static char *
0319
2018-10-04
omar.pol
popc(char *p)
0320
2018-10-04
omar.pol
{
0321
2018-10-04
omar.pol
int len = strlen(p);
0322
2018-10-04
omar.pol
char *e;
0323
2018-05-20
omar.pol
0324
2018-10-04
omar.pol
if (len == 0)
0325
2018-10-04
omar.pol
return p;
0326
2018-05-20
omar.pol
0327
2018-10-04
omar.pol
e = p + len - 1;
0328
2018-05-18
omar.pol
0329
2018-10-04
omar.pol
do {
0330
2018-10-04
omar.pol
char c = *e;
0331
2018-07-21
omar.pol
0332
2018-10-06
omar.pol
*e = '\0';
0333
2018-10-06
omar.pol
e -= 1;
0334
2018-05-18
omar.pol
0335
2018-10-04
omar.pol
/*
0336
2018-10-04
omar.pol
* If c is a starting byte (11......) or is under
0337
2018-10-04
omar.pol
* U+007F we're done.
0338
2018-10-04
omar.pol
*/
0339
2018-10-04
omar.pol
if (((c & 0x80) && (c & 0x40)) || !(c & 0x80))
0340
2018-10-04
omar.pol
break;
0341
2018-10-04
omar.pol
} while (e >= p);
0342
2018-05-18
omar.pol
0343
2018-10-04
omar.pol
return e;
0344
2018-09-19
omar.pol
}
0345
2018-09-19
omar.pol
0346
2018-10-04
omar.pol
/* Remove the last word plus trailing white spaces from the given string */
0347
2022-07-01
op
static void
0348
2018-10-04
omar.pol
popw(char *w)
0349
2018-10-04
omar.pol
{
0350
2019-10-18
omar.pol
short in_word = 1;
0351
2018-09-19
omar.pol
0352
2022-05-23
op
if (*w == '\0')
0353
2018-10-04
omar.pol
return;
0354
2018-09-24
omar.pol
0355
2018-10-04
omar.pol
while (1) {
0356
2018-10-04
omar.pol
char *e = popc(w);
0357
2018-09-19
omar.pol
0358
2018-10-04
omar.pol
if (e < w)
0359
2018-10-04
omar.pol
return;
0360
2018-09-19
omar.pol
0361
2018-10-04
omar.pol
if (in_word && isspace(*e))
0362
2018-10-04
omar.pol
in_word = 0;
0363
2018-09-19
omar.pol
0364
2018-10-04
omar.pol
if (!in_word && !isspace(*e))
0365
2018-10-04
omar.pol
return;
0366
2018-10-04
omar.pol
}
0367
2018-10-04
omar.pol
}
0368
2018-09-19
omar.pol
0369
2019-10-18
omar.pol
/*
0370
2018-10-04
omar.pol
* If the string is surrounded by quates (`"') remove them and replace
0371
2018-10-04
omar.pol
* every `\"' in the string with a single double-quote.
0372
2018-10-04
omar.pol
*/
0373
2022-07-01
op
static char *
0374
2018-10-04
omar.pol
normalize_str(const char *str)
0375
2018-10-04
omar.pol
{
0376
2019-10-18
omar.pol
int len, p;
0377
2019-10-18
omar.pol
char *s;
0378
2018-09-19
omar.pol
0379
2018-10-06
omar.pol
if ((len = strlen(str)) == 0)
0380
2018-10-04
omar.pol
return NULL;
0381
2018-05-19
omar.pol
0382
2019-10-19
omar.pol
if ((s = calloc(len, sizeof(char))) == NULL)
0383
2019-10-19
omar.pol
err(1, "calloc");
0384
2018-10-04
omar.pol
p = 0;
0385
2018-09-24
omar.pol
0386
2018-10-04
omar.pol
while (*str) {
0387
2018-10-04
omar.pol
char c = *str;
0388
2018-09-24
omar.pol
0389
2018-10-04
omar.pol
if (*str == '\\') {
0390
2018-10-04
omar.pol
if (*(str + 1)) {
0391
2018-10-04
omar.pol
s[p] = *(str + 1);
0392
2018-10-04
omar.pol
p++;
0393
2018-10-04
omar.pol
str += 2; /* skip this and the next char */
0394
2018-10-04
omar.pol
continue;
0395
2018-10-04
omar.pol
} else
0396
2018-10-04
omar.pol
break;
0397
2018-10-04
omar.pol
}
0398
2018-10-04
omar.pol
if (c == '"') {
0399
2019-10-18
omar.pol
str++; /* skip only this char */
0400
2018-10-04
omar.pol
continue;
0401
2018-10-04
omar.pol
}
0402
2018-10-04
omar.pol
s[p] = c;
0403
2018-10-04
omar.pol
p++;
0404
2018-10-04
omar.pol
str++;
0405
2018-10-04
omar.pol
}
0406
2018-05-21
omar.pol
0407
2018-10-04
omar.pol
return s;
0408
2018-05-21
omar.pol
}
0409
2018-05-21
omar.pol
0410
2022-07-01
op
static char **
0411
2022-05-16
op
readlines(size_t *lineslen)
0412
2018-10-04
omar.pol
{
0413
2022-05-16
op
size_t len = 0, cap = 0;
0414
2022-05-16
op
size_t linesize = 0;
0415
2022-05-16
op
ssize_t linelen;
0416
2022-05-16
op
char *line = NULL, **lines = NULL;
0417
2018-05-21
omar.pol
0418
2022-05-16
op
while ((linelen = getline(&line, &linesize, stdin)) != -1) {
0419
2022-05-16
op
if (linelen != 0 && line[linelen-1] == '\n')
0420
2022-05-16
op
line[linelen-1] = '\0';
0421
2018-05-18
omar.pol
0422
2022-05-16
op
if (len == cap) {
0423
2022-05-16
op
size_t newcap;
0424
2022-05-16
op
void *t;
0425
2018-05-21
omar.pol
0426
2022-05-16
op
newcap = MAX(cap * 1.5, 32);
0427
2022-05-16
op
t = recallocarray(lines, cap, newcap, sizeof(char *));
0428
2022-05-16
op
if (t == NULL)
0429
2022-05-16
op
err(1, "recallocarray");
0430
2022-05-16
op
cap = newcap;
0431
2022-05-16
op
lines = t;
0432
2022-05-16
op
}
0433
2018-05-21
omar.pol
0434
2022-05-16
op
if ((lines[len++] = strdup(line)) == NULL)
0435
2022-05-16
op
err(1, "strdup");
0436
2018-10-04
omar.pol
}
0437
2018-10-04
omar.pol
0438
2022-05-16
op
if (ferror(stdin))
0439
2022-05-16
op
err(1, "getline");
0440
2022-05-16
op
free(line);
0441
2018-05-21
omar.pol
0442
2022-05-16
op
*lineslen = len;
0443
2018-10-04
omar.pol
return lines;
0444
2018-05-18
omar.pol
}
0445
2018-05-19
omar.pol
0446
2018-10-04
omar.pol
/*
0447
2018-10-04
omar.pol
* Compute the dimensions of the string str once rendered.
0448
2018-10-04
omar.pol
* It'll return the width and set ret_width and ret_height if not NULL
0449
2018-10-04
omar.pol
*/
0450
2022-07-01
op
static int
0451
2022-05-21
op
text_extents(char *str, int len, struct rendering *r, int *ret_width,
0452
2022-05-21
op
int *ret_height)
0453
2018-10-04
omar.pol
{
0454
2019-10-18
omar.pol
int height, width;
0455
2019-10-18
omar.pol
XGlyphInfo gi;
0456
2018-10-04
omar.pol
XftTextExtentsUtf8(r->d, r->font, str, len, &gi);
0457
2018-10-04
omar.pol
height = r->font->ascent - r->font->descent;
0458
2018-10-04
omar.pol
width = gi.width - gi.x;
0459
2022-05-16
op
0460
2019-10-18
omar.pol
if (ret_width != NULL)
0461
2019-10-18
omar.pol
*ret_width = width;
0462
2019-10-18
omar.pol
if (ret_height != NULL)
0463
2019-10-18
omar.pol
*ret_height = height;
0464
2018-10-04
omar.pol
return width;
0465
2018-10-04
omar.pol
}
0466
2018-05-19
omar.pol
0467
2022-07-01
op
static void
0468
2022-05-21
op
draw_string(char *str, int len, int x, int y, struct rendering *r,
0469
2022-05-21
op
enum obj_type tt)
0470
2018-10-04
omar.pol
{
0471
2018-10-04
omar.pol
XftColor xftcolor;
0472
2019-10-18
omar.pol
if (tt == PROMPT)
0473
2019-10-18
omar.pol
xftcolor = r->xft_colors[0];
0474
2019-10-18
omar.pol
if (tt == COMPL)
0475
2019-10-18
omar.pol
xftcolor = r->xft_colors[1];
0476
2019-10-18
omar.pol
if (tt == COMPL_HIGH)
0477
2019-10-18
omar.pol
xftcolor = r->xft_colors[2];
0478
2018-05-19
omar.pol
0479
2018-10-04
omar.pol
XftDrawStringUtf8(r->xftdraw, &xftcolor, r->font, x, y, str, len);
0480
2018-10-04
omar.pol
}
0481
2018-05-21
omar.pol
0482
2018-10-04
omar.pol
/* Duplicate the string and substitute every space with a 'n` */
0483
2022-07-01
op
static char *
0484
2018-10-04
omar.pol
strdupn(char *str)
0485
2018-10-04
omar.pol
{
0486
2022-05-16
op
char *t, *dup;
0487
2018-05-21
omar.pol
0488
2022-05-21
op
if (str == NULL || *str == '\0')
0489
2018-10-04
omar.pol
return NULL;
0490
2018-07-07
omar.pol
0491
2018-10-06
omar.pol
if ((dup = strdup(str)) == NULL)
0492
2018-10-04
omar.pol
return NULL;
0493
2018-05-19
omar.pol
0494
2022-05-16
op
for (t = dup; *t; ++t) {
0495
2022-05-16
op
if (*t == ' ')
0496
2022-05-16
op
*t = 'n';
0497
2022-05-16
op
}
0498
2018-05-19
omar.pol
0499
2018-10-04
omar.pol
return dup;
0500
2018-05-19
omar.pol
}
0501
2018-05-19
omar.pol
0502
2022-07-01
op
static int
0503
2022-05-21
op
draw_v_box(struct rendering *r, int y, char *prefix, int prefix_width,
0504
2022-05-21
op
enum obj_type t, char *text)
0505
2018-10-04
omar.pol
{
0506
2019-10-18
omar.pol
GC *border_color, bg;
0507
2019-10-18
omar.pol
int *padding, *borders;
0508
2019-10-18
omar.pol
int ret = 0, inner_width, inner_height, x;
0509
2018-07-08
omar.pol
0510
2018-10-17
omar.pol
switch (t) {
0511
2018-10-17
omar.pol
case PROMPT:
0512
2019-10-18
omar.pol
border_color = r->p_borders_bg;
0513
2019-10-18
omar.pol
padding = r->p_padding;
0514
2019-10-18
omar.pol
borders = r->p_borders;
0515
2019-10-18
omar.pol
bg = r->bgs[0];
0516
2018-10-17
omar.pol
break;
0517
2018-10-17
omar.pol
case COMPL:
0518
2019-10-18
omar.pol
border_color = r->c_borders_bg;
0519
2019-10-18
omar.pol
padding = r->c_padding;
0520
2019-10-18
omar.pol
borders = r->c_borders;
0521
2019-10-18
omar.pol
bg = r->bgs[1];
0522
2018-10-17
omar.pol
break;
0523
2018-10-17
omar.pol
case COMPL_HIGH:
0524
2019-10-18
omar.pol
border_color = r->ch_borders_bg;
0525
2019-10-18
omar.pol
padding = r->ch_padding;
0526
2019-10-18
omar.pol
borders = r->ch_borders;
0527
2019-10-18
omar.pol
bg = r->bgs[2];
0528
2018-10-17
omar.pol
break;
0529
2018-10-17
omar.pol
}
0530
2018-07-08
omar.pol
0531
2019-10-20
omar.pol
ret = borders[0] + padding[0] + r->text_height + padding[2] + borders[2];
0532
2018-07-08
omar.pol
0533
2022-05-16
op
inner_width = INNER_WIDTH(r) - borders[1] - borders[3];
0534
2018-10-17
omar.pol
inner_height = padding[0] + r->text_height + padding[2];
0535
2018-10-04
omar.pol
0536
2018-10-17
omar.pol
/* Border top */
0537
2022-05-21
op
XFillRectangle(r->d, r->w, border_color[0], r->x_zero, y, r->width,
0538
2022-05-21
op
borders[0]);
0539
2018-10-04
omar.pol
0540
2018-10-17
omar.pol
/* Border right */
0541
2022-05-21
op
XFillRectangle(r->d, r->w, border_color[1],
0542
2022-05-21
op
r->x_zero + INNER_WIDTH(r) - borders[1], y, borders[1], ret);
0543
2018-10-17
omar.pol
0544
2018-10-17
omar.pol
/* Border bottom */
0545
2019-10-18
omar.pol
XFillRectangle(r->d, r->w, border_color[2], r->x_zero,
0546
2022-05-21
op
y + borders[0] + padding[0] + r->text_height + padding[2],
0547
2022-05-21
op
r->width, borders[2]);
0548
2018-10-04
omar.pol
0549
2018-10-17
omar.pol
/* Border left */
0550
2022-05-21
op
XFillRectangle(r->d, r->w, border_color[3], r->x_zero, y, borders[3],
0551
2022-05-21
op
ret);
0552
2018-10-04
omar.pol
0553
2018-10-17
omar.pol
/* bg */
0554
2018-10-17
omar.pol
x = r->x_zero + borders[3];
0555
2018-10-17
omar.pol
y += borders[0];
0556
2018-10-17
omar.pol
XFillRectangle(r->d, r->w, bg, x, y, inner_width, inner_height);
0557
2018-10-04
omar.pol
0558
2018-10-17
omar.pol
/* content */
0559
2018-10-17
omar.pol
y += padding[0] + r->text_height;
0560
2018-10-17
omar.pol
x += padding[3];
0561
2018-10-17
omar.pol
if (prefix != NULL) {
0562
2018-10-17
omar.pol
draw_string(prefix, strlen(prefix), x, y, r, t);
0563
2018-10-17
omar.pol
x += prefix_width;
0564
2018-10-17
omar.pol
}
0565
2018-10-17
omar.pol
draw_string(text, strlen(text), x, y, r, t);
0566
2018-10-04
omar.pol
0567
2018-10-17
omar.pol
return ret;
0568
2018-10-17
omar.pol
}
0569
2018-10-04
omar.pol
0570
2022-07-01
op
static int
0571
2022-05-21
op
draw_h_box(struct rendering *r, int x, char *prefix, int prefix_width,
0572
2022-05-21
op
enum obj_type t, char *text)
0573
2018-10-17
omar.pol
{
0574
2019-10-18
omar.pol
GC *border_color, bg;
0575
2019-10-18
omar.pol
int *padding, *borders;
0576
2019-10-18
omar.pol
int ret = 0, inner_width, inner_height, y, text_width;
0577
2018-10-17
omar.pol
0578
2018-10-17
omar.pol
switch (t) {
0579
2018-10-17
omar.pol
case PROMPT:
0580
2019-10-18
omar.pol
border_color = r->p_borders_bg;
0581
2019-10-18
omar.pol
padding = r->p_padding;
0582
2019-10-18
omar.pol
borders = r->p_borders;
0583
2019-10-18
omar.pol
bg = r->bgs[0];
0584
2018-10-17
omar.pol
break;
0585
2018-10-17
omar.pol
case COMPL:
0586
2019-10-18
omar.pol
border_color = r->c_borders_bg;
0587
2019-10-18
omar.pol
padding = r->c_padding;
0588
2019-10-18
omar.pol
borders = r->c_borders;
0589
2019-10-18
omar.pol
bg = r->bgs[1];
0590
2018-10-17
omar.pol
break;
0591
2018-10-17
omar.pol
case COMPL_HIGH:
0592
2019-10-18
omar.pol
border_color = r->ch_borders_bg;
0593
2019-10-18
omar.pol
padding = r->ch_padding;
0594
2019-10-18
omar.pol
borders = r->ch_borders;
0595
2019-10-18
omar.pol
bg = r->bgs[2];
0596
2018-10-17
omar.pol
break;
0597
2018-10-17
omar.pol
}
0598
2018-10-17
omar.pol
0599
2022-05-21
op
if (padding[0] < 0 || padding[2] < 0) {
0600
2022-05-21
op
padding[0] = INNER_HEIGHT(r) - borders[0] - borders[2]
0601
2022-05-21
op
- r->text_height;
0602
2022-05-21
op
padding[0] /= 2;
0603
2018-10-17
omar.pol
0604
2022-05-21
op
padding[2] = padding[0];
0605
2022-05-21
op
}
0606
2022-05-21
op
0607
2018-10-17
omar.pol
/* If they are still lesser than 0, set 'em to 0 */
0608
2018-10-17
omar.pol
if (padding[0] < 0 || padding[2] < 0)
0609
2018-10-17
omar.pol
padding[0] = padding[2] = 0;
0610
2018-10-17
omar.pol
0611
2018-10-17
omar.pol
/* Get the text width */
0612
2018-10-17
omar.pol
text_extents(text, strlen(text), r, &text_width, NULL);
0613
2018-10-17
omar.pol
if (prefix != NULL)
0614
2018-10-17
omar.pol
text_width += prefix_width;
0615
2018-10-17
omar.pol
0616
2018-10-17
omar.pol
ret = borders[3] + padding[3] + text_width + padding[1] + borders[1];
0617
2018-10-17
omar.pol
0618
2018-10-17
omar.pol
inner_width = padding[3] + text_width + padding[1];
0619
2022-05-16
op
inner_height = INNER_HEIGHT(r) - borders[0] - borders[2];
0620
2018-10-17
omar.pol
0621
2018-10-17
omar.pol
/* Border top */
0622
2022-05-21
op
XFillRectangle(r->d, r->w, border_color[0], x, r->y_zero, ret,
0623
2022-05-21
op
borders[0]);
0624
2018-10-17
omar.pol
0625
2018-10-17
omar.pol
/* Border right */
0626
2022-05-21
op
XFillRectangle(r->d, r->w, border_color[1],
0627
2022-05-21
op
x + borders[3] + inner_width, r->y_zero, borders[1],
0628
2022-05-21
op
INNER_HEIGHT(r));
0629
2018-10-17
omar.pol
0630
2018-10-17
omar.pol
/* Border bottom */
0631
2022-05-21
op
XFillRectangle(r->d, r->w, border_color[2], x,
0632
2022-05-21
op
r->y_zero + INNER_HEIGHT(r) - borders[2], ret,
0633
2022-05-21
op
borders[2]);
0634
2018-10-17
omar.pol
0635
2018-10-17
omar.pol
/* Border left */
0636
2022-05-21
op
XFillRectangle(r->d, r->w, border_color[3], x, r->y_zero, borders[3],
0637
2022-05-21
op
INNER_HEIGHT(r));
0638
2018-10-17
omar.pol
0639
2018-10-17
omar.pol
/* bg */
0640
2018-10-17
omar.pol
x += borders[3];
0641
2018-10-17
omar.pol
y = r->y_zero + borders[0];
0642
2018-10-17
omar.pol
XFillRectangle(r->d, r->w, bg, x, y, inner_width, inner_height);
0643
2018-10-17
omar.pol
0644
2018-10-17
omar.pol
/* content */
0645
2018-10-17
omar.pol
y += padding[0] + r->text_height;
0646
2018-10-17
omar.pol
x += padding[3];
0647
2018-10-17
omar.pol
if (prefix != NULL) {
0648
2018-10-17
omar.pol
draw_string(prefix, strlen(prefix), x, y, r, t);
0649
2018-10-17
omar.pol
x += prefix_width;
0650
2018-10-04
omar.pol
}
0651
2018-10-17
omar.pol
draw_string(text, strlen(text), x, y, r, t);
0652
2018-10-17
omar.pol
0653
2018-10-17
omar.pol
return ret;
0654
2018-05-19
omar.pol
}
0655
2018-05-19
omar.pol
0656
2022-05-21
op
/*
0657
2022-05-21
op
* ,-----------------------------------------------------------------,
0658
2022-05-21
op
* | 20 char text | completion | completion | completion | compl |
0659
2022-05-21
op
* `-----------------------------------------------------------------'
0660
2022-05-21
op
*/
0661
2022-07-01
op
static void
0662
2018-10-17
omar.pol
draw_horizontally(struct rendering *r, char *text, struct completions *cs)
0663
2018-10-17
omar.pol
{
0664
2019-10-18
omar.pol
size_t i;
0665
2019-10-18
omar.pol
int x = r->x_zero;
0666
2018-10-17
omar.pol
0667
2018-10-17
omar.pol
/* Draw the prompt */
0668
2018-10-17
omar.pol
x += draw_h_box(r, x, r->ps1, r->ps1w, PROMPT, text);
0669
2018-10-17
omar.pol
0670
2018-10-17
omar.pol
for (i = r->offset; i < cs->length; ++i) {
0671
2022-05-21
op
enum obj_type t;
0672
2018-10-17
omar.pol
0673
2022-05-21
op
if (cs->selected == (ssize_t)i)
0674
2022-05-21
op
t = COMPL_HIGH;
0675
2022-05-21
op
else
0676
2022-05-21
op
t = COMPL;
0677
2022-05-21
op
0678
2019-10-19
omar.pol
cs->completions[i].offset = x;
0679
2019-10-19
omar.pol
0680
2022-05-21
op
x += draw_h_box(r, x, NULL, 0, t,
0681
2022-05-21
op
cs->completions[i].completion);
0682
2018-10-17
omar.pol
0683
2022-05-16
op
if (x > INNER_WIDTH(r))
0684
2018-10-17
omar.pol
break;
0685
2018-10-17
omar.pol
}
0686
2019-10-19
omar.pol
0687
2019-10-19
omar.pol
for (i += 1; i < cs->length; ++i)
0688
2019-10-19
omar.pol
cs->completions[i].offset = -1;
0689
2018-10-17
omar.pol
}
0690
2018-10-17
omar.pol
0691
2022-05-21
op
/*
0692
2022-05-21
op
* ,-----------------------------------------------------------------,
0693
2022-05-21
op
* | prompt |
0694
2022-05-21
op
* |-----------------------------------------------------------------|
0695
2022-05-21
op
* | completion |
0696
2022-05-21
op
* |-----------------------------------------------------------------|
0697
2022-05-21
op
* | completion |
0698
2022-05-21
op
* `-----------------------------------------------------------------'
0699
2022-05-21
op
*/
0700
2022-07-01
op
static void
0701
2018-10-04
omar.pol
draw_vertically(struct rendering *r, char *text, struct completions *cs)
0702
2018-10-04
omar.pol
{
0703
2019-10-18
omar.pol
size_t i;
0704
2019-10-18
omar.pol
int y = r->y_zero;
0705
2018-05-18
omar.pol
0706
2018-10-17
omar.pol
y += draw_v_box(r, y, r->ps1, r->ps1w, PROMPT, text);
0707
2018-05-18
omar.pol
0708
2018-10-04
omar.pol
for (i = r->offset; i < cs->length; ++i) {
0709
2022-05-21
op
enum obj_type t;
0710
2018-10-04
omar.pol
0711
2022-05-21
op
if (cs->selected == (ssize_t)i)
0712
2022-05-21
op
t = COMPL_HIGH;
0713
2022-05-21
op
else
0714
2022-05-21
op
t = COMPL;
0715
2022-05-21
op
0716
2019-10-19
omar.pol
cs->completions[i].offset = y;
0717
2019-10-19
omar.pol
0718
2022-05-21
op
y += draw_v_box(r, y, NULL, 0, t,
0719
2022-05-21
op
cs->completions[i].completion);
0720
2018-10-04
omar.pol
0721
2022-05-16
op
if (y > INNER_HEIGHT(r))
0722
2018-10-17
omar.pol
break;
0723
2018-10-04
omar.pol
}
0724
2019-10-19
omar.pol
0725
2019-10-19
omar.pol
for (i += 1; i < cs->length; ++i)
0726
2019-10-19
omar.pol
cs->completions[i].offset = -1;
0727
2018-05-18
omar.pol
}
0728
2018-05-18
omar.pol
0729
2022-07-01
op
static void
0730
2018-10-04
omar.pol
draw(struct rendering *r, char *text, struct completions *cs)
0731
2018-10-04
omar.pol
{
0732
2018-10-17
omar.pol
/* Draw the background */
0733
2022-05-21
op
XFillRectangle(r->d, r->w, r->bgs[1], r->x_zero, r->y_zero,
0734
2022-05-21
op
INNER_WIDTH(r), INNER_HEIGHT(r));
0735
2018-10-17
omar.pol
0736
2018-10-17
omar.pol
/* Draw the contents */
0737
2018-10-04
omar.pol
if (r->horizontal_layout)
0738
2018-10-04
omar.pol
draw_horizontally(r, text, cs);
0739
2018-10-04
omar.pol
else
0740
2018-10-04
omar.pol
draw_vertically(r, text, cs);
0741
2018-10-04
omar.pol
0742
2018-10-04
omar.pol
/* Draw the borders */
0743
2018-10-09
omar.pol
if (r->borders[0] != 0)
0744
2022-05-21
op
XFillRectangle(r->d, r->w, r->borders_bg[0], 0, 0, r->width,
0745
2022-05-21
op
r->borders[0]);
0746
2018-10-04
omar.pol
0747
2018-10-09
omar.pol
if (r->borders[1] != 0)
0748
2022-05-21
op
XFillRectangle(r->d, r->w, r->borders_bg[1],
0749
2022-05-21
op
r->width - r->borders[1], 0, r->borders[1],
0750
2022-05-21
op
r->height);
0751
2018-10-04
omar.pol
0752
2018-10-09
omar.pol
if (r->borders[2] != 0)
0753
2022-05-21
op
XFillRectangle(r->d, r->w, r->borders_bg[2], 0,
0754
2022-05-21
op
r->height - r->borders[2], r->width, r->borders[2]);
0755
2018-10-04
omar.pol
0756
2018-10-09
omar.pol
if (r->borders[3] != 0)
0757
2022-05-21
op
XFillRectangle(r->d, r->w, r->borders_bg[3], 0, 0,
0758
2022-05-21
op
r->borders[3], r->height);
0759
2018-10-09
omar.pol
0760
2018-10-04
omar.pol
/* render! */
0761
2018-10-04
omar.pol
XFlush(r->d);
0762
2018-10-04
omar.pol
}
0763
2018-10-04
omar.pol
0764
2018-10-04
omar.pol
/* Set some WM stuff */
0765
2022-07-01
op
static void
0766
2018-10-04
omar.pol
set_win_atoms_hints(Display *d, Window w, int width, int height)
0767
2018-10-04
omar.pol
{
0768
2019-10-18
omar.pol
Atom type;
0769
2019-10-18
omar.pol
XClassHint *class_hint;
0770
2019-10-18
omar.pol
XSizeHints *size_hint;
0771
2018-10-04
omar.pol
0772
2018-10-04
omar.pol
type = XInternAtom(d, "_NET_WM_WINDOW_TYPE_DOCK", 0);
0773
2022-05-21
op
XChangeProperty(d, w, XInternAtom(d, "_NET_WM_WINDOW_TYPE", 0),
0774
2022-05-21
op
XInternAtom(d, "ATOM", 0), 32, PropModeReplace,
0775
2022-05-21
op
(unsigned char *)&type, 1);
0776
2018-10-04
omar.pol
0777
2018-10-04
omar.pol
/* some window managers honor this properties */
0778
2018-10-04
omar.pol
type = XInternAtom(d, "_NET_WM_STATE_ABOVE", 0);
0779
2022-05-21
op
XChangeProperty(d, w, XInternAtom(d, "_NET_WM_STATE", 0),
0780
2022-05-21
op
XInternAtom(d, "ATOM", 0), 32, PropModeReplace,
0781
2022-05-21
op
(unsigned char *)&type, 1);
0782
2018-10-04
omar.pol
0783
2018-10-04
omar.pol
type = XInternAtom(d, "_NET_WM_STATE_FOCUSED", 0);
0784
2022-05-21
op
XChangeProperty(d, w, XInternAtom(d, "_NET_WM_STATE", 0),
0785
2022-05-21
op
XInternAtom(d, "ATOM", 0), 32, PropModeAppend,
0786
2022-05-21
op
(unsigned char *)&type, 1);
0787
2018-10-04
omar.pol
0788
2018-10-04
omar.pol
/* Setting window hints */
0789
2018-10-04
omar.pol
class_hint = XAllocClassHint();
0790
2018-10-04
omar.pol
if (class_hint == NULL) {
0791
2018-10-04
omar.pol
fprintf(stderr, "Could not allocate memory for class hint\n");
0792
2018-10-04
omar.pol
exit(EX_UNAVAILABLE);
0793
2018-10-04
omar.pol
}
0794
2018-10-06
omar.pol
0795
2022-05-16
op
class_hint->res_name = RESNAME;
0796
2022-05-16
op
class_hint->res_class = RESCLASS;
0797
2018-10-04
omar.pol
XSetClassHint(d, w, class_hint);
0798
2018-10-04
omar.pol
XFree(class_hint);
0799
2018-07-15
omar.pol
0800
2018-10-04
omar.pol
size_hint = XAllocSizeHints();
0801
2018-10-04
omar.pol
if (size_hint == NULL) {
0802
2018-10-04
omar.pol
fprintf(stderr, "Could not allocate memory for size hint\n");
0803
2018-10-04
omar.pol
exit(EX_UNAVAILABLE);
0804
2018-10-04
omar.pol
}
0805
2018-10-06
omar.pol
0806
2018-10-04
omar.pol
size_hint->flags = PMinSize | PBaseSize;
0807
2018-10-04
omar.pol
size_hint->min_width = width;
0808
2018-10-04
omar.pol
size_hint->base_width = width;
0809
2018-10-04
omar.pol
size_hint->min_height = height;
0810
2018-10-04
omar.pol
size_hint->base_height = height;
0811
2018-05-18
omar.pol
0812
2018-10-04
omar.pol
XFlush(d);
0813
2018-05-18
omar.pol
}
0814
2018-05-18
omar.pol
0815
2018-10-04
omar.pol
/* Get the width and height of the window `w' */
0816
2022-07-01
op
static void
0817
2018-10-04
omar.pol
get_wh(Display *d, Window *w, int *width, int *height)
0818
2018-10-04
omar.pol
{
0819
2018-10-04
omar.pol
XWindowAttributes win_attr;
0820
2018-10-04
omar.pol
0821
2018-10-04
omar.pol
XGetWindowAttributes(d, *w, &win_attr);
0822
2018-10-04
omar.pol
*height = win_attr.height;
0823
2018-10-04
omar.pol
*width = win_attr.width;
0824
2022-05-21
op
}
0825
2022-05-21
op
0826
2022-05-21
op
/* find the current xinerama monitor if possible */
0827
2022-07-01
op
static void
0828
2022-05-21
op
findmonitor(Display *d, int *x, int *y, int *width, int *height)
0829
2022-05-21
op
{
0830
2022-05-21
op
XineramaScreenInfo *info;
0831
2022-05-21
op
Window rr;
0832
2022-05-21
op
Window root;
0833
2022-05-21
op
int screens, monitors, i;
0834
2022-05-21
op
int rootx, rooty, winx, winy;
0835
2022-05-21
op
unsigned int mask;
0836
2022-05-21
op
short res;
0837
2022-05-21
op
0838
2022-05-21
op
if (!XineramaIsActive(d))
0839
2022-05-21
op
return;
0840
2022-05-21
op
0841
2022-05-21
op
screens = XScreenCount(d);
0842
2022-05-21
op
for (i = 0; i < screens; ++i) {
0843
2022-05-21
op
root = XRootWindow(d, i);
0844
2022-05-21
op
res = XQueryPointer(d, root, &rr, &rr, &rootx, &rooty, &winx,
0845
2022-05-21
op
&winy, &mask);
0846
2022-05-21
op
if (res)
0847
2022-05-21
op
break;
0848
2022-05-21
op
}
0849
2022-05-21
op
0850
2022-05-21
op
if (!res)
0851
2022-05-21
op
return;
0852
2022-05-21
op
0853
2022-05-21
op
/* Now find in which monitor the mice is */
0854
2022-05-21
op
info = XineramaQueryScreens(d, &monitors);
0855
2022-05-21
op
if (info == NULL)
0856
2022-05-21
op
return;
0857
2022-05-21
op
0858
2022-05-21
op
for (i = 0; i < monitors; ++i) {
0859
2022-05-21
op
if (info[i].x_org <= rootx &&
0860
2022-05-21
op
rootx <= (info[i].x_org + info[i].width) &&
0861
2022-05-21
op
info[i].y_org <= rooty &&
0862
2022-05-21
op
rooty <= (info[i].y_org + info[i].height)) {
0863
2022-05-21
op
*x = info[i].x_org;
0864
2022-05-21
op
*y = info[i].y_org;
0865
2022-05-21
op
*width = info[i].width;
0866
2022-05-21
op
*height = info[i].height;
0867
2022-05-21
op
break;
0868
2022-05-21
op
}
0869
2022-05-21
op
}
0870
2022-05-21
op
0871
2022-05-21
op
XFree(info);
0872
2018-09-13
omar.pol
}
0873
2018-09-13
omar.pol
0874
2022-07-01
op
static int
0875
2018-10-04
omar.pol
grabfocus(Display *d, Window w)
0876
2018-10-04
omar.pol
{
0877
2019-10-18
omar.pol
int i;
0878
2018-10-04
omar.pol
for (i = 0; i < 100; ++i) {
0879
2018-10-04
omar.pol
Window focuswin;
0880
2018-10-04
omar.pol
int revert_to_win;
0881
2018-09-13
omar.pol
0882
2018-10-04
omar.pol
XGetInputFocus(d, &focuswin, &revert_to_win);
0883
2018-09-13
omar.pol
0884
2018-10-04
omar.pol
if (focuswin == w)
0885
2018-10-04
omar.pol
return 1;
0886
2018-09-13
omar.pol
0887
2018-10-04
omar.pol
XSetInputFocus(d, w, RevertToParent, CurrentTime);
0888
2018-10-04
omar.pol
usleep(1000);
0889
2018-10-04
omar.pol
}
0890
2018-10-04
omar.pol
return 0;
0891
2018-10-04
omar.pol
}
0892
2018-09-13
omar.pol
0893
2019-10-18
omar.pol
/*
0894
2018-10-04
omar.pol
* I know this may seem a little hackish BUT is the only way I managed
0895
2018-10-04
omar.pol
* to actually grab that goddam keyboard. Only one call to
0896
2018-10-04
omar.pol
* XGrabKeyboard does not always end up with the keyboard grabbed!
0897
2018-10-04
omar.pol
*/
0898
2022-07-01
op
static int
0899
2018-10-04
omar.pol
take_keyboard(Display *d, Window w)
0900
2018-10-04
omar.pol
{
0901
2018-10-04
omar.pol
int i;
0902
2018-10-04
omar.pol
for (i = 0; i < 100; i++) {
0903
2022-05-21
op
if (XGrabKeyboard(d, w, 1, GrabModeAsync, GrabModeAsync,
0904
2022-05-21
op
CurrentTime) == GrabSuccess)
0905
2018-10-04
omar.pol
return 1;
0906
2018-10-04
omar.pol
usleep(1000);
0907
2018-10-04
omar.pol
}
0908
2018-10-04
omar.pol
fprintf(stderr, "Cannot grab keyboard\n");
0909
2018-10-04
omar.pol
return 0;
0910
2018-05-18
omar.pol
}
0911
2018-05-18
omar.pol
0912
2022-07-01
op
static unsigned long
0913
2018-10-04
omar.pol
parse_color(const char *str, const char *def)
0914
2018-10-04
omar.pol
{
0915
2018-10-04
omar.pol
size_t len;
0916
2018-10-04
omar.pol
rgba_t tmp;
0917
2018-10-04
omar.pol
char *ep;
0918
2018-05-22
omar.pol
0919
2018-10-04
omar.pol
if (str == NULL)
0920
2022-05-21
op
goto err;
0921
2018-05-18
omar.pol
0922
2018-10-04
omar.pol
len = strlen(str);
0923
2018-05-18
omar.pol
0924
2018-10-04
omar.pol
/* +1 for the # ath the start */
0925
2018-10-04
omar.pol
if (*str != '#' || len > 9 || len < 4)
0926
2022-05-21
op
goto err;
0927
2019-10-18
omar.pol
++str; /* skip the # */
0928
2018-07-08
omar.pol
0929
2018-10-04
omar.pol
errno = 0;
0930
2018-10-04
omar.pol
tmp = (rgba_t)(uint32_t)strtoul(str, &ep, 16);
0931
2018-07-08
omar.pol
0932
2018-10-04
omar.pol
if (errno)
0933
2022-05-21
op
goto err;
0934
2018-07-08
omar.pol
0935
2019-10-18
omar.pol
switch (len - 1) {
0936
2018-10-04
omar.pol
case 3:
0937
2018-10-04
omar.pol
/* expand #rgb -> #rrggbb */
0938
2019-10-18
omar.pol
tmp.v = (tmp.v & 0xf00) * 0x1100 | (tmp.v & 0x0f0) * 0x0110
0939
2018-10-04
omar.pol
| (tmp.v & 0x00f) * 0x0011;
0940
2022-07-02
op
/* fallthrough */
0941
2018-10-04
omar.pol
case 6:
0942
2018-10-04
omar.pol
/* assume 0xff opacity */
0943
2018-10-06
omar.pol
tmp.rgba.a = 0xff;
0944
2018-10-04
omar.pol
break;
0945
2018-10-04
omar.pol
} /* colors in #aarrggbb need no adjustments */
0946
2018-07-08
omar.pol
0947
2018-10-04
omar.pol
/* premultiply the alpha */
0948
2018-10-06
omar.pol
if (tmp.rgba.a) {
0949
2018-10-06
omar.pol
tmp.rgba.r = (tmp.rgba.r * tmp.rgba.a) / 255;
0950
2018-10-06
omar.pol
tmp.rgba.g = (tmp.rgba.g * tmp.rgba.a) / 255;
0951
2018-10-06
omar.pol
tmp.rgba.b = (tmp.rgba.b * tmp.rgba.a) / 255;
0952
2018-10-04
omar.pol
return tmp.v;
0953
2018-10-04
omar.pol
}
0954
2018-07-08
omar.pol
0955
2018-10-04
omar.pol
return 0U;
0956
2018-07-08
omar.pol
0957
2022-05-21
op
err:
0958
2018-10-04
omar.pol
fprintf(stderr, "Invalid color: \"%s\".\n", str);
0959
2018-10-04
omar.pol
if (def != NULL)
0960
2018-10-04
omar.pol
return parse_color(def, NULL);
0961
2018-10-04
omar.pol
else
0962
2018-10-04
omar.pol
return 0U;
0963
2018-10-04
omar.pol
}
0964
2018-07-08
omar.pol
0965
2019-10-18
omar.pol
/*
0966
2022-05-16
op
* Given a string try to parse it as a number or return `def'.
0967
2018-10-04
omar.pol
*/
0968
2022-07-01
op
static int
0969
2022-05-16
op
parse_integer(const char *str, int def)
0970
2018-10-04
omar.pol
{
0971
2022-05-16
op
const char *errstr;
0972
2022-05-16
op
int i;
0973
2018-07-08
omar.pol
0974
2022-05-16
op
i = strtonum(str, INT_MIN, INT_MAX, &errstr);
0975
2022-05-16
op
if (errstr != NULL) {
0976
2022-05-16
op
warnx("'%s' is %s; using %d as default", str, errstr, def);
0977
2022-05-16
op
return def;
0978
2018-10-04
omar.pol
}
0979
2018-10-04
omar.pol
0980
2022-05-16
op
return i;
0981
2018-07-08
omar.pol
}
0982
2018-07-08
omar.pol
0983
2022-05-21
op
/*
0984
2022-05-21
op
* Like parse_integer but recognize the percentages (i.e. strings
0985
2022-05-21
op
* ending with `%')
0986
2022-05-21
op
*/
0987
2022-07-01
op
static int
0988
2018-10-04
omar.pol
parse_int_with_percentage(const char *str, int default_value, int max)
0989
2018-10-04
omar.pol
{
0990
2018-10-04
omar.pol
int len = strlen(str);
0991
2018-06-30
omar.pol
0992
2019-10-18
omar.pol
if (len > 0 && str[len - 1] == '%') {
0993
2018-10-04
omar.pol
int val;
0994
2018-10-04
omar.pol
char *cpy;
0995
2018-06-30
omar.pol
0996
2019-10-19
omar.pol
if ((cpy = strdup(str)) == NULL)
0997
2019-10-19
omar.pol
err(1, "strdup");
0998
2019-10-19
omar.pol
0999
2019-10-18
omar.pol
cpy[len - 1] = '\0';
1000
2018-10-04
omar.pol
val = parse_integer(cpy, default_value);
1001
2018-10-04
omar.pol
free(cpy);
1002
2018-10-04
omar.pol
return val * max / 100;
1003
2018-10-04
omar.pol
}
1004
2018-10-06
omar.pol
1005
2018-10-04
omar.pol
return parse_integer(str, default_value);
1006
2018-06-30
omar.pol
}
1007
2019-10-20
omar.pol
1008
2022-07-01
op
static void
1009
2019-10-20
omar.pol
get_mouse_coords(Display *d, int *x, int *y)
1010
2019-10-20
omar.pol
{
1011
2019-10-20
omar.pol
Window w, root;
1012
2019-10-20
omar.pol
int i;
1013
2019-10-20
omar.pol
unsigned int u;
1014
2018-06-30
omar.pol
1015
2019-10-20
omar.pol
*x = *y = 0;
1016
2019-10-20
omar.pol
root = DefaultRootWindow(d);
1017
2019-10-20
omar.pol
1018
2019-10-20
omar.pol
if (!XQueryPointer(d, root, &root, &w, x, y, &i, &i, &u)) {
1019
2019-10-20
omar.pol
for (i = 0; i < ScreenCount(d); ++i) {
1020
2019-10-20
omar.pol
if (root == RootWindow(d, i))
1021
2019-10-20
omar.pol
break;
1022
2019-10-20
omar.pol
}
1023
2019-10-20
omar.pol
}
1024
2019-10-20
omar.pol
}
1025
2019-10-20
omar.pol
1026
2019-10-18
omar.pol
/*
1027
2018-10-04
omar.pol
* Like parse_int_with_percentage but understands some special values:
1028
2018-10-04
omar.pol
* - middle that is (max-self)/2
1029
2019-10-20
omar.pol
* - center = middle
1030
2018-10-04
omar.pol
* - start that is 0
1031
2018-10-04
omar.pol
* - end that is (max-self)
1032
2019-10-20
omar.pol
* - mx x coordinate of the mouse
1033
2019-10-20
omar.pol
* - my y coordinate of the mouse
1034
2018-10-04
omar.pol
*/
1035
2022-07-01
op
static int
1036
2022-05-21
op
parse_int_with_pos(Display *d, const char *str, int default_value, int max,
1037
2022-05-21
op
int self)
1038
2018-10-04
omar.pol
{
1039
2018-10-04
omar.pol
if (!strcmp(str, "start"))
1040
2018-10-04
omar.pol
return 0;
1041
2019-10-18
omar.pol
if (!strcmp(str, "middle") || !strcmp(str, "center"))
1042
2019-10-18
omar.pol
return (max - self) / 2;
1043
2018-10-04
omar.pol
if (!strcmp(str, "end"))
1044
2019-10-18
omar.pol
return max - self;
1045
2019-10-20
omar.pol
if (!strcmp(str, "mx") || !strcmp(str, "my")) {
1046
2019-10-20
omar.pol
int x, y;
1047
2019-10-20
omar.pol
1048
2019-10-20
omar.pol
get_mouse_coords(d, &x, &y);
1049
2019-10-20
omar.pol
if (!strcmp(str, "mx"))
1050
2019-10-20
omar.pol
return x - 1;
1051
2019-10-20
omar.pol
else
1052
2019-10-20
omar.pol
return y - 1;
1053
2019-10-20
omar.pol
}
1054
2018-10-04
omar.pol
return parse_int_with_percentage(str, default_value, max);
1055
2018-08-13
omar.pol
}
1056
2018-08-13
omar.pol
1057
2018-10-04
omar.pol
/* Parse a string like a CSS value. */
1058
2018-10-04
omar.pol
/* TODO: harden a bit this function */
1059
2022-07-01
op
static int
1060
2022-05-23
op
parse_csslike(const char *str, char **ret)
1061
2018-10-04
omar.pol
{
1062
2019-10-18
omar.pol
int i, j;
1063
2022-05-23
op
char *s, *token;
1064
2019-10-18
omar.pol
short any_null;
1065
2018-08-13
omar.pol
1066
2022-05-23
op
memset(ret, 0, 4 * sizeof(*ret));
1067
2022-05-23
op
1068
2018-10-04
omar.pol
s = strdup(str);
1069
2018-10-04
omar.pol
if (s == NULL)
1070
2022-05-23
op
return -1;
1071
2018-08-13
omar.pol
1072
2018-10-06
omar.pol
for (i = 0; (token = strsep(&s, " ")) != NULL && i < 4; ++i)
1073
2018-10-04
omar.pol
ret[i] = strdup(token);
1074
2018-08-13
omar.pol
1075
2018-10-04
omar.pol
if (i == 1)
1076
2018-10-06
omar.pol
for (j = 1; j < 4; j++)
1077
2018-10-04
omar.pol
ret[j] = strdup(ret[0]);
1078
2018-08-13
omar.pol
1079
2018-10-04
omar.pol
if (i == 2) {
1080
2018-10-04
omar.pol
ret[2] = strdup(ret[0]);
1081
2018-10-04
omar.pol
ret[3] = strdup(ret[1]);
1082
2018-10-04
omar.pol
}
1083
2018-08-13
omar.pol
1084
2018-10-04
omar.pol
if (i == 3)
1085
2018-10-04
omar.pol
ret[3] = strdup(ret[1]);
1086
2018-08-13
omar.pol
1087
2022-05-21
op
/*
1088
2022-05-21
op
* before we didn't check for the return type of strdup, here
1089
2022-05-21
op
* we will
1090
2019-10-18
omar.pol
*/
1091
2018-08-13
omar.pol
1092
2018-10-04
omar.pol
any_null = 0;
1093
2018-10-04
omar.pol
for (i = 0; i < 4; ++i)
1094
2018-10-04
omar.pol
any_null = ret[i] == NULL || any_null;
1095
2018-08-13
omar.pol
1096
2018-10-04
omar.pol
if (any_null)
1097
2018-10-04
omar.pol
for (i = 0; i < 4; ++i)
1098
2022-05-23
op
free(ret[i]);
1099
2018-08-13
omar.pol
1100
2018-10-04
omar.pol
if (i == 0 || any_null) {
1101
2018-10-04
omar.pol
free(s);
1102
2022-05-23
op
return -1;
1103
2018-10-04
omar.pol
}
1104
2018-08-13
omar.pol
1105
2022-05-23
op
return 1;
1106
2018-10-04
omar.pol
}
1107
2018-08-13
omar.pol
1108
2019-10-18
omar.pol
/*
1109
2018-10-04
omar.pol
* Given an event, try to understand what the users wants. If the
1110
2018-10-04
omar.pol
* return value is ADD_CHAR then `input' is a pointer to a string that
1111
2018-10-04
omar.pol
* will need to be free'ed later.
1112
2018-10-04
omar.pol
*/
1113
2022-07-01
op
static enum action
1114
2019-10-18
omar.pol
parse_event(Display *d, XKeyPressedEvent *ev, XIC xic, char **input)
1115
2018-10-04
omar.pol
{
1116
2019-10-18
omar.pol
char str[SYM_BUF_SIZE] = { 0 };
1117
2019-10-18
omar.pol
Status s;
1118
2018-08-13
omar.pol
1119
2018-10-04
omar.pol
if (ev->keycode == XKeysymToKeycode(d, XK_BackSpace))
1120
2018-10-04
omar.pol
return DEL_CHAR;
1121
2018-08-13
omar.pol
1122
2018-10-04
omar.pol
if (ev->keycode == XKeysymToKeycode(d, XK_Tab))
1123
2018-10-04
omar.pol
return ev->state & ShiftMask ? PREV_COMPL : NEXT_COMPL;
1124
2018-08-13
omar.pol
1125
2018-10-04
omar.pol
if (ev->keycode == XKeysymToKeycode(d, XK_Return))
1126
2018-10-04
omar.pol
return CONFIRM;
1127
2018-08-13
omar.pol
1128
2018-10-04
omar.pol
if (ev->keycode == XKeysymToKeycode(d, XK_Escape))
1129
2018-10-04
omar.pol
return EXIT;
1130
2018-08-13
omar.pol
1131
2018-10-04
omar.pol
/* Try to read what key was pressed */
1132
2018-10-04
omar.pol
s = 0;
1133
2018-10-04
omar.pol
Xutf8LookupString(xic, ev, str, SYM_BUF_SIZE, 0, &s);
1134
2018-10-04
omar.pol
if (s == XBufferOverflow) {
1135
2019-10-18
omar.pol
fprintf(stderr,
1136
2022-05-21
op
"Buffer overflow when trying to create keyboard "
1137
2022-05-21
op
"symbol map.\n");
1138
2018-10-04
omar.pol
return EXIT;
1139
2018-10-04
omar.pol
}
1140
2018-08-13
omar.pol
1141
2018-10-04
omar.pol
if (ev->state & ControlMask) {
1142
2018-10-04
omar.pol
if (!strcmp(str, "")) /* C-u */
1143
2018-10-04
omar.pol
return DEL_LINE;
1144
2018-10-04
omar.pol
if (!strcmp(str, "")) /* C-w */
1145
2018-10-04
omar.pol
return DEL_WORD;
1146
2018-10-04
omar.pol
if (!strcmp(str, "")) /* C-h */
1147
2018-10-04
omar.pol
return DEL_CHAR;
1148
2018-10-04
omar.pol
if (!strcmp(str, "\r")) /* C-m */
1149
2018-10-04
omar.pol
return CONFIRM_CONTINUE;
1150
2018-10-04
omar.pol
if (!strcmp(str, "")) /* C-p */
1151
2018-10-04
omar.pol
return PREV_COMPL;
1152
2018-10-04
omar.pol
if (!strcmp(str, "")) /* C-n */
1153
2018-10-04
omar.pol
return NEXT_COMPL;
1154
2018-10-04
omar.pol
if (!strcmp(str, "")) /* C-c */
1155
2018-10-04
omar.pol
return EXIT;
1156
2018-10-04
omar.pol
if (!strcmp(str, "\t")) /* C-i */
1157
2018-10-04
omar.pol
return TOGGLE_FIRST_SELECTED;
1158
2018-10-04
omar.pol
}
1159
2018-08-13
omar.pol
1160
2018-10-04
omar.pol
*input = strdup(str);
1161
2018-10-04
omar.pol
if (*input == NULL) {
1162
2018-10-04
omar.pol
fprintf(stderr, "Error while allocating memory for key.\n");
1163
2018-10-04
omar.pol
return EXIT;
1164
2018-10-04
omar.pol
}
1165
2018-08-13
omar.pol
1166
2018-10-04
omar.pol
return ADD_CHAR;
1167
2018-10-04
omar.pol
}
1168
2018-08-13
omar.pol
1169
2022-07-01
op
static void
1170
2022-05-21
op
confirm(enum state *status, struct rendering *r, struct completions *cs,
1171
2022-05-21
op
char **text, int *textlen)
1172
2018-10-04
omar.pol
{
1173
2018-10-04
omar.pol
if ((cs->selected != -1) || (cs->length > 0 && r->first_selected)) {
1174
2018-10-04
omar.pol
/* if there is something selected expand it and return */
1175
2018-10-04
omar.pol
int index = cs->selected == -1 ? 0 : cs->selected;
1176
2018-10-04
omar.pol
struct completion *c = cs->completions;
1177
2018-10-04
omar.pol
char *t;
1178
2018-08-13
omar.pol
1179
2018-10-04
omar.pol
while (1) {
1180
2018-10-04
omar.pol
if (index == 0)
1181
2018-10-04
omar.pol
break;
1182
2018-10-04
omar.pol
c++;
1183
2018-10-04
omar.pol
index--;
1184
2018-10-04
omar.pol
}
1185
2018-08-13
omar.pol
1186
2018-10-04
omar.pol
t = c->rcompletion;
1187
2018-10-04
omar.pol
free(*text);
1188
2018-10-04
omar.pol
*text = strdup(t);
1189
2018-08-13
omar.pol
1190
2018-10-04
omar.pol
if (*text == NULL) {
1191
2018-10-04
omar.pol
fprintf(stderr, "Memory allocation error\n");
1192
2018-10-04
omar.pol
*status = ERR;
1193
2018-10-04
omar.pol
}
1194
2018-08-13
omar.pol
1195
2018-10-04
omar.pol
*textlen = strlen(*text);
1196
2018-10-04
omar.pol
return;
1197
2018-10-04
omar.pol
}
1198
2018-10-04
omar.pol
1199
2018-10-04
omar.pol
if (!r->free_text) /* cannot accept arbitrary text */
1200
2018-10-04
omar.pol
*status = LOOPING;
1201
2019-10-19
omar.pol
}
1202
2019-10-19
omar.pol
1203
2022-05-21
op
/*
1204
2022-05-21
op
* cs: completion list
1205
2019-10-19
omar.pol
* offset: the offset of the click
1206
2019-10-19
omar.pol
* first: the first (rendered) item
1207
2019-10-19
omar.pol
* def: the default action
1208
2019-10-19
omar.pol
*/
1209
2022-07-01
op
static enum action
1210
2022-07-01
op
select_clicked(struct completions *cs, ssize_t offset, size_t first,
1211
2022-05-21
op
enum action def)
1212
2019-10-19
omar.pol
{
1213
2019-10-19
omar.pol
ssize_t selected = first;
1214
2019-10-19
omar.pol
int set = 0;
1215
2019-10-19
omar.pol
1216
2019-10-19
omar.pol
if (cs->length == 0)
1217
2019-10-19
omar.pol
return NO_OP;
1218
2019-10-19
omar.pol
1219
2019-10-19
omar.pol
if (offset < cs->completions[selected].offset)
1220
2019-10-20
omar.pol
return EXIT;
1221
2019-10-19
omar.pol
1222
2019-10-19
omar.pol
/* skip the first entry */
1223
2022-07-01
op
for (selected += 1; selected < (ssize_t)cs->length; ++selected) {
1224
2019-10-19
omar.pol
if (cs->completions[selected].offset == -1)
1225
2019-10-19
omar.pol
break;
1226
2019-10-19
omar.pol
1227
2019-10-19
omar.pol
if (offset < cs->completions[selected].offset) {
1228
2019-10-19
omar.pol
cs->selected = selected - 1;
1229
2019-10-19
omar.pol
set = 1;
1230
2019-10-19
omar.pol
break;
1231
2019-10-19
omar.pol
}
1232
2019-10-19
omar.pol
}
1233
2019-10-19
omar.pol
1234
2019-10-19
omar.pol
if (!set)
1235
2019-10-19
omar.pol
cs->selected = selected - 1;
1236
2019-10-19
omar.pol
1237
2019-10-19
omar.pol
return def;
1238
2019-10-19
omar.pol
}
1239
2019-10-19
omar.pol
1240
2022-07-01
op
static enum action
1241
2022-05-21
op
handle_mouse(struct rendering *r, struct completions *cs,
1242
2022-05-21
op
XButtonPressedEvent *e)
1243
2019-10-19
omar.pol
{
1244
2019-10-19
omar.pol
size_t off;
1245
2019-10-19
omar.pol
1246
2019-10-19
omar.pol
if (r->horizontal_layout)
1247
2019-10-19
omar.pol
off = e->x;
1248
2019-10-19
omar.pol
else
1249
2019-10-19
omar.pol
off = e->y;
1250
2019-10-19
omar.pol
1251
2019-10-19
omar.pol
switch (e->button) {
1252
2019-10-19
omar.pol
case Button1:
1253
2019-10-19
omar.pol
return select_clicked(cs, off, r->offset, CONFIRM);
1254
2019-10-19
omar.pol
1255
2019-10-19
omar.pol
case Button3:
1256
2019-10-19
omar.pol
return select_clicked(cs, off, r->offset, CONFIRM_CONTINUE);
1257
2019-10-19
omar.pol
1258
2019-10-19
omar.pol
case Button4:
1259
2019-10-19
omar.pol
return SCROLL_UP;
1260
2019-10-19
omar.pol
1261
2019-10-19
omar.pol
case Button5:
1262
2019-10-19
omar.pol
return SCROLL_DOWN;
1263
2019-10-19
omar.pol
}
1264
2019-10-19
omar.pol
1265
2019-10-19
omar.pol
return NO_OP;
1266
2018-06-07
omar.pol
}
1267
2018-06-07
omar.pol
1268
2018-10-04
omar.pol
/* event loop */
1269
2022-07-01
op
static enum state
1270
2022-05-21
op
loop(struct rendering *r, char **text, int *textlen, struct completions *cs,
1271
2022-05-21
op
char **lines, char **vlines)
1272
2018-10-04
omar.pol
{
1273
2022-05-23
op
enum action a;
1274
2022-05-23
op
char *input = NULL;
1275
2018-10-04
omar.pol
enum state status = LOOPING;
1276
2022-05-23
op
int i;
1277
2018-07-21
omar.pol
1278
2018-10-04
omar.pol
while (status == LOOPING) {
1279
2018-10-04
omar.pol
XEvent e;
1280
2018-10-04
omar.pol
XNextEvent(r->d, &e);
1281
2018-07-03
omar.pol
1282
2018-10-04
omar.pol
if (XFilterEvent(&e, r->w))
1283
2018-10-04
omar.pol
continue;
1284
2018-06-07
omar.pol
1285
2018-10-04
omar.pol
switch (e.type) {
1286
2018-10-04
omar.pol
case KeymapNotify:
1287
2018-10-04
omar.pol
XRefreshKeyboardMapping(&e.xmapping);
1288
2018-10-04
omar.pol
break;
1289
2018-07-15
omar.pol
1290
2018-10-04
omar.pol
case FocusIn:
1291
2018-10-04
omar.pol
/* Re-grab focus */
1292
2018-10-04
omar.pol
if (e.xfocus.window != r->w)
1293
2018-10-04
omar.pol
grabfocus(r->d, r->w);
1294
2018-10-04
omar.pol
break;
1295
2018-07-21
omar.pol
1296
2018-10-04
omar.pol
case VisibilityNotify:
1297
2018-10-04
omar.pol
if (e.xvisibility.state != VisibilityUnobscured)
1298
2018-10-04
omar.pol
XRaiseWindow(r->d, r->w);
1299
2018-10-04
omar.pol
break;
1300
2018-08-13
omar.pol
1301
2018-10-04
omar.pol
case MapNotify:
1302
2018-10-04
omar.pol
get_wh(r->d, &r->w, &r->width, &r->height);
1303
2018-10-04
omar.pol
draw(r, *text, cs);
1304
2018-10-04
omar.pol
break;
1305
2018-06-07
omar.pol
1306
2019-10-19
omar.pol
case KeyPress:
1307
2022-05-23
op
case ButtonPress:
1308
2019-10-19
omar.pol
if (e.type == KeyPress)
1309
2022-05-21
op
a = parse_event(r->d, (XKeyPressedEvent *)&e,
1310
2022-05-21
op
r->xic, &input);
1311
2019-10-19
omar.pol
else
1312
2022-05-21
op
a = handle_mouse(r, cs,
1313
2022-05-21
op
(XButtonPressedEvent *)&e);
1314
2019-10-19
omar.pol
1315
2019-10-19
omar.pol
switch (a) {
1316
2019-10-19
omar.pol
case NO_OP:
1317
2019-10-19
omar.pol
break;
1318
2019-10-19
omar.pol
1319
2018-10-04
omar.pol
case EXIT:
1320
2018-10-04
omar.pol
status = ERR;
1321
2018-10-04
omar.pol
break;
1322
2018-05-18
omar.pol
1323
2022-05-23
op
case CONFIRM:
1324
2018-10-04
omar.pol
status = OK;
1325
2018-10-04
omar.pol
confirm(&status, r, cs, text, textlen);
1326
2018-10-04
omar.pol
break;
1327
2018-07-21
omar.pol
1328
2022-05-23
op
case CONFIRM_CONTINUE:
1329
2018-10-04
omar.pol
status = OK_LOOP;
1330
2018-10-04
omar.pol
confirm(&status, r, cs, text, textlen);
1331
2018-10-04
omar.pol
break;
1332
2018-05-18
omar.pol
1333
2022-05-23
op
case PREV_COMPL:
1334
2022-05-21
op
complete(cs, r->first_selected, 1, text,
1335
2022-05-21
op
textlen, &status);
1336
2018-10-04
omar.pol
r->offset = cs->selected;
1337
2018-10-04
omar.pol
break;
1338
2022-05-23
op
1339
2022-05-23
op
case NEXT_COMPL:
1340
2022-05-21
op
complete(cs, r->first_selected, 0, text,
1341
2022-05-21
op
textlen, &status);
1342
2018-10-04
omar.pol
r->offset = cs->selected;
1343
2018-10-04
omar.pol
break;
1344
2018-05-18
omar.pol
1345
2018-10-04
omar.pol
case DEL_CHAR:
1346
2018-10-04
omar.pol
popc(*text);
1347
2022-05-21
op
update_completions(cs, *text, lines, vlines,
1348
2022-05-21
op
r->first_selected);
1349
2018-10-04
omar.pol
r->offset = 0;
1350
2018-10-04
omar.pol
break;
1351
2018-05-18
omar.pol
1352
2022-05-23
op
case DEL_WORD:
1353
2018-10-04
omar.pol
popw(*text);
1354
2022-05-21
op
update_completions(cs, *text, lines, vlines,
1355
2022-05-21
op
r->first_selected);
1356
2018-10-04
omar.pol
break;
1357
2018-05-18
omar.pol
1358
2022-05-23
op
case DEL_LINE:
1359
2018-10-04
omar.pol
for (i = 0; i < *textlen; ++i)
1360
2022-05-21
op
(*text)[i] = 0;
1361
2022-05-21
op
update_completions(cs, *text, lines, vlines,
1362
2022-05-21
op
r->first_selected);
1363
2018-10-04
omar.pol
r->offset = 0;
1364
2018-10-04
omar.pol
break;
1365
2018-05-26
omar.pol
1366
2022-05-23
op
case ADD_CHAR:
1367
2018-10-04
omar.pol
/*
1368
2018-10-04
omar.pol
* sometimes a strange key is pressed
1369
2018-10-04
omar.pol
* i.e. ctrl alone), so input will be
1370
2018-10-04
omar.pol
* empty. Don't need to update
1371
2018-10-04
omar.pol
* completion in that case
1372
2018-10-04
omar.pol
*/
1373
2022-05-23
op
if (*input == '\0')
1374
2018-10-04
omar.pol
break;
1375
2018-05-18
omar.pol
1376
2022-05-23
op
for (i = 0; input[i] != '\0'; ++i) {
1377
2022-05-21
op
*textlen = pushc(text, *textlen,
1378
2022-05-21
op
input[i]);
1379
2018-10-04
omar.pol
if (*textlen == -1) {
1380
2019-10-18
omar.pol
fprintf(stderr,
1381
2022-05-21
op
"Memory allocation "
1382
2022-05-21
op
"error\n");
1383
2018-10-04
omar.pol
status = ERR;
1384
2018-10-04
omar.pol
break;
1385
2018-10-04
omar.pol
}
1386
2018-10-04
omar.pol
}
1387
2018-05-18
omar.pol
1388
2018-10-04
omar.pol
if (status != ERR) {
1389
2022-05-21
op
update_completions(cs, *text, lines,
1390
2022-05-21
op
vlines, r->first_selected);
1391
2018-10-04
omar.pol
free(input);
1392
2018-10-04
omar.pol
}
1393
2018-05-18
omar.pol
1394
2018-10-04
omar.pol
r->offset = 0;
1395
2018-10-04
omar.pol
break;
1396
2018-05-18
omar.pol
1397
2018-10-04
omar.pol
case TOGGLE_FIRST_SELECTED:
1398
2018-10-04
omar.pol
r->first_selected = !r->first_selected;
1399
2018-10-04
omar.pol
if (r->first_selected && cs->selected < 0)
1400
2018-10-04
omar.pol
cs->selected = 0;
1401
2018-10-04
omar.pol
if (!r->first_selected && cs->selected == 0)
1402
2018-10-04
omar.pol
cs->selected = -1;
1403
2018-10-04
omar.pol
break;
1404
2018-07-15
omar.pol
1405
2019-10-19
omar.pol
case SCROLL_DOWN:
1406
2019-10-20
omar.pol
r->offset = MIN(r->offset + 1, cs->length - 1);
1407
2019-10-19
omar.pol
break;
1408
2018-05-18
omar.pol
1409
2019-10-19
omar.pol
case SCROLL_UP:
1410
2019-10-19
omar.pol
r->offset = MAX((ssize_t)r->offset - 1, 0);
1411
2019-10-19
omar.pol
break;
1412
2019-10-19
omar.pol
}
1413
2018-10-04
omar.pol
}
1414
2018-05-18
omar.pol
1415
2018-10-04
omar.pol
draw(r, *text, cs);
1416
2018-10-04
omar.pol
}
1417
2018-09-13
omar.pol
1418
2018-10-04
omar.pol
return status;
1419
2018-10-04
omar.pol
}
1420
2018-09-13
omar.pol
1421
2022-07-01
op
static int
1422
2018-10-04
omar.pol
load_font(struct rendering *r, const char *fontname)
1423
2018-10-04
omar.pol
{
1424
2018-10-04
omar.pol
r->font = XftFontOpenName(r->d, DefaultScreen(r->d), fontname);
1425
2018-10-04
omar.pol
return 0;
1426
2018-10-04
omar.pol
}
1427
2018-05-19
omar.pol
1428
2022-07-01
op
static void
1429
2018-10-06
omar.pol
xim_init(struct rendering *r, XrmDatabase *xdb)
1430
2018-10-06
omar.pol
{
1431
2019-10-18
omar.pol
XIMStyle best_match_style;
1432
2019-10-18
omar.pol
XIMStyles *xis;
1433
2019-10-18
omar.pol
int i;
1434
2018-10-06
omar.pol
1435
2018-10-06
omar.pol
/* Open the X input method */
1436
2022-05-16
op
if ((r->xim = XOpenIM(r->d, *xdb, RESNAME, RESCLASS)) == NULL)
1437
2019-10-19
omar.pol
err(1, "XOpenIM");
1438
2018-10-06
omar.pol
1439
2018-10-20
omar.pol
if (XGetIMValues(r->xim, XNQueryInputStyle, &xis, NULL) || !xis) {
1440
2018-10-06
omar.pol
fprintf(stderr, "Input Styles could not be retrieved\n");
1441
2018-10-06
omar.pol
exit(EX_UNAVAILABLE);
1442
2018-10-06
omar.pol
}
1443
2018-10-06
omar.pol
1444
2018-10-06
omar.pol
best_match_style = 0;
1445
2018-10-06
omar.pol
for (i = 0; i < xis->count_styles; ++i) {
1446
2018-10-06
omar.pol
XIMStyle ts = xis->supported_styles[i];
1447
2018-10-06
omar.pol
if (ts == (XIMPreeditNothing | XIMStatusNothing)) {
1448
2018-10-06
omar.pol
best_match_style = ts;
1449
2018-10-06
omar.pol
break;
1450
2018-10-06
omar.pol
}
1451
2018-10-06
omar.pol
}
1452
2018-10-06
omar.pol
XFree(xis);
1453
2018-10-06
omar.pol
1454
2018-10-06
omar.pol
if (!best_match_style)
1455
2022-05-21
op
fprintf(stderr,
1456
2022-05-21
op
"No matching input style could be determined\n");
1457
2018-10-06
omar.pol
1458
2022-05-21
op
r->xic = XCreateIC(r->xim, XNInputStyle, best_match_style,
1459
2022-05-21
op
XNClientWindow, r->w, XNFocusWindow, r->w, NULL);
1460
2019-10-19
omar.pol
if (r->xic == NULL)
1461
2019-10-19
omar.pol
err(1, "XCreateIC");
1462
2018-10-06
omar.pol
}
1463
2018-10-06
omar.pol
1464
2022-07-01
op
static void
1465
2022-05-21
op
create_window(struct rendering *r, Window parent_window, Colormap cmap,
1466
2022-05-21
op
XVisualInfo vinfo, int x, int y, int ox, int oy,
1467
2022-05-21
op
unsigned long background_pixel)
1468
2018-10-06
omar.pol
{
1469
2019-10-18
omar.pol
XSetWindowAttributes attr;
1470
2022-05-21
op
unsigned long vmask;
1471
2018-10-06
omar.pol
1472
2018-10-06
omar.pol
/* Create the window */
1473
2018-10-06
omar.pol
attr.colormap = cmap;
1474
2018-10-06
omar.pol
attr.override_redirect = 1;
1475
2018-10-06
omar.pol
attr.border_pixel = 0;
1476
2018-10-20
omar.pol
attr.background_pixel = background_pixel;
1477
2022-05-21
op
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask
1478
2022-05-21
op
| KeymapStateMask | ButtonPress | VisibilityChangeMask;
1479
2018-10-06
omar.pol
1480
2022-05-21
op
vmask = CWBorderPixel | CWBackPixel | CWColormap | CWEventMask |
1481
2022-05-21
op
CWOverrideRedirect;
1482
2022-05-21
op
1483
2019-10-20
omar.pol
r->w = XCreateWindow(r->d, parent_window, x + ox, y + oy, r->width, r->height, 0,
1484
2022-05-21
op
vinfo.depth, InputOutput, vinfo.visual, vmask, &attr);
1485
2018-10-06
omar.pol
}
1486
2018-10-06
omar.pol
1487
2022-07-01
op
static void
1488
2018-10-06
omar.pol
ps1extents(struct rendering *r)
1489
2018-10-06
omar.pol
{
1490
2018-10-06
omar.pol
char *dup;
1491
2018-10-06
omar.pol
dup = strdupn(r->ps1);
1492
2019-10-20
omar.pol
text_extents(dup == NULL ? r->ps1 : dup, r->ps1len, r, &r->ps1w, &r->ps1h);
1493
2018-10-06
omar.pol
free(dup);
1494
2018-10-06
omar.pol
}
1495
2018-10-06
omar.pol
1496
2022-07-01
op
static void
1497
2018-10-04
omar.pol
usage(char *prgname)
1498
2018-10-04
omar.pol
{
1499
2018-10-17
omar.pol
fprintf(stderr,
1500
2022-05-21
op
"%s [-Aahmv] [-B colors] [-b size] [-C color] [-c color]\n"
1501
2022-05-21
op
" [-d separator] [-e window] [-f font] [-G color] [-g "
1502
2022-05-21
op
"size]\n"
1503
2022-05-21
op
" [-H height] [-I color] [-i size] [-J color] [-j "
1504
2022-05-21
op
"size] [-l layout]\n"
1505
2022-05-21
op
" [-P padding] [-p prompt] [-S color] [-s color] [-T "
1506
2022-05-21
op
"color]\n"
1507
2022-05-21
op
" [-t color] [-W width] [-x coord] [-y coord]\n",
1508
2022-05-21
op
prgname);
1509
2018-10-04
omar.pol
}
1510
2018-05-18
omar.pol
1511
2018-10-04
omar.pol
int
1512
2018-10-04
omar.pol
main(int argc, char **argv)
1513
2018-10-04
omar.pol
{
1514
2019-10-18
omar.pol
struct completions *cs;
1515
2019-10-18
omar.pol
struct rendering r;
1516
2019-10-18
omar.pol
XVisualInfo vinfo;
1517
2019-10-18
omar.pol
Colormap cmap;
1518
2019-10-18
omar.pol
size_t nlines, i;
1519
2019-10-18
omar.pol
Window parent_window;
1520
2019-10-18
omar.pol
XrmDatabase xdb;
1521
2019-10-18
omar.pol
unsigned long fgs[3], bgs[3]; /* prompt, compl, compl_highlighted */
1522
2019-10-18
omar.pol
unsigned long borders_bg[4], p_borders_bg[4], c_borders_bg[4],
1523
2019-10-18
omar.pol
ch_borders_bg[4]; /* N E S W */
1524
2022-05-23
op
enum state status = LOOPING;
1525
2019-10-18
omar.pol
int ch;
1526
2022-05-23
op
int offset_x = 0, offset_y = 0;
1527
2022-05-23
op
int x = 0, y = 0;
1528
2019-10-18
omar.pol
int textlen, d_width, d_height;
1529
2019-10-18
omar.pol
short embed;
1530
2022-05-23
op
const char *sep = NULL;
1531
2022-05-23
op
const char *parent_window_id = NULL;
1532
2022-05-23
op
char *tmp[4];
1533
2022-05-16
op
char **lines, **vlines;
1534
2019-10-18
omar.pol
char *fontname, *text, *xrm;
1535
2018-05-18
omar.pol
1536
2022-05-23
op
setlocale(LC_ALL, getenv("LANG"));
1537
2018-05-18
omar.pol
1538
2022-05-23
op
for (i = 0; i < 4; ++i) {
1539
2022-05-23
op
/* default paddings */
1540
2022-05-23
op
r.p_padding[i] = 10;
1541
2022-05-23
op
r.c_padding[i] = 10;
1542
2022-05-23
op
r.ch_padding[i] = 10;
1543
2022-05-23
op
1544
2022-05-23
op
/* default borders */
1545
2022-05-23
op
r.borders[i] = 0;
1546
2022-05-23
op
r.p_borders[i] = 0;
1547
2022-05-23
op
r.c_borders[i] = 0;
1548
2022-05-23
op
r.ch_borders[i] = 0;
1549
2022-05-23
op
}
1550
2022-05-23
op
1551
2018-10-06
omar.pol
r.first_selected = 0;
1552
2018-10-06
omar.pol
r.free_text = 1;
1553
2018-10-06
omar.pol
r.multiple_select = 0;
1554
2018-10-06
omar.pol
r.offset = 0;
1555
2018-10-06
omar.pol
1556
2022-05-23
op
/* default width and height */
1557
2022-05-23
op
r.width = 400;
1558
2022-05-23
op
r.height = 20;
1559
2022-05-23
op
1560
2022-05-23
op
/*
1561
2022-05-23
op
* The prompt. We duplicate the string so later is easy to
1562
2022-05-23
op
* free (in the case it's been overwritten by the user)
1563
2022-05-23
op
*/
1564
2022-05-23
op
if ((r.ps1 = strdup("$ ")) == NULL)
1565
2022-05-23
op
err(1, "strdup");
1566
2022-05-23
op
1567
2022-05-23
op
/* same for the font name */
1568
2022-05-23
op
if ((fontname = strdup(DEFFONT)) == NULL)
1569
2022-05-23
op
err(1, "strdup");
1570
2022-05-23
op
1571
2018-10-04
omar.pol
while ((ch = getopt(argc, argv, ARGS)) != -1) {
1572
2018-10-04
omar.pol
switch (ch) {
1573
2019-10-18
omar.pol
case 'h': /* help */
1574
2018-10-04
omar.pol
usage(*argv);
1575
2018-10-04
omar.pol
return 0;
1576
2019-10-18
omar.pol
case 'v': /* version */
1577
2018-10-04
omar.pol
fprintf(stderr, "%s version: %s\n", *argv, VERSION);
1578
2018-10-04
omar.pol
return 0;
1579
2019-10-18
omar.pol
case 'e': /* embed */
1580
2019-10-19
omar.pol
if ((parent_window_id = strdup(optarg)) == NULL)
1581
2019-10-19
omar.pol
err(1, "strdup");
1582
2018-10-04
omar.pol
break;
1583
2018-10-09
omar.pol
case 'd':
1584
2019-10-19
omar.pol
if ((sep = strdup(optarg)) == NULL)
1585
2019-10-19
omar.pol
err(1, "strdup");
1586
2019-10-19
omar.pol
break;
1587
2018-10-09
omar.pol
case 'A':
1588
2018-10-06
omar.pol
r.free_text = 0;
1589
2018-10-04
omar.pol
break;
1590
2018-10-09
omar.pol
case 'm':
1591
2018-10-06
omar.pol
r.multiple_select = 1;
1592
2018-10-04
omar.pol
break;
1593
2018-10-04
omar.pol
default:
1594
2018-10-04
omar.pol
break;
1595
2018-10-04
omar.pol
}
1596
2018-10-04
omar.pol
}
1597
2018-05-26
omar.pol
1598
2022-05-16
op
lines = readlines(&nlines);
1599
2018-07-08
omar.pol
1600
2018-10-04
omar.pol
vlines = NULL;
1601
2018-10-04
omar.pol
if (sep != NULL) {
1602
2018-10-04
omar.pol
int l;
1603
2018-10-04
omar.pol
l = strlen(sep);
1604
2019-10-19
omar.pol
if ((vlines = calloc(nlines, sizeof(char *))) == NULL)
1605
2019-10-19
omar.pol
err(1, "calloc");
1606
2018-05-18
omar.pol
1607
2018-10-04
omar.pol
for (i = 0; i < nlines; i++) {
1608
2018-10-04
omar.pol
char *t;
1609
2018-10-04
omar.pol
t = strstr(lines[i], sep);
1610
2018-10-04
omar.pol
if (t == NULL)
1611
2018-10-04
omar.pol
vlines[i] = lines[i];
1612
2018-10-04
omar.pol
else
1613
2018-10-04
omar.pol
vlines[i] = t + l;
1614
2018-10-04
omar.pol
}
1615
2018-10-04
omar.pol
}
1616
2018-05-18
omar.pol
1617
2018-10-04
omar.pol
textlen = 10;
1618
2019-10-19
omar.pol
if ((text = malloc(textlen * sizeof(char))) == NULL)
1619
2019-10-19
omar.pol
err(1, "malloc");
1620
2018-05-18
omar.pol
1621
2018-10-04
omar.pol
/* struct completions *cs = filter(text, lines); */
1622
2019-10-19
omar.pol
if ((cs = compls_new(nlines)) == NULL)
1623
2019-10-19
omar.pol
err(1, "compls_new");
1624
2018-05-18
omar.pol
1625
2018-10-04
omar.pol
/* start talking to xorg */
1626
2018-10-06
omar.pol
r.d = XOpenDisplay(NULL);
1627
2018-10-06
omar.pol
if (r.d == NULL) {
1628
2018-10-04
omar.pol
fprintf(stderr, "Could not open display!\n");
1629
2018-10-04
omar.pol
return EX_UNAVAILABLE;
1630
2018-10-04
omar.pol
}
1631
2018-05-18
omar.pol
1632
2018-10-04
omar.pol
embed = 1;
1633
2019-10-20
omar.pol
if (!(parent_window_id && (parent_window = strtol(parent_window_id, NULL, 0)))) {
1634
2018-10-06
omar.pol
parent_window = DefaultRootWindow(r.d);
1635
2018-10-04
omar.pol
embed = 0;
1636
2018-10-04
omar.pol
}
1637
2018-05-18
omar.pol
1638
2018-10-04
omar.pol
/* get display size */
1639
2018-10-06
omar.pol
get_wh(r.d, &parent_window, &d_width, &d_height);
1640
2018-10-06
omar.pol
1641
2022-05-21
op
if (!embed)
1642
2022-05-21
op
findmonitor(r.d, &offset_x, &offset_y, &d_width, &d_height);
1643
2018-05-18
omar.pol
1644
2018-10-06
omar.pol
XMatchVisualInfo(r.d, DefaultScreen(r.d), 32, TrueColor, &vinfo);
1645
2022-05-21
op
cmap = XCreateColormap(r.d, XDefaultRootWindow(r.d), vinfo.visual,
1646
2022-05-21
op
AllocNone);
1647
2018-05-21
omar.pol
1648
2018-10-09
omar.pol
fgs[0] = fgs[1] = parse_color("#fff", NULL);
1649
2018-10-09
omar.pol
fgs[2] = parse_color("#000", NULL);
1650
2018-05-21
omar.pol
1651
2018-10-09
omar.pol
bgs[0] = bgs[1] = parse_color("#000", NULL);
1652
2018-10-09
omar.pol
bgs[2] = parse_color("#fff", NULL);
1653
2018-05-21
omar.pol
1654
2022-05-21
op
borders_bg[0] = borders_bg[1] = borders_bg[2] = borders_bg[3] =
1655
2022-05-21
op
parse_color("#000", NULL);
1656
2018-09-13
omar.pol
1657
2019-10-18
omar.pol
p_borders_bg[0] = p_borders_bg[1] = p_borders_bg[2] = p_borders_bg[3]
1658
2019-10-18
omar.pol
= parse_color("#000", NULL);
1659
2019-10-18
omar.pol
c_borders_bg[0] = c_borders_bg[1] = c_borders_bg[2] = c_borders_bg[3]
1660
2019-10-18
omar.pol
= parse_color("#000", NULL);
1661
2019-10-20
omar.pol
ch_borders_bg[0] = ch_borders_bg[1] = ch_borders_bg[2] = ch_borders_bg[3]
1662
2019-10-20
omar.pol
= parse_color("#000", NULL);
1663
2018-10-17
omar.pol
1664
2018-10-06
omar.pol
r.horizontal_layout = 1;
1665
2018-09-13
omar.pol
1666
2018-10-04
omar.pol
/* Read the resources */
1667
2018-10-04
omar.pol
XrmInitialize();
1668
2018-10-06
omar.pol
xrm = XResourceManagerString(r.d);
1669
2018-10-04
omar.pol
xdb = NULL;
1670
2018-10-04
omar.pol
if (xrm != NULL) {
1671
2018-10-04
omar.pol
XrmValue value;
1672
2018-10-04
omar.pol
char *datatype[20];
1673
2018-10-04
omar.pol
1674
2018-10-04
omar.pol
xdb = XrmGetStringDatabase(xrm);
1675
2018-10-04
omar.pol
1676
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.font", "*", datatype, &value)) {
1677
2018-10-04
omar.pol
free(fontname);
1678
2019-10-19
omar.pol
if ((fontname = strdup(value.addr)) == NULL)
1679
2019-10-19
omar.pol
err(1, "strdup");
1680
2018-10-04
omar.pol
} else {
1681
2019-10-20
omar.pol
fprintf(stderr, "no font defined, using %s\n", fontname);
1682
2018-10-04
omar.pol
}
1683
2018-10-04
omar.pol
1684
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.layout", "*", datatype, &value))
1685
2019-10-20
omar.pol
r.horizontal_layout = !strcmp(value.addr, "horizontal");
1686
2018-10-04
omar.pol
else
1687
2019-10-20
omar.pol
fprintf(stderr, "no layout defined, using horizontal\n");
1688
2018-10-04
omar.pol
1689
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.prompt", "*", datatype, &value)) {
1690
2018-10-06
omar.pol
free(r.ps1);
1691
2018-10-06
omar.pol
r.ps1 = normalize_str(value.addr);
1692
2018-10-04
omar.pol
} else {
1693
2019-10-18
omar.pol
fprintf(stderr,
1694
2019-10-18
omar.pol
"no prompt defined, using \"%s\" as "
1695
2019-10-18
omar.pol
"default\n",
1696
2019-10-18
omar.pol
r.ps1);
1697
2018-10-04
omar.pol
}
1698
2018-10-04
omar.pol
1699
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.prompt.border.size", "*", datatype, &value)) {
1700
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1701
2022-05-23
op
err(1, "parse_csslike");
1702
2022-05-23
op
for (i = 0; i < 4; ++i) {
1703
2022-05-23
op
r.p_borders[i] = parse_integer(tmp[i], 0);
1704
2022-05-23
op
free(tmp[i]);
1705
2022-05-23
op
}
1706
2018-10-17
omar.pol
}
1707
2018-10-17
omar.pol
1708
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.prompt.border.color", "*", datatype, &value)) {
1709
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1710
2022-05-23
op
err(1, "parse_csslike");
1711
2022-05-23
op
1712
2022-05-23
op
for (i = 0; i < 4; ++i) {
1713
2022-05-23
op
p_borders_bg[i] = parse_color(tmp[i], "#000");
1714
2022-05-23
op
free(tmp[i]);
1715
2022-05-23
op
}
1716
2018-10-17
omar.pol
}
1717
2018-10-17
omar.pol
1718
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.prompt.padding", "*", datatype, &value)) {
1719
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1720
2022-05-23
op
err(1, "parse_csslike");
1721
2022-05-23
op
1722
2022-05-23
op
for (i = 0; i < 4; ++i) {
1723
2022-05-23
op
r.p_padding[i] = parse_integer(tmp[i], 0);
1724
2022-05-23
op
free(tmp[i]);
1725
2022-05-23
op
}
1726
2018-10-17
omar.pol
}
1727
2018-10-17
omar.pol
1728
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.width", "*", datatype, &value))
1729
2019-10-20
omar.pol
r.width = parse_int_with_percentage(value.addr, r.width, d_width);
1730
2018-10-04
omar.pol
else
1731
2019-10-20
omar.pol
fprintf(stderr, "no width defined, using %d\n", r.width);
1732
2018-10-04
omar.pol
1733
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.height", "*", datatype, &value))
1734
2019-10-20
omar.pol
r.height = parse_int_with_percentage(value.addr, r.height, d_height);
1735
2018-10-04
omar.pol
else
1736
2019-10-20
omar.pol
fprintf(stderr, "no height defined, using %d\n", r.height);
1737
2018-10-04
omar.pol
1738
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.x", "*", datatype, &value))
1739
2019-10-20
omar.pol
x = parse_int_with_pos(r.d, value.addr, x, d_width, r.width);
1740
2018-10-04
omar.pol
1741
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.y", "*", datatype, &value))
1742
2019-10-20
omar.pol
y = parse_int_with_pos(r.d, value.addr, y, d_height, r.height);
1743
2018-10-04
omar.pol
1744
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.border.size", "*", datatype, &value)) {
1745
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1746
2022-05-23
op
err(1, "parse_csslike");
1747
2022-05-23
op
1748
2022-05-23
op
for (i = 0; i < 4; ++i) {
1749
2022-05-23
op
r.borders[i] = parse_int_with_percentage(tmp[i], 0,
1750
2022-05-23
op
(i % 2) == 0 ? d_height : d_width);
1751
2022-05-23
op
free(tmp[i]);
1752
2022-05-23
op
}
1753
2018-10-17
omar.pol
}
1754
2018-10-04
omar.pol
1755
2018-10-04
omar.pol
/* Prompt */
1756
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.prompt.foreground", "*", datatype, &value))
1757
2018-10-09
omar.pol
fgs[0] = parse_color(value.addr, "#fff");
1758
2018-10-04
omar.pol
1759
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.prompt.background", "*", datatype, &value))
1760
2018-10-09
omar.pol
bgs[0] = parse_color(value.addr, "#000");
1761
2018-10-04
omar.pol
1762
2018-10-04
omar.pol
/* Completions */
1763
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.completion.foreground", "*", datatype, &value))
1764
2018-10-09
omar.pol
fgs[1] = parse_color(value.addr, "#fff");
1765
2018-10-04
omar.pol
1766
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.completion.background", "*", datatype, &value))
1767
2018-10-09
omar.pol
bgs[1] = parse_color(value.addr, "#000");
1768
2018-10-04
omar.pol
1769
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.completion.padding", "*", datatype, &value)) {
1770
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1771
2022-05-23
op
err(1, "parse_csslike");
1772
2022-05-23
op
1773
2022-05-23
op
for (i = 0; i < 4; ++i) {
1774
2022-05-23
op
r.c_padding[i] = parse_integer(tmp[i], 0);
1775
2022-05-23
op
free(tmp[i]);
1776
2022-05-23
op
}
1777
2018-10-17
omar.pol
}
1778
2018-10-17
omar.pol
1779
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.completion.border.size", "*", datatype, &value)) {
1780
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1781
2022-05-23
op
err(1, "parse_csslike");
1782
2022-05-23
op
1783
2022-05-23
op
for (i = 0; i < 4; ++i) {
1784
2022-05-23
op
r.c_borders[i] = parse_integer(tmp[i], 0);
1785
2022-05-23
op
free(tmp[i]);
1786
2022-05-23
op
}
1787
2018-10-17
omar.pol
}
1788
2018-10-17
omar.pol
1789
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.completion.border.color", "*", datatype, &value)) {
1790
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1791
2022-05-23
op
err(1, "parse_csslike");
1792
2022-05-23
op
1793
2022-05-23
op
for (i = 0; i < 4; ++i) {
1794
2022-05-23
op
c_borders_bg[i] = parse_color(tmp[i], "#000");
1795
2022-05-23
op
free(tmp[i]);
1796
2022-05-23
op
}
1797
2018-10-17
omar.pol
}
1798
2018-10-17
omar.pol
1799
2018-10-04
omar.pol
/* Completion Highlighted */
1800
2019-10-20
omar.pol
if (XrmGetResource(
1801
2019-10-20
omar.pol
xdb, "MyMenu.completion_highlighted.foreground", "*", datatype, &value))
1802
2018-10-09
omar.pol
fgs[2] = parse_color(value.addr, "#000");
1803
2018-10-04
omar.pol
1804
2019-10-20
omar.pol
if (XrmGetResource(
1805
2019-10-20
omar.pol
xdb, "MyMenu.completion_highlighted.background", "*", datatype, &value))
1806
2018-10-09
omar.pol
bgs[2] = parse_color(value.addr, "#fff");
1807
2018-10-04
omar.pol
1808
2019-10-20
omar.pol
if (XrmGetResource(
1809
2019-10-20
omar.pol
xdb, "MyMenu.completion_highlighted.padding", "*", datatype, &value)) {
1810
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1811
2022-05-23
op
err(1, "parse_csslike");
1812
2022-05-23
op
1813
2022-05-23
op
for (i = 0; i < 4; ++i) {
1814
2022-05-23
op
r.ch_padding[i] = parse_integer(tmp[i], 0);
1815
2022-05-23
op
free(tmp[i]);
1816
2022-05-23
op
}
1817
2018-10-17
omar.pol
}
1818
2018-10-17
omar.pol
1819
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.completion_highlighted.border.size", "*", datatype,
1820
2022-05-23
op
&value)) {
1821
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1822
2022-05-23
op
err(1, "parse_csslike");
1823
2022-05-23
op
1824
2022-05-23
op
for (i = 0; i < 4; ++i) {
1825
2022-05-23
op
r.ch_borders[i] = parse_integer(tmp[i], 0);
1826
2022-05-23
op
free(tmp[i]);
1827
2022-05-23
op
}
1828
2018-10-17
omar.pol
}
1829
2018-10-17
omar.pol
1830
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.completion_highlighted.border.color", "*", datatype,
1831
2019-10-20
omar.pol
&value)) {
1832
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1833
2022-05-23
op
err(1, "parse_csslike");
1834
2022-05-23
op
1835
2022-05-23
op
for (i = 0; i < 4; ++i) {
1836
2022-05-23
op
ch_borders_bg[i] = parse_color(tmp[i], "#000");
1837
2022-05-23
op
free(tmp[i]);
1838
2022-05-23
op
}
1839
2018-10-17
omar.pol
}
1840
2018-10-17
omar.pol
1841
2018-10-04
omar.pol
/* Border */
1842
2019-10-20
omar.pol
if (XrmGetResource(xdb, "MyMenu.border.color", "*", datatype, &value)) {
1843
2022-05-23
op
if (parse_csslike(value.addr, tmp) == -1)
1844
2022-05-23
op
err(1, "parse_csslike");
1845
2022-05-23
op
1846
2022-05-23
op
for (i = 0; i < 4; ++i) {
1847
2022-05-23
op
borders_bg[i] = parse_color(tmp[i], "#000");
1848
2022-05-23
op
free(tmp[i]);
1849
2022-05-23
op
}
1850
2018-10-04
omar.pol
}
1851
2018-10-04
omar.pol
}
1852
2018-10-04
omar.pol
1853
2018-10-04
omar.pol
/* Second round of args parsing */
1854
2019-10-18
omar.pol
optind = 0; /* reset the option index */
1855
2018-10-04
omar.pol
while ((ch = getopt(argc, argv, ARGS)) != -1) {
1856
2018-10-04
omar.pol
switch (ch) {
1857
2018-10-04
omar.pol
case 'a':
1858
2018-10-06
omar.pol
r.first_selected = 1;
1859
2018-10-04
omar.pol
break;
1860
2018-10-04
omar.pol
case 'A':
1861
2018-10-04
omar.pol
/* free_text -- already catched */
1862
2018-10-04
omar.pol
case 'd':
1863
2018-10-04
omar.pol
/* separator -- this case was already catched */
1864
2018-10-04
omar.pol
case 'e':
1865
2018-10-04
omar.pol
/* embedding mymenu this case was already catched. */
1866
2018-10-04
omar.pol
case 'm':
1867
2019-10-18
omar.pol
/* multiple selection this case was already catched.
1868
2019-10-18
omar.pol
*/
1869
2018-10-04
omar.pol
break;
1870
2018-10-04
omar.pol
case 'p': {
1871
2018-10-04
omar.pol
char *newprompt;
1872
2018-10-04
omar.pol
newprompt = strdup(optarg);
1873
2018-10-04
omar.pol
if (newprompt != NULL) {
1874
2018-10-06
omar.pol
free(r.ps1);
1875
2018-10-06
omar.pol
r.ps1 = newprompt;
1876
2018-10-04
omar.pol
}
1877
2018-10-04
omar.pol
break;
1878
2018-10-04
omar.pol
}
1879
2018-10-04
omar.pol
case 'x':
1880
2019-10-20
omar.pol
x = parse_int_with_pos(r.d, optarg, x, d_width, r.width);
1881
2018-10-04
omar.pol
break;
1882
2018-10-04
omar.pol
case 'y':
1883
2019-10-20
omar.pol
y = parse_int_with_pos(r.d, optarg, y, d_height, r.height);
1884
2018-10-04
omar.pol
break;
1885
2022-05-23
op
case 'P':
1886
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1887
2022-05-23
op
err(1, "parse_csslike");
1888
2022-05-23
op
for (i = 0; i < 4; ++i)
1889
2022-05-23
op
r.p_padding[i] = parse_integer(tmp[i], 0);
1890
2018-10-04
omar.pol
break;
1891
2022-05-23
op
case 'G':
1892
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1893
2022-05-23
op
err(1, "parse_csslike");
1894
2022-05-23
op
for (i = 0; i < 4; ++i)
1895
2022-05-23
op
p_borders_bg[i] = parse_color(tmp[i], "#000");
1896
2018-10-17
omar.pol
break;
1897
2022-05-23
op
case 'g':
1898
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1899
2022-05-23
op
err(1, "parse_csslike");
1900
2022-05-23
op
for (i = 0; i < 4; ++i)
1901
2022-05-23
op
r.p_borders[i] = parse_integer(tmp[i], 0);
1902
2018-10-17
omar.pol
break;
1903
2022-05-23
op
case 'I':
1904
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1905
2022-05-23
op
err(1, "parse_csslike");
1906
2022-05-23
op
for (i = 0; i < 4; ++i)
1907
2022-05-23
op
c_borders_bg[i] = parse_color(tmp[i], "#000");
1908
2018-10-17
omar.pol
break;
1909
2022-05-23
op
case 'i':
1910
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1911
2022-05-23
op
err(1, "parse_csslike");
1912
2022-05-23
op
for (i = 0; i < 4; ++i)
1913
2022-05-23
op
r.c_borders[i] = parse_integer(tmp[i], 0);
1914
2018-10-17
omar.pol
break;
1915
2022-05-23
op
case 'J':
1916
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1917
2022-05-23
op
err(1, "parse_csslike");
1918
2022-05-23
op
for (i = 0; i < 4; ++i)
1919
2022-05-23
op
ch_borders_bg[i] = parse_color(tmp[i], "#000");
1920
2018-10-17
omar.pol
break;
1921
2022-05-23
op
case 'j':
1922
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1923
2022-05-23
op
err(1, "parse_csslike");
1924
2022-05-23
op
for (i = 0; i < 4; ++i)
1925
2022-05-23
op
r.ch_borders[i] = parse_integer(tmp[i], 0);
1926
2022-05-23
op
break;
1927
2018-10-04
omar.pol
case 'l':
1928
2018-10-06
omar.pol
r.horizontal_layout = !strcmp(optarg, "horizontal");
1929
2018-10-04
omar.pol
break;
1930
2018-10-04
omar.pol
case 'f': {
1931
2018-10-04
omar.pol
char *newfont;
1932
2018-10-04
omar.pol
if ((newfont = strdup(optarg)) != NULL) {
1933
2018-10-04
omar.pol
free(fontname);
1934
2018-10-04
omar.pol
fontname = newfont;
1935
2018-10-04
omar.pol
}
1936
2018-10-04
omar.pol
break;
1937
2018-10-04
omar.pol
}
1938
2018-10-04
omar.pol
case 'W':
1939
2019-10-20
omar.pol
r.width = parse_int_with_percentage(optarg, r.width, d_width);
1940
2018-10-04
omar.pol
break;
1941
2018-10-04
omar.pol
case 'H':
1942
2019-10-20
omar.pol
r.height = parse_int_with_percentage(optarg, r.height, d_height);
1943
2018-10-04
omar.pol
break;
1944
2022-05-23
op
case 'b':
1945
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1946
2022-05-23
op
err(1, "parse_csslike");
1947
2022-05-23
op
for (i = 0; i < 4; ++i)
1948
2022-05-23
op
r.borders[i] = parse_integer(tmp[i], 0);
1949
2018-10-04
omar.pol
break;
1950
2022-05-23
op
case 'B':
1951
2022-05-23
op
if (parse_csslike(optarg, tmp) == -1)
1952
2022-05-23
op
err(1, "parse_csslike");
1953
2022-05-23
op
for (i = 0; i < 4; ++i)
1954
2022-05-23
op
borders_bg[i] = parse_color(tmp[i], "#000");
1955
2018-10-04
omar.pol
break;
1956
2018-10-06
omar.pol
case 't':
1957
2018-10-09
omar.pol
fgs[0] = parse_color(optarg, NULL);
1958
2018-10-04
omar.pol
break;
1959
2018-10-06
omar.pol
case 'T':
1960
2018-10-09
omar.pol
bgs[0] = parse_color(optarg, NULL);
1961
2018-10-04
omar.pol
break;
1962
2018-10-06
omar.pol
case 'c':
1963
2018-10-09
omar.pol
fgs[1] = parse_color(optarg, NULL);
1964
2018-10-04
omar.pol
break;
1965
2018-10-06
omar.pol
case 'C':
1966
2018-10-09
omar.pol
bgs[1] = parse_color(optarg, NULL);
1967
2018-10-04
omar.pol
break;
1968
2018-10-06
omar.pol
case 's':
1969
2018-10-09
omar.pol
fgs[2] = parse_color(optarg, NULL);
1970
2018-10-04
omar.pol
break;
1971
2018-10-06
omar.pol
case 'S':
1972
2020-04-10
op
bgs[2] = parse_color(optarg, NULL);
1973
2018-10-04
omar.pol
break;
1974
2018-10-04
omar.pol
default:
1975
2018-10-04
omar.pol
fprintf(stderr, "Unrecognized option %c\n", ch);
1976
2018-10-04
omar.pol
status = ERR;
1977
2018-10-04
omar.pol
break;
1978
2018-10-04
omar.pol
}
1979
2018-10-04
omar.pol
}
1980
2018-10-04
omar.pol
1981
2018-10-17
omar.pol
if (r.height < 0 || r.width < 0 || x < 0 || y < 0) {
1982
2018-10-17
omar.pol
fprintf(stderr, "height, width, x or y are lesser than 0.");
1983
2018-10-17
omar.pol
status = ERR;
1984
2018-10-17
omar.pol
}
1985
2018-10-17
omar.pol
1986
2018-10-04
omar.pol
/* since only now we know if the first should be selected,
1987
2018-10-04
omar.pol
* update the completion here */
1988
2018-10-06
omar.pol
update_completions(cs, text, lines, vlines, r.first_selected);
1989
2018-10-04
omar.pol
1990
2019-10-18
omar.pol
/* update the prompt lenght, only now we surely know the length of it
1991
2019-10-18
omar.pol
*/
1992
2018-10-06
omar.pol
r.ps1len = strlen(r.ps1);
1993
2018-10-06
omar.pol
1994
2018-10-04
omar.pol
/* Create the window */
1995
2019-10-20
omar.pol
create_window(&r, parent_window, cmap, vinfo, x, y, offset_x, offset_y, bgs[1]);
1996
2018-10-06
omar.pol
set_win_atoms_hints(r.d, r.w, r.width, r.height);
1997
2018-10-06
omar.pol
XMapRaised(r.d, r.w);
1998
2018-10-04
omar.pol
1999
2018-10-04
omar.pol
/* If embed, listen for other events as well */
2000
2018-10-04
omar.pol
if (embed) {
2001
2019-10-18
omar.pol
Window *children, parent, root;
2002
2019-10-18
omar.pol
unsigned int children_no;
2003
2018-10-04
omar.pol
2004
2018-10-06
omar.pol
XSelectInput(r.d, parent_window, FocusChangeMask);
2005
2019-10-20
omar.pol
if (XQueryTree(r.d, parent_window, &root, &parent, &children, &children_no)
2006
2019-10-18
omar.pol
&& children) {
2007
2019-10-20
omar.pol
for (i = 0; i < children_no && children[i] != r.w; ++i)
2008
2019-10-20
omar.pol
XSelectInput(r.d, children[i], FocusChangeMask);
2009
2018-10-04
omar.pol
XFree(children);
2010
2018-10-04
omar.pol
}
2011
2018-10-06
omar.pol
grabfocus(r.d, r.w);
2012
2018-10-04
omar.pol
}
2013
2018-10-04
omar.pol
2014
2018-10-06
omar.pol
take_keyboard(r.d, r.w);
2015
2018-10-04
omar.pol
2016
2018-10-09
omar.pol
r.x_zero = r.borders[3];
2017
2018-10-09
omar.pol
r.y_zero = r.borders[0];
2018
2018-10-04
omar.pol
2019
2018-10-06
omar.pol
{
2020
2019-10-18
omar.pol
XGCValues values;
2021
2018-10-06
omar.pol
2022
2018-10-17
omar.pol
for (i = 0; i < 3; ++i) {
2023
2018-10-17
omar.pol
r.fgs[i] = XCreateGC(r.d, r.w, 0, &values);
2024
2018-10-17
omar.pol
r.bgs[i] = XCreateGC(r.d, r.w, 0, &values);
2025
2018-10-17
omar.pol
}
2026
2018-10-17
omar.pol
2027
2018-10-17
omar.pol
for (i = 0; i < 4; ++i) {
2028
2018-10-17
omar.pol
r.borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
2029
2018-10-17
omar.pol
r.p_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
2030
2018-10-17
omar.pol
r.c_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
2031
2018-10-17
omar.pol
r.ch_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values);
2032
2018-10-17
omar.pol
}
2033
2018-10-06
omar.pol
}
2034
2018-10-06
omar.pol
2035
2018-10-17
omar.pol
/* Load the colors in our GCs */
2036
2018-10-17
omar.pol
for (i = 0; i < 3; ++i) {
2037
2018-10-17
omar.pol
XSetForeground(r.d, r.fgs[i], fgs[i]);
2038
2018-10-17
omar.pol
XSetForeground(r.d, r.bgs[i], bgs[i]);
2039
2018-10-17
omar.pol
}
2040
2018-10-17
omar.pol
2041
2018-10-17
omar.pol
for (i = 0; i < 4; ++i) {
2042
2018-10-17
omar.pol
XSetForeground(r.d, r.borders_bg[i], borders_bg[i]);
2043
2018-10-17
omar.pol
XSetForeground(r.d, r.p_borders_bg[i], p_borders_bg[i]);
2044
2018-10-17
omar.pol
XSetForeground(r.d, r.c_borders_bg[i], c_borders_bg[i]);
2045
2018-10-17
omar.pol
XSetForeground(r.d, r.ch_borders_bg[i], ch_borders_bg[i]);
2046
2018-10-17
omar.pol
}
2047
2018-10-17
omar.pol
2048
2018-10-04
omar.pol
if (load_font(&r, fontname) == -1)
2049
2018-10-04
omar.pol
status = ERR;
2050
2018-10-04
omar.pol
2051
2018-10-17
omar.pol
r.xftdraw = XftDrawCreate(r.d, r.w, vinfo.visual, cmap);
2052
2018-10-04
omar.pol
2053
2018-10-19
omar.pol
for (i = 0; i < 3; ++i) {
2054
2019-10-18
omar.pol
rgba_t c;
2055
2019-10-18
omar.pol
XRenderColor xrcolor;
2056
2018-10-04
omar.pol
2057
2019-10-18
omar.pol
c = *(rgba_t *)&fgs[i];
2058
2019-10-18
omar.pol
xrcolor.red = EXPANDBITS(c.rgba.r);
2059
2019-10-18
omar.pol
xrcolor.green = EXPANDBITS(c.rgba.g);
2060
2019-10-18
omar.pol
xrcolor.blue = EXPANDBITS(c.rgba.b);
2061
2019-10-18
omar.pol
xrcolor.alpha = EXPANDBITS(c.rgba.a);
2062
2019-10-20
omar.pol
XftColorAllocValue(r.d, vinfo.visual, cmap, &xrcolor, &r.xft_colors[i]);
2063
2018-10-04
omar.pol
}
2064
2018-05-21
omar.pol
2065
2018-10-06
omar.pol
/* compute prompt dimensions */
2066
2018-10-06
omar.pol
ps1extents(&r);
2067
2018-05-19
omar.pol
2068
2018-10-06
omar.pol
xim_init(&r, &xdb);
2069
2018-05-18
omar.pol
2070
2018-10-06
omar.pol
#ifdef __OpenBSD__
2071
2022-05-16
op
if (pledge("stdio", "") == -1)
2072
2022-05-16
op
err(1, "pledge");
2073
2018-10-06
omar.pol
#endif
2074
2018-10-06
omar.pol
2075
2018-10-17
omar.pol
/* Cache text height */
2076
2018-10-17
omar.pol
text_extents("fyjpgl", 6, &r, NULL, &r.text_height);
2077
2018-10-17
omar.pol
2078
2018-10-09
omar.pol
/* Draw the window for the first time */
2079
2018-10-09
omar.pol
draw(&r, text, cs);
2080
2018-10-09
omar.pol
2081
2018-10-04
omar.pol
/* Main loop */
2082
2018-10-04
omar.pol
while (status == LOOPING || status == OK_LOOP) {
2083
2018-10-04
omar.pol
status = loop(&r, &text, &textlen, cs, lines, vlines);
2084
2018-05-18
omar.pol
2085
2018-10-04
omar.pol
if (status != ERR)
2086
2018-10-04
omar.pol
printf("%s\n", text);
2087
2018-07-15
omar.pol
2088
2018-10-06
omar.pol
if (!r.multiple_select && status == OK_LOOP)
2089
2018-10-04
omar.pol
status = OK;
2090
2018-10-04
omar.pol
}
2091
2018-05-18
omar.pol
2092
2018-10-06
omar.pol
XUngrabKeyboard(r.d, CurrentTime);
2093
2018-10-20
omar.pol
2094
2018-10-20
omar.pol
for (i = 0; i < 3; ++i)
2095
2018-10-20
omar.pol
XftColorFree(r.d, vinfo.visual, cmap, &r.xft_colors[i]);
2096
2018-10-20
omar.pol
2097
2018-10-20
omar.pol
for (i = 0; i < 3; ++i) {
2098
2018-10-20
omar.pol
XFreeGC(r.d, r.fgs[i]);
2099
2018-10-20
omar.pol
XFreeGC(r.d, r.bgs[i]);
2100
2018-10-20
omar.pol
}
2101
2018-07-07
omar.pol
2102
2018-10-20
omar.pol
for (i = 0; i < 4; ++i) {
2103
2018-10-20
omar.pol
XFreeGC(r.d, r.borders_bg[i]);
2104
2018-10-20
omar.pol
XFreeGC(r.d, r.p_borders_bg[i]);
2105
2018-10-20
omar.pol
XFreeGC(r.d, r.c_borders_bg[i]);
2106
2018-10-20
omar.pol
XFreeGC(r.d, r.ch_borders_bg[i]);
2107
2018-10-20
omar.pol
}
2108
2018-10-20
omar.pol
2109
2018-10-20
omar.pol
XDestroyIC(r.xic);
2110
2018-10-20
omar.pol
XCloseIM(r.xim);
2111
2018-10-20
omar.pol
2112
2018-10-19
omar.pol
for (i = 0; i < 3; ++i)
2113
2018-10-19
omar.pol
XftColorFree(r.d, vinfo.visual, cmap, &r.xft_colors[i]);
2114
2018-10-20
omar.pol
XftFontClose(r.d, r.font);
2115
2018-10-20
omar.pol
XftDrawDestroy(r.xftdraw);
2116
2018-07-07
omar.pol
2117
2018-10-06
omar.pol
free(r.ps1);
2118
2018-10-04
omar.pol
free(fontname);
2119
2018-10-04
omar.pol
free(text);
2120
2018-07-07
omar.pol
2121
2018-10-04
omar.pol
free(lines);
2122
2018-10-04
omar.pol
free(vlines);
2123
2018-10-04
omar.pol
compls_delete(cs);
2124
2018-07-07
omar.pol
2125
2018-10-20
omar.pol
XFreeColormap(r.d, cmap);
2126
2018-10-20
omar.pol
2127
2018-10-04
omar.pol
XDestroyWindow(r.d, r.w);
2128
2018-10-04
omar.pol
XCloseDisplay(r.d);
2129
2018-07-07
omar.pol
2130
2018-10-04
omar.pol
return status != OK;
2131
2018-05-18
omar.pol
}
Omar Polo