Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
Luca Bilke | 3caf01a905 | |
Luca Bilke | 5f4bcf8f71 | |
Luca Bilke | 856a9d7094 | |
Luca Bilke | dbd0c5295c | |
Luca Bilke | cdbccd7871 | |
Luca Bilke | 7a3fcf6fe4 |
|
@ -1,8 +0,0 @@
|
||||||
BasedOnStyle: Google
|
|
||||||
IndentWidth: 4
|
|
||||||
InsertBraces: true
|
|
||||||
ColumnLimit: 79
|
|
||||||
AlignConsecutiveMacros: Consecutive
|
|
||||||
AllowShortFunctionsOnASingleLine: None
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
|
30
.clang-tidy
30
.clang-tidy
|
@ -1,30 +0,0 @@
|
||||||
Checks: |
|
|
||||||
-*,
|
|
||||||
abseil-*,
|
|
||||||
bugprone-*,
|
|
||||||
clang-analyzer-*,
|
|
||||||
misc-*,
|
|
||||||
modernize-*,
|
|
||||||
performance-*,
|
|
||||||
portability-*,
|
|
||||||
readability-*,
|
|
||||||
llvm-*,
|
|
||||||
-bugprone-easily-swappable-parameters,
|
|
||||||
-readability-avoid-const-params-in-decls,
|
|
||||||
-readability-identifier-length
|
|
||||||
|
|
||||||
CheckOptions:
|
|
||||||
- key: readability-inconsistent-declaration-parameter-name.Strict
|
|
||||||
value: true
|
|
||||||
- key: readability-identifier-naming.StructCase
|
|
||||||
value: lower_case
|
|
||||||
- key: readability-identifier-naming.FunctionCase
|
|
||||||
value: lower_case
|
|
||||||
- key: readability-identifier-naming.VariableCase
|
|
||||||
value: lower_case
|
|
||||||
- key: readability-identifier-naming.EnumConstantCase
|
|
||||||
value: UPPER_CASE
|
|
||||||
- key: readability-identifier-naming.MacroDefinitionCase
|
|
||||||
value: UPPER_CASE
|
|
||||||
- key: readability-function-cognitive-complexity.Threshold
|
|
||||||
value: 15
|
|
|
@ -1,4 +1,3 @@
|
||||||
build
|
build
|
||||||
*.o
|
*.o
|
||||||
pinentry-dmenu
|
pinentry-dmenu
|
||||||
compile_commands.json
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
when:
|
when:
|
||||||
event: tag
|
- event: tag
|
||||||
|
- event: manual
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
build:
|
build:
|
||||||
image: ghcr.io/void-linux/void-glibc
|
image: gcc
|
||||||
environment:
|
environment:
|
||||||
- BUILD_DEPS=base-devel libX11-devel libXinerama-devel libXft-devel libconfig-devel gpgme-devel libassuan-devel
|
- BUILD_DEPS=libx11-dev libxinerama-dev libxft-dev libfreetype6-dev libgpgme-dev libfontconfig1-dev libassuan-dev
|
||||||
commands: |
|
commands: |
|
||||||
xbps-install -Sy $${BUILD_DEPS} >/dev/null 2>&1
|
apt-get update
|
||||||
|
apt-get install -y $${BUILD_DEPS}
|
||||||
make install DESTDIR="$${CI_WORKSPACE}/pkg" PREFIX="/usr"
|
make install DESTDIR="$${CI_WORKSPACE}/pkg" PREFIX="/usr"
|
||||||
|
|
||||||
package-xbps:
|
package-xbps:
|
||||||
|
@ -47,7 +50,7 @@ steps:
|
||||||
- source: xbps_pem_passphrase
|
- source: xbps_pem_passphrase
|
||||||
target: XBPS_PASSPHRASE
|
target: XBPS_PASSPHRASE
|
||||||
volumes:
|
volumes:
|
||||||
- /srv/xbps:/target
|
- /var/www/xbps:/target
|
||||||
- /etc/woodpecker/:/etc/woodpecker:ro
|
- /etc/woodpecker/:/etc/woodpecker:ro
|
||||||
commands: |
|
commands: |
|
||||||
export XBPS_TARGET_ARCH
|
export XBPS_TARGET_ARCH
|
||||||
|
|
78
Makefile
78
Makefile
|
@ -1,66 +1,68 @@
|
||||||
# pinentry-dmenu - dmenu-like stupid pin entry
|
# pinentry-dmenu - dmenu-like stupid pin entry
|
||||||
# See LICENSE file for copyright and license details.
|
# See LICENSE file for copyright and license details.
|
||||||
|
.POSIX:
|
||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
SRC = pinentry-dmenu.c drw.c util.c
|
SRC = pinentry-dmenu.c drw.c util.c
|
||||||
OBJ = ${SRC:.c=.o}
|
OBJ = $(SRC:.c=.o)
|
||||||
OBJ_PIN = pinentry/pinentry.o pinentry/util.o pinentry/password-cache.o pinentry/argparse.o pinentry/secmem.o
|
PIN_SRC = \
|
||||||
|
pinentry/argparse.c\
|
||||||
|
pinentry/password-cache.c\
|
||||||
|
pinentry/pinentry.c\
|
||||||
|
pinentry/secmem.c\
|
||||||
|
pinentry/util.c
|
||||||
|
PIN_OBJ = $(PIN_SRC:.c=.o)
|
||||||
|
PIN_DEP = \
|
||||||
|
pinentry/argparse.h\
|
||||||
|
pinentry/password-cache.h\
|
||||||
|
pinentry/pinentry.h\
|
||||||
|
pinentry/memory.h\
|
||||||
|
pinentry/util.h
|
||||||
|
|
||||||
all: options pinentry-dmenu
|
all: options pinentry-dmenu
|
||||||
|
|
||||||
options:
|
options:
|
||||||
@echo pinentry-dmenu build options:
|
@echo pinentry-dmenu build options:
|
||||||
@echo "CFLAGS = ${CFLAGS}"
|
@echo "CFLAGS = $(CFLAGS)"
|
||||||
@echo "LDFLAGS = ${LDFLAGS}"
|
@echo "LDFLAGS = $(LDFLAGS)"
|
||||||
@echo "CC = ${CC}"
|
@echo "CC = $(CC)"
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
@echo CC $<
|
$(CC) -c $(CFLAGS) $(INCS) $(CPPFLAGS) -o $@ -c $<
|
||||||
@${CC} -c ${CFLAGS} $<
|
|
||||||
|
|
||||||
config.h:
|
config.h:
|
||||||
@echo creating $@ from config.def.h
|
cp config.def.h $@
|
||||||
@cp config.def.h $@
|
|
||||||
|
|
||||||
${OBJ}: config.h config.mk drw.h
|
$(OBJ): config.h config.mk drw.h
|
||||||
|
|
||||||
pinentry:
|
$(PIN_OBJ): $(PIN_DEP)
|
||||||
$(MAKE) -C pinentry
|
|
||||||
|
|
||||||
pinentry-dmenu: pinentry pinentry-dmenu.o drw.o util.o
|
pinentry-dmenu: $(OBJ) $(PIN_OBJ)
|
||||||
@echo CC -o $@
|
$(CC) -o $@ $(OBJ) $(PIN_OBJ) $(LDFLAGS) $(LIBS)
|
||||||
@${CC} -o $@ ${OBJ} ${OBJ_PIN} ${LDFLAGS} -lassuan -lgpgme -lgpg-error -lconfig
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@echo cleaning
|
rm -f pinentry-dmenu $(OBJ) $(PIN_OBJ)
|
||||||
@rm -f pinentry-dmenu ${OBJ}
|
|
||||||
$(MAKE) -C pinentry/ clean
|
|
||||||
|
|
||||||
dist: clean
|
dist: clean
|
||||||
@echo creating dist tarball
|
mkdir -p pinentry-dmenu-$(VERSION)
|
||||||
@mkdir -p dmenu-${VERSION}
|
cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1 \
|
||||||
@cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1 \
|
drw.h util.h $(SRC) \
|
||||||
drw.h util.h dmenu_path dmenu_run stest.1 ${SRC} \
|
pinentry-dmenu-$(VERSION)
|
||||||
dmenu-${VERSION}
|
tar -cf pinentry-dmenu-$(VERSION).tar pinentry-dmenu-$(VERSION)
|
||||||
@tar -cf dmenu-${VERSION}.tar dmenu-${VERSION}
|
gzip pinentry-dmenu-$(VERSION).tar
|
||||||
@gzip dmenu-${VERSION}.tar
|
rm -rf pinentry-dmenu-$(VERSION)
|
||||||
@rm -rf dmenu-${VERSION}
|
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
@echo installing executable to ${DESTDIR}${PREFIX}/bin
|
mkdir -p $(DESTDIR)$(PREFIX)/bin
|
||||||
@mkdir -p ${DESTDIR}${PREFIX}/bin
|
cp -f pinentry-dmenu $(DESTDIR)$(PREFIX)/bin
|
||||||
@cp -f pinentry-dmenu ${DESTDIR}${PREFIX}/bin
|
chmod 755 $(DESTDIR)$(PREFIX)/bin/pinentry-dmenu
|
||||||
@chmod 755 ${DESTDIR}${PREFIX}/bin/pinentry-dmenu
|
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
|
||||||
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
|
sed "s/VERSION/$(VERSION)/g" < pinentry-dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/pinentry-dmenu.1
|
||||||
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/pinentry-dmenu.1
|
||||||
@sed "s/VERSION/${VERSION}/g;s/DATE/${DATE}/g;s/BUGREPORT/${BUGREPORT}/g" < pinentry-dmenu.1 > ${DESTDIR}${MANPREFIX}/man1/pinentry-dmenu.1
|
|
||||||
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/pinentry-dmenu.1
|
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
@echo removing executable from ${DESTDIR}${PREFIX}/bin
|
rm -f $(DESTDIR)$(PREFIX)/bin/pinentry-dmenu
|
||||||
@rm -f ${DESTDIR}${PREFIX}/bin/pinentry-dmenu
|
rm -f $(DESTDIR)$(MANPREFIX)/man1/pinentry-dmenu.1
|
||||||
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
|
|
||||||
@rm -f ${DESTDIR}${MANPREFIX}/man1/pinentry-dmenu.1
|
|
||||||
|
|
||||||
.PHONY: all options clean dist install pinentry uninstall
|
.PHONY: all options clean dist install pinentry uninstall
|
||||||
|
|
41
README.md
41
README.md
|
@ -5,6 +5,8 @@ pinentry-dmenu is a pinentry program with the charm of [dmenu](https://tools.suc
|
||||||
|
|
||||||
This program is a fork from [spine](https://gitgud.io/zavok/spine.git) which is also a fork from [dmenu](https://tools.suckless.org/dmenu).
|
This program is a fork from [spine](https://gitgud.io/zavok/spine.git) which is also a fork from [dmenu](https://tools.suckless.org/dmenu).
|
||||||
|
|
||||||
|
This is a further fork of pinentry-dmenu with many of the upstream [dmenu](https://tools.suckless.org/dmenu) changes merged and config file support removed.
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
@ -25,41 +27,4 @@ Config
|
||||||
------
|
------
|
||||||
To use pinentry-dmenu add in `~/.gnupg/gpg-agent.conf`:
|
To use pinentry-dmenu add in `~/.gnupg/gpg-agent.conf`:
|
||||||
|
|
||||||
pinentry-program <absolute path to pinentry-dmenu>
|
pinentry-program <absolut path to pinentry-dmenu>
|
||||||
|
|
||||||
The config is located in `~/.gnupg/pinentry-dmenu.conf`.
|
|
||||||
|
|
||||||
Parameter | Default | Description
|
|
||||||
:------------------ |:----------------- |:-----------
|
|
||||||
asterisk | * | Defines the symbol which is showed for each typed character
|
|
||||||
bottom | false | pinentry-dmenu appears at the bottom of the screen
|
|
||||||
min_password_length | 32 | The minimal space of the password field. This value has affect to the description field after the password field
|
|
||||||
monitor | -1 | pinentry-dmenu is displayed on the monitor number supplied. Monitor numbers are starting from 0
|
|
||||||
prompt | "" | Defines the prompt to be displayed to the left of the input field
|
|
||||||
font | monospace:size=10 | Defines the font or font set used
|
|
||||||
prompt_bg | #bbbbbb | Defines the prompt background color
|
|
||||||
prompt_fg | #222222 | Defines the prompt foreground color
|
|
||||||
normal_bg | #bbbbbb | Defines the normal background color
|
|
||||||
normal_fg | #222222 | Defines the normal foreground color
|
|
||||||
select_bg | #eeeeee | Defines the selected background color
|
|
||||||
select_fg | #005577 | Defines the selected foreground color
|
|
||||||
desc_bg | #bbbbbb | Defines the description background color
|
|
||||||
desc_fg | #222222 | Defines the description foreground color
|
|
||||||
embedded | false | Embed into window
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
```
|
|
||||||
asterisk= "# ";
|
|
||||||
prompt = "$";
|
|
||||||
font = "Noto Sans UI:size=13";
|
|
||||||
prompt_fg = "#eeeeee";
|
|
||||||
prompt_bg = "#d9904a";
|
|
||||||
normal_fg = "#ffffff";
|
|
||||||
normal_bg = "#000000";
|
|
||||||
select_fg = "#eeeeee";
|
|
||||||
select_bg = "#d9904a";
|
|
||||||
desc_fg = "#eeeeee";
|
|
||||||
desc_bg = "#d9904a";
|
|
||||||
```
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
/* minimum length to use for displaying the pw field */
|
||||||
|
static int minpwflen = 16;
|
||||||
|
|
||||||
|
/* character to be used as a replacement for typed characters */
|
||||||
|
static const char *asterisk = "*";
|
||||||
|
|
||||||
|
/* if 0, pinentry-dmenu appears at bottom */
|
||||||
|
static int topbar = 1;
|
||||||
|
|
||||||
|
/* default X11 font or font set */
|
||||||
|
static const char *fonts[] = {
|
||||||
|
"monospace:size=10"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *prompt = NULL;
|
||||||
|
static const char *colors[SchemeLast][2] = {
|
||||||
|
/* fg bg */
|
||||||
|
[SchemePrompt] = { "#bbbbbb", "#222222" },
|
||||||
|
[SchemeNorm] = { "#bbbbbb", "#222222" },
|
||||||
|
[SchemeSel] = { "#eeeeee", "#005577" },
|
||||||
|
[SchemeDesc] = { "#bbbbbb", "#222222" }
|
||||||
|
};
|
17
config.h
17
config.h
|
@ -1,22 +1,15 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
static int minpwlen = 16;
|
||||||
/* Default settings; can be overriden by command line. */
|
|
||||||
|
|
||||||
static int bottom = 0;
|
|
||||||
static int embedded = 0;
|
|
||||||
static int minpwlen = 32;
|
|
||||||
static int mon = -1;
|
|
||||||
static int lineheight = 0;
|
|
||||||
static int min_lineheight = 8;
|
|
||||||
|
|
||||||
static const char *asterisk = "";
|
static const char *asterisk = "";
|
||||||
|
static int topbar = 1;
|
||||||
static const char *fonts[] = {
|
static const char *fonts[] = {
|
||||||
"FiraCode Nerd Font Mono:pixelsize=14",
|
"FiraCode Nerd Font Mono:pixelsize=14",
|
||||||
"Noto Color Emoji:pixelsize=14",
|
"Noto Color Emoji:pixelsize=14",
|
||||||
"FontAwesome:pixelsize=14"
|
"FontAwesome:pixelsize=14"
|
||||||
};
|
};
|
||||||
static const char *prompt = "";
|
static const char *prompt = "";
|
||||||
static const char *colors[SchemeLast][4] = {
|
static const char *colors[SchemeLast][4] = {
|
||||||
[SchemePrompt] = {"#7aa2f7", "#15161E"},
|
[SchemePrompt] = {"#7aa2f7", "#15161E"},
|
||||||
[SchemeNormal] = {"#7aa2f7", "#15161E"},
|
[SchemeNormal] = {"#7aa2f7", "#15161E"},
|
||||||
[SchemeSelect] = {"#15161E", "#7aa2f7"},
|
[SchemeSelect] = {"#15161E", "#7aa2f7"},
|
||||||
[SchemeDesc] = {"#7aa2f7", "#15161E"}};
|
[SchemeDesc] = {"#7aa2f7", "#15161E"}
|
||||||
|
};
|
||||||
|
|
17
config.mk
17
config.mk
|
@ -1,11 +1,10 @@
|
||||||
# Pinentry settings
|
# Pinentry settings
|
||||||
DATE = $$(date +'%B %Y')
|
|
||||||
VERSION = 0.1
|
VERSION = 0.1
|
||||||
BUGREPORT = https:\/\/github.com\/ritze\/pinentry-dmenu
|
BUGREPORT = https:\/\/github.com\/0x766F6964\/pinentry-dmenu
|
||||||
|
|
||||||
# Paths
|
# Paths
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
MANPREFIX = ${PREFIX}/share/man
|
MANPREFIX = $(PREFIX)/share/man
|
||||||
|
|
||||||
X11INC = /usr/X11R6/include
|
X11INC = /usr/X11R6/include
|
||||||
X11LIB = /usr/X11R6/lib
|
X11LIB = /usr/X11R6/lib
|
||||||
|
@ -18,16 +17,16 @@ XINERAMAFLAGS = -DXINERAMA
|
||||||
FREETYPELIBS = -lfontconfig -lXft
|
FREETYPELIBS = -lfontconfig -lXft
|
||||||
FREETYPEINC = /usr/include/freetype2
|
FREETYPEINC = /usr/include/freetype2
|
||||||
# OpenBSD (uncomment)
|
# OpenBSD (uncomment)
|
||||||
#FREETYPEINC = ${X11INC}/freetype2
|
#FREETYPEINC = $(X11INC)/freetype2
|
||||||
|
|
||||||
# Includes and libs
|
# Includes and libs
|
||||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
INCS = -I$(X11INC) -I$(FREETYPEINC)
|
||||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
LIBS = -lassuan -lgpg-error -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -DPACKAGE_VERSION=\"${VERSION}\" -DPACKAGE_BUGREPORT=\"${BUGREPORT}\"
|
CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) -DPACKAGE_VERSION=\"$(VERSION)\" -DPACKAGE_BUGREPORT=\"$(BUGREPORT)\" -DHAVE_MLOCK
|
||||||
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
|
CFLAGS = -std=c99 -pedantic -Wall -Os
|
||||||
LDFLAGS = -s ${LIBS}
|
LDFLAGS = -s
|
||||||
|
|
||||||
# Compiler and linker
|
# Compiler and linker
|
||||||
CC = cc
|
CC = cc
|
||||||
|
|
80
drw.c
80
drw.c
|
@ -95,6 +95,7 @@ drw_free(Drw *drw)
|
||||||
{
|
{
|
||||||
XFreePixmap(drw->dpy, drw->drawable);
|
XFreePixmap(drw->dpy, drw->drawable);
|
||||||
XFreeGC(drw->dpy, drw->gc);
|
XFreeGC(drw->dpy, drw->gc);
|
||||||
|
drw_fontset_free(drw->fonts);
|
||||||
free(drw);
|
free(drw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,12 +238,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
|
||||||
int
|
int
|
||||||
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
int ty, ellipsis_x = 0;
|
||||||
int ty;
|
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
|
||||||
unsigned int ew;
|
|
||||||
XftDraw *d = NULL;
|
XftDraw *d = NULL;
|
||||||
Fnt *usedfont, *curfont, *nextfont;
|
Fnt *usedfont, *curfont, *nextfont;
|
||||||
size_t i, len;
|
|
||||||
int utf8strlen, utf8charlen, render = x || y || w || h;
|
int utf8strlen, utf8charlen, render = x || y || w || h;
|
||||||
long utf8codepoint = 0;
|
long utf8codepoint = 0;
|
||||||
const char *utf8str;
|
const char *utf8str;
|
||||||
|
@ -250,13 +249,15 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
FcPattern *fcpattern;
|
FcPattern *fcpattern;
|
||||||
FcPattern *match;
|
FcPattern *match;
|
||||||
XftResult result;
|
XftResult result;
|
||||||
int charexists = 0;
|
int charexists = 0, overflow = 0;
|
||||||
|
/* keep track of a couple codepoints for which we have no match. */
|
||||||
|
static unsigned int nomatches[128], ellipsis_width;
|
||||||
|
|
||||||
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
|
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!render) {
|
if (!render) {
|
||||||
w = ~w;
|
w = invert ? invert : ~invert;
|
||||||
} else {
|
} else {
|
||||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||||
|
@ -268,8 +269,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
}
|
}
|
||||||
|
|
||||||
usedfont = drw->fonts;
|
usedfont = drw->fonts;
|
||||||
|
if (!ellipsis_width && render)
|
||||||
|
ellipsis_width = drw_fontset_getwidth(drw, "...");
|
||||||
while (1) {
|
while (1) {
|
||||||
utf8strlen = 0;
|
ew = ellipsis_len = utf8strlen = 0;
|
||||||
utf8str = text;
|
utf8str = text;
|
||||||
nextfont = NULL;
|
nextfont = NULL;
|
||||||
while (*text) {
|
while (*text) {
|
||||||
|
@ -277,9 +280,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||||
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||||
if (charexists) {
|
if (charexists) {
|
||||||
if (curfont == usedfont) {
|
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
|
||||||
|
if (ew + ellipsis_width <= w) {
|
||||||
|
/* keep track where the ellipsis still fits */
|
||||||
|
ellipsis_x = x + ew;
|
||||||
|
ellipsis_w = w - ew;
|
||||||
|
ellipsis_len = utf8strlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ew + tmpw > w) {
|
||||||
|
overflow = 1;
|
||||||
|
/* called from drw_fontset_getwidth_clamp():
|
||||||
|
* it wants the width AFTER the overflow
|
||||||
|
*/
|
||||||
|
if (!render)
|
||||||
|
x += tmpw;
|
||||||
|
else
|
||||||
|
utf8strlen = ellipsis_len;
|
||||||
|
} else if (curfont == usedfont) {
|
||||||
utf8strlen += utf8charlen;
|
utf8strlen += utf8charlen;
|
||||||
text += utf8charlen;
|
text += utf8charlen;
|
||||||
|
ew += tmpw;
|
||||||
} else {
|
} else {
|
||||||
nextfont = curfont;
|
nextfont = curfont;
|
||||||
}
|
}
|
||||||
|
@ -287,36 +308,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!charexists || nextfont)
|
if (overflow || !charexists || nextfont)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
charexists = 0;
|
charexists = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utf8strlen) {
|
if (utf8strlen) {
|
||||||
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
|
|
||||||
/* shorten text if necessary */
|
|
||||||
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
|
|
||||||
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
|
|
||||||
|
|
||||||
if (len) {
|
|
||||||
memcpy(buf, utf8str, len);
|
|
||||||
buf[len] = '\0';
|
|
||||||
if (len < utf8strlen)
|
|
||||||
for (i = len; i && i > len - 3; buf[--i] = '.')
|
|
||||||
; /* NOP */
|
|
||||||
|
|
||||||
if (render) {
|
if (render) {
|
||||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||||
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
|
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
|
||||||
}
|
}
|
||||||
x += ew;
|
x += ew;
|
||||||
w -= ew;
|
w -= ew;
|
||||||
}
|
}
|
||||||
}
|
if (render && overflow)
|
||||||
|
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
|
||||||
|
|
||||||
if (!*text) {
|
if (!*text || overflow) {
|
||||||
break;
|
break;
|
||||||
} else if (nextfont) {
|
} else if (nextfont) {
|
||||||
charexists = 0;
|
charexists = 0;
|
||||||
|
@ -326,6 +336,15 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
* character must be drawn. */
|
* character must be drawn. */
|
||||||
charexists = 1;
|
charexists = 1;
|
||||||
|
|
||||||
|
hash = (unsigned int)utf8codepoint;
|
||||||
|
hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
|
||||||
|
hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
|
||||||
|
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
|
||||||
|
h1 = (hash >> 17) % LENGTH(nomatches);
|
||||||
|
/* avoid expensive XftFontMatch call when we know we won't find a match */
|
||||||
|
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint)
|
||||||
|
goto no_match;
|
||||||
|
|
||||||
fccharset = FcCharSetCreate();
|
fccharset = FcCharSetCreate();
|
||||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||||
|
|
||||||
|
@ -353,6 +372,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
curfont->next = usedfont;
|
curfont->next = usedfont;
|
||||||
} else {
|
} else {
|
||||||
xfont_free(usedfont);
|
xfont_free(usedfont);
|
||||||
|
nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint;
|
||||||
|
no_match:
|
||||||
usedfont = drw->fonts;
|
usedfont = drw->fonts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,6 +403,15 @@ drw_fontset_getwidth(Drw *drw, const char *text)
|
||||||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned int tmp = 0;
|
||||||
|
if (drw && drw->fonts && text && n)
|
||||||
|
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
|
||||||
|
return MIN(n, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
||||||
{
|
{
|
||||||
|
|
1
drw.h
1
drw.h
|
@ -35,6 +35,7 @@ void drw_free(Drw *drw);
|
||||||
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
||||||
void drw_fontset_free(Fnt* set);
|
void drw_fontset_free(Fnt* set);
|
||||||
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||||
|
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
|
||||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||||
|
|
||||||
/* Colorscheme abstraction */
|
/* Colorscheme abstraction */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.TH PINENTRY-DMENU 1 "DATE" pinentry-dmenu\-VERSION "pinentry-dmenu Manual"
|
.TH PINENTRY-DMENU 1 pinentry-dmenu\-VERSION "pinentry-dmenu Manual"
|
||||||
|
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
|
@ -19,63 +19,6 @@ to
|
||||||
.B pinentry-dmenu
|
.B pinentry-dmenu
|
||||||
to use the program as the regular dialog for
|
to use the program as the regular dialog for
|
||||||
.BR gpg-agent .
|
.BR gpg-agent .
|
||||||
.PP
|
|
||||||
The configuration is placed in
|
|
||||||
.IR ~/.gnupg/pinentry-dmenu.conf .
|
|
||||||
You can change the path to the config file with the environment variable
|
|
||||||
.IR GNUPGHOME .
|
|
||||||
|
|
||||||
|
|
||||||
.SH OPTIONS
|
|
||||||
.TP
|
|
||||||
.BI "asterisk =" " *"
|
|
||||||
Defines the symbol which is showed for each typed character.
|
|
||||||
.TP
|
|
||||||
.BI "bottom =" " false"
|
|
||||||
pinentry-dmenu appears at the bottom of the screen.
|
|
||||||
.TP
|
|
||||||
.BI "min_password_length =" " 32"
|
|
||||||
The minimal space of the password field. This value has affect to the description field after the password field.
|
|
||||||
.TP
|
|
||||||
.BI "monitor =" " -1"
|
|
||||||
pinentry-dmenu is displayed on the monitor number supplied. Monitor numbers are starting from 0.
|
|
||||||
.TP
|
|
||||||
.BI "prompt =" " """"
|
|
||||||
Defines the prompt to be displayed to the left of the input field.
|
|
||||||
.TP
|
|
||||||
.BI "font =" " monospace:size=10"
|
|
||||||
Defines the font or font set used.
|
|
||||||
.TP
|
|
||||||
.BI "prompt_bg =" " #bbbbbb"
|
|
||||||
Defines the prompt background color.
|
|
||||||
.IR #RGB ,
|
|
||||||
.I #RRGGBB
|
|
||||||
and X color names are supported.
|
|
||||||
.TP
|
|
||||||
.BI "prompt_fg =" " #222222"
|
|
||||||
Defines the prompt foreground color.
|
|
||||||
.TP
|
|
||||||
.BI "normal_bg =" " #bbbbbb"
|
|
||||||
Defines the normal background color.
|
|
||||||
.TP
|
|
||||||
.BI "normal_fg =" " #222222"
|
|
||||||
Defines the normal foreground color.
|
|
||||||
.TP
|
|
||||||
.BI "select_bg =" " #eeeeee"
|
|
||||||
Defines the selected background color.
|
|
||||||
.TP
|
|
||||||
.BI "select_fg =" " #005577"
|
|
||||||
Defines the selected foreground color.
|
|
||||||
.TP
|
|
||||||
.BI "desc_bg =" " #bbbbbb"
|
|
||||||
Defines the description background color.
|
|
||||||
.TP
|
|
||||||
.BI "desc_fg =" " #222222"
|
|
||||||
Defines the description foreground color.
|
|
||||||
.TP
|
|
||||||
.BI "embedded =" " false"
|
|
||||||
Embed into window.
|
|
||||||
|
|
||||||
|
|
||||||
.SH USAGE
|
.SH USAGE
|
||||||
pinentry-dmenu is completely controlled by the keyboard.
|
pinentry-dmenu is completely controlled by the keyboard.
|
||||||
|
@ -184,25 +127,6 @@ Delete line left
|
||||||
Paste from primary X selection
|
Paste from primary X selection
|
||||||
|
|
||||||
|
|
||||||
.SH EXAMPLES
|
|
||||||
.sp
|
|
||||||
.if n \{
|
|
||||||
.RS 4
|
|
||||||
.\}
|
|
||||||
.nf
|
|
||||||
asterisk= "# ";
|
|
||||||
prompt = "$";
|
|
||||||
font = "Noto Sans UI:size=13";
|
|
||||||
prompt_fg = "#eeeeee";
|
|
||||||
prompt_bg = "#d9904a";
|
|
||||||
normal_fg = "#ffffff";
|
|
||||||
normal_bg = "#000000";
|
|
||||||
select_fg = "#eeeeee";
|
|
||||||
select_bg = "#d9904a";
|
|
||||||
desc_fg = "#eeeeee";
|
|
||||||
desc_bg = "#d9904a";
|
|
||||||
|
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
.B pinentry-dmenu
|
.B pinentry-dmenu
|
||||||
is a fork of
|
is a fork of
|
||||||
|
@ -214,11 +138,6 @@ and uses the api of
|
||||||
.B pinentry-dmenu
|
.B pinentry-dmenu
|
||||||
itself was written by Moritz Lüdecke <ritze@skweez.net>.
|
itself was written by Moritz Lüdecke <ritze@skweez.net>.
|
||||||
|
|
||||||
|
|
||||||
.SH REPORTING BUGS
|
|
||||||
Report pinentry-dmenu bugs to <BUGREPORT>
|
|
||||||
|
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR dmenu (1),
|
.BR dmenu (1),
|
||||||
.BR dwm (1),
|
.BR dwm (1),
|
||||||
|
|
427
pinentry-dmenu.c
427
pinentry-dmenu.c
|
@ -1,6 +1,5 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <libconfig.h>
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -25,28 +24,24 @@
|
||||||
#include "pinentry/pinentry.h"
|
#include "pinentry/pinentry.h"
|
||||||
#include "pinentry/memory.h"
|
#include "pinentry/memory.h"
|
||||||
|
|
||||||
#define CONFIG_DIR "/.gnupg"
|
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
|
||||||
#define CONFIG_FILE "/pinentry-dmenu.conf"
|
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
|
||||||
#define INTERSECT(x, y, w, h, r) \
|
|
||||||
(MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
|
|
||||||
&& MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
|
|
||||||
#define LENGTH(X) (sizeof(X) / sizeof(X[0]))
|
|
||||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||||
#define MINDESCLEN 8
|
#define MINDESCLEN 8
|
||||||
|
|
||||||
|
/* enums */
|
||||||
enum { SchemePrompt, SchemeNormal, SchemeSelect, SchemeDesc, SchemeLast };
|
enum { SchemePrompt, SchemeNormal, SchemeSelect, SchemeDesc, SchemeLast }; /* color schemes */
|
||||||
enum { WinPin, WinConfirm };
|
enum { WinPin, WinConfirm };
|
||||||
enum { Ok, NotOk, Cancel };
|
|
||||||
enum { Nothing, Yes, No };
|
enum { Nothing, Yes, No };
|
||||||
|
|
||||||
|
/* FIXME: this can't currently be set */
|
||||||
|
static char *embed;
|
||||||
static int bh, mw, mh;
|
static int bh, mw, mh;
|
||||||
static int sel;
|
static int sel;
|
||||||
static int promptw, pdescw;
|
static int promptw, pdescw;
|
||||||
/* Sum of left and right padding */
|
static int lrpad; /* sum of left and right padding */
|
||||||
static int lrpad;
|
|
||||||
static size_t cursor;
|
static size_t cursor;
|
||||||
static int screen;
|
static int mon = -1, screen;
|
||||||
|
|
||||||
static char *pin;
|
static char *pin;
|
||||||
static int pin_len;
|
static int pin_len;
|
||||||
|
@ -69,7 +64,8 @@ pinentry_t pinentry_info;
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
drawitem(const char* text, Bool sel, int x, int y, int w) {
|
drawitem(const char* text, Bool sel, int x, int y, int w)
|
||||||
|
{
|
||||||
unsigned int i = (sel) ? SchemeSelect : SchemeNormal;
|
unsigned int i = (sel) ? SchemeSelect : SchemeNormal;
|
||||||
|
|
||||||
drw_setscheme(drw, scheme[i]);
|
drw_setscheme(drw, scheme[i]);
|
||||||
|
@ -78,57 +74,54 @@ drawitem(const char* text, Bool sel, int x, int y, int w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grabfocus(void) {
|
grabfocus(void)
|
||||||
|
{
|
||||||
|
struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
|
||||||
Window focuswin;
|
Window focuswin;
|
||||||
int i, revertwin;
|
int i, revertwin;
|
||||||
|
|
||||||
for (i = 0; i < 100; ++i) {
|
for (i = 0; i < 100; ++i) {
|
||||||
XGetInputFocus(dpy, &focuswin, &revertwin);
|
XGetInputFocus(dpy, &focuswin, &revertwin);
|
||||||
if (focuswin == win) {
|
if (focuswin == win)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
|
XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
|
||||||
usleep(1000);
|
nanosleep(&ts, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
die("cannot grab focus");
|
die("cannot grab focus");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grabkeyboard(void) {
|
grabkeyboard(void)
|
||||||
|
{
|
||||||
|
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (embedded) {
|
if (embed)
|
||||||
return;
|
return;
|
||||||
}
|
/* try to grab keyboard, we may have to wait for another process to ungrab */
|
||||||
|
|
||||||
/* Try to grab keyboard,
|
|
||||||
* we may have to wait for another process to ungrab */
|
|
||||||
for (i = 0; i < 1000; i++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
|
if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
|
||||||
GrabModeAsync, CurrentTime) == GrabSuccess) {
|
GrabModeAsync, CurrentTime) == GrabSuccess)
|
||||||
return;
|
return;
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
}
|
}
|
||||||
usleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
die("cannot grab keyboard");
|
die("cannot grab keyboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
nextrune(int cursor, int inc) {
|
nextrune(int inc)
|
||||||
|
{
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
/* Return location of next utf8 rune in the given direction (+1 or -1) */
|
/* return location of next utf8 rune in the given direction (+1 or -1) */
|
||||||
for (n = cursor + inc;
|
for (n = cursor + inc; n + inc >= 0 && (pin[n] & 0xc0) == 0x80; n += inc)
|
||||||
n + inc >= 0 && (pin[n] & 0xc0) == 0x80;
|
;
|
||||||
n += inc);
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_pin(char* pin_ptr, int len, int reset) {
|
setup_pin(char *pin_ptr, int len, int reset)
|
||||||
|
{
|
||||||
pin = pin_ptr;
|
pin = pin_ptr;
|
||||||
pin_len = len;
|
pin_len = len;
|
||||||
|
|
||||||
|
@ -136,14 +129,14 @@ setup_pin(char* pin_ptr, int len, int reset) {
|
||||||
promptw = (prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
|
promptw = (prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
|
|
||||||
if (pin) {
|
if (pin)
|
||||||
pin[0] = '\0';
|
pin[0] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
insert(const char *str, ssize_t n) {
|
insert(const char *str, ssize_t n)
|
||||||
|
{
|
||||||
size_t len = strlen(pin);
|
size_t len = strlen(pin);
|
||||||
|
|
||||||
// FIXME: Pinentry crashes when increasing the pin buffer the second time.
|
// FIXME: Pinentry crashes when increasing the pin buffer the second time.
|
||||||
|
@ -153,37 +146,35 @@ insert(const char *str, ssize_t n) {
|
||||||
pin_repeat_len = 2 * pin_repeat_len;
|
pin_repeat_len = 2 * pin_repeat_len;
|
||||||
pin_repeat = secmem_realloc(pin_repeat, pin_repeat_len);
|
pin_repeat = secmem_realloc(pin_repeat, pin_repeat_len);
|
||||||
setup_pin(pin_repeat, pin_repeat_len, 0);
|
setup_pin(pin_repeat, pin_repeat_len, 0);
|
||||||
if (!pin_repeat) {
|
if (!pin_repeat)
|
||||||
pin_len = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!pinentry_setbufferlen(pinentry_info, 2 * pinentry_info->pin_len)) {
|
|
||||||
pin_len = 0;
|
pin_len = 0;
|
||||||
} else {
|
} else {
|
||||||
|
if (!pinentry_setbufferlen(pinentry_info, 2 * pinentry_info->pin_len))
|
||||||
|
pin_len = 0;
|
||||||
|
else
|
||||||
setup_pin(pinentry_info->pin, pinentry_info->pin_len, 0);
|
setup_pin(pinentry_info->pin, pinentry_info->pin_len, 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (pin_len == 0) {
|
if (pin_len == 0) {
|
||||||
printf("Error: Couldn't allocate secure memory\n");
|
printf("Error: Couldn't allocate secure memory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move existing text out of the way, insert new text, and update cursor */
|
/* move existing text out of the way, insert new text, and update cursor */
|
||||||
memmove(&pin[cursor + n], &pin[cursor], pin_len - cursor - MAX(n, 0));
|
memmove(&pin[cursor + n], &pin[cursor], pin_len - cursor - MAX(n, 0));
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0)
|
||||||
memcpy(&pin[cursor], str, n);
|
memcpy(&pin[cursor], str, n);
|
||||||
}
|
|
||||||
|
|
||||||
cursor += n;
|
cursor += n;
|
||||||
pin[len + n] = '\0';
|
pin[len + n] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drawwin(void) {
|
drawmenu(void)
|
||||||
|
{
|
||||||
unsigned int curpos;
|
unsigned int curpos;
|
||||||
int x = 0, pb, pbw = 0, i;
|
int x = 0, fh = drw->fonts->h, pb, pbw = 0, i;
|
||||||
size_t asterlen = strlen(asterisk);
|
size_t asterlen = strlen(asterisk);
|
||||||
size_t pdesclen;
|
size_t pdesclen;
|
||||||
int leftinput;
|
int leftinput;
|
||||||
|
@ -223,11 +214,9 @@ drawwin(void) {
|
||||||
pbw = MIN(pbw, pb);
|
pbw = MIN(pbw, pb);
|
||||||
pb = mw - pbw;
|
pb = mw - pbw;
|
||||||
|
|
||||||
for (i = 0; i < pdesclen; i++) {
|
for (i = 0; i < pdesclen; i++)
|
||||||
if (pinentry_info->description[i] == '\n') {
|
if (pinentry_info->description[i] == '\n')
|
||||||
pinentry_info->description[i] = ' ';
|
pinentry_info->description[i] = ' ';
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drw_setscheme(drw, scheme[SchemeDesc]);
|
drw_setscheme(drw, scheme[SchemeDesc]);
|
||||||
drw_text(drw, pb, 0, pbw, bh, lrpad / 2, pinentry_info->description,
|
drw_text(drw, pb, 0, pbw, bh, lrpad / 2, pinentry_info->description,
|
||||||
|
@ -244,18 +233,17 @@ drawwin(void) {
|
||||||
if (winmode == WinPin) {
|
if (winmode == WinPin) {
|
||||||
censort = ecalloc(1, asterlen * pin_len);
|
censort = ecalloc(1, asterlen * pin_len);
|
||||||
|
|
||||||
for (i = 0; i < asterlen * strlen(pin); i += asterlen) {
|
for (i = 0; i < asterlen * strlen(pin); i += asterlen)
|
||||||
memcpy(&censort[i], asterisk, asterlen);
|
memcpy(&censort[i], asterisk, asterlen);
|
||||||
}
|
|
||||||
|
|
||||||
censort[i+1] = '\n';
|
censort[i+1] = '\n';
|
||||||
leftinput = mw - x - pbw;
|
leftinput = mw - x - pbw;
|
||||||
drw_text(drw, x, 0, leftinput, bh, lrpad / 2, censort, 0);
|
drw_text(drw, x, 0, leftinput, bh, lrpad / 2, censort, 0);
|
||||||
drw_font_getexts(drw->fonts, censort, cursor * asterlen, &curpos, NULL);
|
curpos = TEXTW(censort) - TEXTW(&censort[cursor]);
|
||||||
|
|
||||||
if ((curpos += lrpad / 2 - 1) < leftinput) {
|
if ((curpos += lrpad / 2 - 1) < leftinput) {
|
||||||
drw_setscheme(drw, scheme[SchemeNormal]);
|
drw_setscheme(drw, scheme[SchemeNormal]);
|
||||||
drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
|
drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(censort);
|
free(censort);
|
||||||
|
@ -264,29 +252,27 @@ drawwin(void) {
|
||||||
x = drawitem("No", (sel == No), x, 0, TEXTW("No"));
|
x = drawitem("No", (sel == No), x, 0, TEXTW("No"));
|
||||||
x = drawitem("Yes", (sel == Yes), x, 0, TEXTW("Yes"));
|
x = drawitem("Yes", (sel == Yes), x, 0, TEXTW("Yes"));
|
||||||
}
|
}
|
||||||
|
|
||||||
drw_map(drw, win, 0, 0, mw, mh);
|
drw_map(drw, win, 0, 0, mw, mh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup(void) {
|
setup(void)
|
||||||
int x, y, i = 0;
|
{
|
||||||
|
int x, y, i, j;
|
||||||
unsigned int du;
|
unsigned int du;
|
||||||
XSetWindowAttributes swa;
|
XSetWindowAttributes swa;
|
||||||
XIM xim;
|
XIM xim;
|
||||||
Window w, dw, *dws;
|
Window w, dw, *dws;
|
||||||
XWindowAttributes wa;
|
XWindowAttributes wa;
|
||||||
|
XClassHint ch = {"pinentry-dmenu", "pinentry-dmenu"};
|
||||||
#ifdef XINERAMA
|
#ifdef XINERAMA
|
||||||
XineramaScreenInfo *info;
|
XineramaScreenInfo *info;
|
||||||
Window pw;
|
Window pw;
|
||||||
int a, j, di, n, area = 0;
|
int a, di, n, area = 0;
|
||||||
#endif
|
#endif
|
||||||
|
/* init appearance */
|
||||||
/* Init appearance */
|
for (j = 0; j < SchemeLast; j++)
|
||||||
scheme[SchemePrompt] = drw_scm_create(drw, colors[SchemePrompt], 2);
|
scheme[j] = drw_scm_create(drw, colors[j], 2);
|
||||||
scheme[SchemeNormal] = drw_scm_create(drw, colors[SchemeNormal], 2);
|
|
||||||
scheme[SchemeSelect] = drw_scm_create(drw, colors[SchemeSelect], 2);
|
|
||||||
scheme[SchemeDesc] = drw_scm_create(drw, colors[SchemeDesc], 2);
|
|
||||||
|
|
||||||
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
||||||
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
|
@ -295,52 +281,43 @@ setup(void) {
|
||||||
bh = drw->fonts->h + 2;
|
bh = drw->fonts->h + 2;
|
||||||
mh = bh;
|
mh = bh;
|
||||||
#ifdef XINERAMA
|
#ifdef XINERAMA
|
||||||
info = XineramaQueryScreens(dpy, &n);
|
i = 0;
|
||||||
|
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
|
||||||
if (parentwin == root && info) {
|
|
||||||
XGetInputFocus(dpy, &w, &di);
|
XGetInputFocus(dpy, &w, &di);
|
||||||
if (mon >= 0 && mon < n) {
|
if (mon >= 0 && mon < n)
|
||||||
i = mon;
|
i = mon;
|
||||||
} else if (w != root && w != PointerRoot && w != None) {
|
else if (w != root && w != PointerRoot && w != None) {
|
||||||
/* Find top-level window containing current input focus */
|
/* find top-level window containing current input focus */
|
||||||
do {
|
do {
|
||||||
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) {
|
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
|
||||||
XFree(dws);
|
XFree(dws);
|
||||||
}
|
|
||||||
} while (w != root && w != pw);
|
} while (w != root && w != pw);
|
||||||
/* Find xinerama screen with which the window intersects most */
|
/* find xinerama screen with which the window intersects most */
|
||||||
if (XGetWindowAttributes(dpy, pw, &wa)) {
|
if (XGetWindowAttributes(dpy, pw, &wa))
|
||||||
for (j = 0; j < n; j++) {
|
for (j = 0; j < n; j++)
|
||||||
a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j]);
|
if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
|
||||||
if (a > area) {
|
|
||||||
area = a;
|
area = a;
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
/* no focused window is on screen, so use pointer location instead */
|
||||||
}
|
if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
|
||||||
/* No focused window is on screen, so use pointer location instead */
|
for (i = 0; i < n; i++)
|
||||||
if (mon < 0 && !area
|
if (INTERSECT(x, y, 1, 1, info[i]) != 0)
|
||||||
&& XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) {
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
if (INTERSECT(x, y, 1, 1, info[i])) {
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x = info[i].x_org;
|
x = info[i].x_org;
|
||||||
y = info[i].y_org + (bottom ? info[i].height - mh : 0);
|
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
|
||||||
mw = info[i].width;
|
mw = info[i].width;
|
||||||
XFree(info);
|
XFree(info);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!XGetWindowAttributes(dpy, parentwin, &wa)) {
|
if (!XGetWindowAttributes(dpy, parentwin, &wa))
|
||||||
die("could not get embedding window attributes: 0x%lx", parentwin);
|
die("could not get embedding window attributes: 0x%lx",
|
||||||
}
|
parentwin);
|
||||||
x = 0;
|
x = 0;
|
||||||
y = bottom ? wa.height - mh : 0;
|
y = topbar ? 0 : wa.height - mh;
|
||||||
mw = wa.width;
|
mw = wa.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,43 +330,44 @@ setup(void) {
|
||||||
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
|
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
|
||||||
CopyFromParent, CopyFromParent, CopyFromParent,
|
CopyFromParent, CopyFromParent, CopyFromParent,
|
||||||
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
|
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
|
||||||
|
XSetClassHint(dpy, win, &ch);
|
||||||
|
|
||||||
|
/* input methods */
|
||||||
|
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
|
||||||
|
die("XOpenIM failed: could not open input device");
|
||||||
|
|
||||||
/* Open input methods */
|
|
||||||
xim = XOpenIM(dpy, NULL, NULL, NULL);
|
|
||||||
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
||||||
XNClientWindow, win, XNFocusWindow, win, NULL);
|
XNClientWindow, win, XNFocusWindow, win, NULL);
|
||||||
XMapRaised(dpy, win);
|
XMapRaised(dpy, win);
|
||||||
|
if (embed) {
|
||||||
if (embedded) {
|
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
|
||||||
XSelectInput(dpy, parentwin, FocusChangeMask);
|
|
||||||
|
|
||||||
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
|
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
|
||||||
for (i = 0; i < du && dws[i] != win; ++i) {
|
for (i = 0; i < du && dws[i] != win; ++i)
|
||||||
XSelectInput(dpy, dws[i], FocusChangeMask);
|
XSelectInput(dpy, dws[i], FocusChangeMask);
|
||||||
}
|
|
||||||
|
|
||||||
XFree(dws);
|
XFree(dws);
|
||||||
}
|
}
|
||||||
grabfocus();
|
grabfocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
drw_resize(drw, mw, mh);
|
drw_resize(drw, mw, mh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cleanup(void) {
|
cleanup(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
||||||
free(scheme[SchemeDesc]);
|
for (i = 0; i < SchemeLast; i++)
|
||||||
free(scheme[SchemeSelect]);
|
free(scheme[i]);
|
||||||
free(scheme[SchemeNormal]);
|
|
||||||
free(scheme[SchemePrompt]);
|
|
||||||
drw_free(drw);
|
drw_free(drw);
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
XCloseDisplay(dpy);
|
XCloseDisplay(dpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keypress_confirm(XKeyEvent *ev, KeySym ksym) {
|
keypress_confirm(XKeyEvent *ev, KeySym ksym)
|
||||||
|
{
|
||||||
if (ev->state & ControlMask) {
|
if (ev->state & ControlMask) {
|
||||||
switch(ksym) {
|
switch(ksym) {
|
||||||
case XK_c:
|
case XK_c:
|
||||||
|
@ -404,9 +382,8 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) {
|
||||||
switch(ksym) {
|
switch(ksym) {
|
||||||
case XK_KP_Enter:
|
case XK_KP_Enter:
|
||||||
case XK_Return:
|
case XK_Return:
|
||||||
if (sel != Nothing) {
|
if (sel != Nothing)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case XK_y:
|
case XK_y:
|
||||||
case XK_Y:
|
case XK_Y:
|
||||||
|
@ -425,17 +402,23 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) {
|
||||||
case XK_h:
|
case XK_h:
|
||||||
case XK_j:
|
case XK_j:
|
||||||
case XK_Home:
|
case XK_Home:
|
||||||
|
case XK_KP_Home:
|
||||||
case XK_Left:
|
case XK_Left:
|
||||||
|
case XK_KP_Left:
|
||||||
case XK_Prior:
|
case XK_Prior:
|
||||||
|
case XK_KP_Prior:
|
||||||
case XK_Up:
|
case XK_Up:
|
||||||
|
case XK_KP_Up:
|
||||||
sel = No;
|
sel = No;
|
||||||
break;
|
break;
|
||||||
case XK_k:
|
case XK_k:
|
||||||
case XK_l:
|
case XK_l:
|
||||||
case XK_Down:
|
case XK_Down:
|
||||||
|
case XK_KP_Down:
|
||||||
case XK_End:
|
case XK_End:
|
||||||
case XK_Next:
|
case XK_Next:
|
||||||
case XK_Right:
|
case XK_Right:
|
||||||
|
case XK_KP_Right:
|
||||||
sel = Yes;
|
sel = Yes;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +427,8 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) {
|
keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len)
|
||||||
|
{
|
||||||
int old;
|
int old;
|
||||||
|
|
||||||
if (ev->state & ControlMask) {
|
if (ev->state & ControlMask) {
|
||||||
|
@ -482,34 +466,35 @@ keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) {
|
||||||
|
|
||||||
switch(ksym) {
|
switch(ksym) {
|
||||||
case XK_Delete:
|
case XK_Delete:
|
||||||
if (pin[cursor] == '\0') {
|
case XK_KP_Delete:
|
||||||
|
if (pin[cursor] == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
}
|
cursor = nextrune(+1);
|
||||||
cursor = nextrune(cursor, +1);
|
|
||||||
/* Fallthrough */
|
/* Fallthrough */
|
||||||
case XK_BackSpace:
|
case XK_BackSpace:
|
||||||
if (cursor == 0) {
|
if (cursor == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
insert(NULL, nextrune(-1) - cursor);
|
||||||
insert(NULL, nextrune(cursor, -1) - cursor);
|
|
||||||
break;
|
break;
|
||||||
case XK_Escape:
|
case XK_Escape:
|
||||||
pinentry_info->canceled = 1;
|
pinentry_info->canceled = 1;
|
||||||
return 1;
|
return 1;
|
||||||
case XK_Left:
|
case XK_Left:
|
||||||
if (cursor > 0) {
|
case XK_KP_Left:
|
||||||
cursor = nextrune(cursor, -1);
|
if (cursor > 0)
|
||||||
}
|
cursor = nextrune(-1);
|
||||||
break;
|
break;
|
||||||
case XK_Right:
|
case XK_Right:
|
||||||
if (pin[cursor] != '\0') {
|
case XK_KP_Right:
|
||||||
cursor = nextrune(cursor, +1);
|
if (pin[cursor] != '\0')
|
||||||
}
|
cursor = nextrune(+1);
|
||||||
break;
|
break;
|
||||||
case XK_Home:
|
case XK_Home:
|
||||||
|
case XK_KP_Home:
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
break;
|
break;
|
||||||
case XK_End:
|
case XK_End:
|
||||||
|
case XK_KP_End:
|
||||||
cursor = strlen(pin);
|
cursor = strlen(pin);
|
||||||
break;
|
break;
|
||||||
case XK_Return:
|
case XK_Return:
|
||||||
|
@ -517,16 +502,16 @@ keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) {
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!iscntrl(*buf)) {
|
if (!iscntrl((unsigned char)*buf))
|
||||||
insert(buf, len);
|
insert(buf, len);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keypress(XKeyEvent *ev) {
|
keypress(XKeyEvent *ev)
|
||||||
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
int len;
|
int len;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
@ -536,79 +521,83 @@ keypress(XKeyEvent *ev) {
|
||||||
len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status);
|
len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status);
|
||||||
|
|
||||||
if (status != XBufferOverflow) {
|
if (status != XBufferOverflow) {
|
||||||
if (winmode == WinConfirm) {
|
if (winmode == WinConfirm)
|
||||||
ret = keypress_confirm(ev, ksym);
|
ret = keypress_confirm(ev, ksym);
|
||||||
} else {
|
else
|
||||||
ret = keypress_pin(ev, ksym, buf, len);
|
ret = keypress_pin(ev, ksym, buf, len);
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0)
|
||||||
drawwin();
|
drawmenu();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
paste(void) {
|
paste(void)
|
||||||
|
{
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int di;
|
int di;
|
||||||
unsigned long dl;
|
unsigned long dl;
|
||||||
Atom da;
|
Atom da;
|
||||||
|
|
||||||
/* We have been given the current selection, now insert it into input */
|
/* we have been given the current selection, now insert it into input */
|
||||||
XGetWindowProperty(dpy, win, utf8, 0, pin_len / 4, False, utf8, &da, &di,
|
if (XGetWindowProperty(dpy, win, utf8, 0, (pin_len/ 4) + 1, False,
|
||||||
&dl, &dl, (unsigned char **)&p);
|
utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
|
||||||
|
== Success && p) {
|
||||||
insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
|
insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
|
||||||
XFree(p);
|
XFree(p);
|
||||||
drawwin();
|
}
|
||||||
|
drawmenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run(void) {
|
run(void)
|
||||||
|
{
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
|
|
||||||
drawwin();
|
drawmenu();
|
||||||
|
|
||||||
while (!XNextEvent(dpy, &ev)) {
|
while (!XNextEvent(dpy, &ev)) {
|
||||||
if (XFilterEvent(&ev, win)) {
|
if (XFilterEvent(&ev, win))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
switch(ev.type) {
|
switch(ev.type) {
|
||||||
|
case DestroyNotify:
|
||||||
|
if (ev.xdestroywindow.window != win)
|
||||||
|
break;
|
||||||
|
cleanup();
|
||||||
|
exit(1);
|
||||||
case Expose:
|
case Expose:
|
||||||
if (ev.xexpose.count == 0) {
|
if (ev.xexpose.count == 0)
|
||||||
drw_map(drw, win, 0, 0, mw, mh);
|
drw_map(drw, win, 0, 0, mw, mh);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
if (keypress(&ev.xkey)) {
|
if (keypress(&ev.xkey))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
if (ev.xselection.property == utf8) {
|
if (ev.xselection.property == utf8)
|
||||||
paste();
|
paste();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case VisibilityNotify:
|
case VisibilityNotify:
|
||||||
if (ev.xvisibility.state != VisibilityUnobscured) {
|
if (ev.xvisibility.state != VisibilityUnobscured)
|
||||||
XRaiseWindow(dpy, win);
|
XRaiseWindow(dpy, win);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: this does nothing */
|
||||||
static void
|
static void
|
||||||
catchsig(int sig) {
|
catchsig(int sig)
|
||||||
if (sig == SIGALRM) {
|
{
|
||||||
|
if (sig == SIGALRM)
|
||||||
timed_out = 1;
|
timed_out = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
password(void) {
|
password(void)
|
||||||
|
{
|
||||||
winmode = WinPin;
|
winmode = WinPin;
|
||||||
repeat = 0;
|
repeat = 0;
|
||||||
setup_pin(pinentry_info->pin, pinentry_info->pin_len, 1);
|
setup_pin(pinentry_info->pin, pinentry_info->pin_len, 1);
|
||||||
|
@ -639,7 +628,8 @@ password(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
confirm(void) {
|
confirm(void)
|
||||||
|
{
|
||||||
winmode = WinConfirm;
|
winmode = WinConfirm;
|
||||||
sel = Nothing;
|
sel = Nothing;
|
||||||
run();
|
run();
|
||||||
|
@ -647,30 +637,33 @@ confirm(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmdhandler(pinentry_t received_pinentry) {
|
cmdhandler(pinentry_t received_pinentry)
|
||||||
|
{
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
XWindowAttributes wa;
|
XWindowAttributes wa;
|
||||||
|
|
||||||
pinentry_info = received_pinentry;
|
pinentry_info = received_pinentry;
|
||||||
|
|
||||||
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) {
|
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
|
||||||
fputs("warning: no locale support\n", stderr);
|
fputs("warning: no locale support\n", stderr);
|
||||||
}
|
if (!(dpy = XOpenDisplay(pinentry_info->display)))
|
||||||
if (!(dpy = XOpenDisplay(pinentry_info->display))) {
|
|
||||||
die("cannot open display");
|
die("cannot open display");
|
||||||
}
|
|
||||||
screen = DefaultScreen(dpy);
|
screen = DefaultScreen(dpy);
|
||||||
root = RootWindow(dpy, screen);
|
root = RootWindow(dpy, screen);
|
||||||
embedded = (pinentry_info->parent_wid) ? embedded : 0;
|
embed = (pinentry_info->parent_wid) ? embed : 0;
|
||||||
parentwin = (embedded) ? pinentry_info->parent_wid : root;
|
parentwin = (embed) ? pinentry_info->parent_wid : root;
|
||||||
if (!XGetWindowAttributes(dpy, parentwin, &wa)) {
|
if (!XGetWindowAttributes(dpy, parentwin, &wa))
|
||||||
die("could not get embedding window attributes: 0x%lx", parentwin);
|
die("could not get embedding window attributes: 0x%lx", parentwin);
|
||||||
}
|
|
||||||
drw = drw_create(dpy, screen, root, wa.width, wa.height);
|
drw = drw_create(dpy, screen, root, wa.width, wa.height);
|
||||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) {
|
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||||
die("no fonts could be loaded.");
|
die("no fonts could be loaded.");
|
||||||
}
|
|
||||||
lrpad = drw->fonts->h;
|
lrpad = drw->fonts->h;
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
if (pledge("stdio rpath", NULL) == -1)
|
||||||
|
die("pledge");
|
||||||
|
#endif
|
||||||
|
|
||||||
drw_setscheme(drw, scheme[SchemePrompt]);
|
drw_setscheme(drw, scheme[SchemePrompt]);
|
||||||
|
|
||||||
if (pinentry_info->timeout) {
|
if (pinentry_info->timeout) {
|
||||||
|
@ -683,14 +676,13 @@ cmdhandler(pinentry_t received_pinentry) {
|
||||||
grabkeyboard();
|
grabkeyboard();
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
if (pinentry_info->pin) {
|
if (pinentry_info->pin)
|
||||||
do {
|
do {
|
||||||
password();
|
password();
|
||||||
} while (!pinentry_info->canceled && pinentry_info->repeat_passphrase
|
} while (!pinentry_info->canceled && pinentry_info->repeat_passphrase
|
||||||
&& !pinentry_info->repeat_okay);
|
&& !pinentry_info->repeat_okay);
|
||||||
} else {
|
else
|
||||||
confirm();
|
confirm();
|
||||||
}
|
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
|
@ -700,100 +692,13 @@ cmdhandler(pinentry_t received_pinentry) {
|
||||||
pinentry_cmd_handler_t pinentry_cmd_handler = cmdhandler;
|
pinentry_cmd_handler_t pinentry_cmd_handler = cmdhandler;
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(int argc, char *argv[])
|
||||||
Bool bval;
|
{
|
||||||
int i, val;
|
|
||||||
const char *str;
|
|
||||||
struct passwd *pw;
|
|
||||||
char path[PATH_MAX];
|
|
||||||
char *sudo_uid = getenv("SUDO_UID");
|
|
||||||
char *home = getenv("HOME");
|
|
||||||
char *gnupghome = getenv("GNUPGHOME");
|
|
||||||
config_t cfg;
|
|
||||||
|
|
||||||
if (gnupghome) {
|
|
||||||
i = strlen(gnupghome);
|
|
||||||
strcpy(path, gnupghome);
|
|
||||||
} else {
|
|
||||||
/* Get the home dir even if the user used sudo or logged in as root */
|
|
||||||
if (sudo_uid) {
|
|
||||||
i = atoi(sudo_uid);
|
|
||||||
pw = getpwuid(i);
|
|
||||||
home = pw->pw_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = strlen(home);
|
|
||||||
strcpy(path, home);
|
|
||||||
strcpy(&path[i], CONFIG_DIR);
|
|
||||||
i += strlen(CONFIG_DIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(&path[i], CONFIG_FILE);
|
|
||||||
endpwent();
|
|
||||||
|
|
||||||
config_init(&cfg);
|
|
||||||
|
|
||||||
/* Read the file. If there is an error, report it and exit. */
|
|
||||||
if (config_read_file(&cfg, path)) {
|
|
||||||
if (config_lookup_string(&cfg, "asterisk", &str)) {
|
|
||||||
asterisk = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_bool(&cfg, "bottom", &bval)) {
|
|
||||||
bottom = bval;
|
|
||||||
}
|
|
||||||
if (config_lookup_int(&cfg, "min_password_length", &val)) {
|
|
||||||
minpwlen = val;
|
|
||||||
}
|
|
||||||
if (config_lookup_int(&cfg, "monitor", &val)) {
|
|
||||||
mon = val;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "prompt", &str)) {
|
|
||||||
prompt = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "font", &str)) {
|
|
||||||
fonts[0] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "prompt_bg", &str)) {
|
|
||||||
colors[SchemePrompt][ColBg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "prompt_fg", &str)) {
|
|
||||||
colors[SchemePrompt][ColFg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "normal_bg", &str)) {
|
|
||||||
colors[SchemeNormal][ColBg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "normal_fg", &str)) {
|
|
||||||
colors[SchemeNormal][ColFg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "select_bg", &str)) {
|
|
||||||
colors[SchemeSelect][ColBg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "select_fg", &str)) {
|
|
||||||
colors[SchemeSelect][ColFg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "desc_bg", &str)) {
|
|
||||||
colors[SchemeDesc][ColBg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_string(&cfg, "desc_fg", &str)) {
|
|
||||||
colors[SchemeDesc][ColFg] = str;
|
|
||||||
}
|
|
||||||
if (config_lookup_bool(&cfg, "embedded", &bval)) {
|
|
||||||
embedded = bval;
|
|
||||||
}
|
|
||||||
} else if ((str = config_error_file(&cfg))) {
|
|
||||||
fprintf(stderr, "%s:%d: %s\n", config_error_file(&cfg),
|
|
||||||
config_error_line(&cfg), config_error_text(&cfg));
|
|
||||||
return(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
pinentry_init("pinentry-dmenu");
|
pinentry_init("pinentry-dmenu");
|
||||||
pinentry_parse_opts(argc, argv);
|
pinentry_parse_opts(argc, argv);
|
||||||
|
|
||||||
if (pinentry_loop()) {
|
if (pinentry_loop())
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
config_destroy(&cfg);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
include ../config.mk
|
|
||||||
|
|
||||||
SRC = util.c pinentry.c argparse.c password-cache.c secmem.c
|
|
||||||
OBJ = ${SRC:.c=.o}
|
|
||||||
CFLAGS += -DHAVE_MLOCK
|
|
||||||
|
|
||||||
all: pinentry
|
|
||||||
|
|
||||||
.c.o:
|
|
||||||
@echo CC $<
|
|
||||||
@${CC} -c ${CFLAGS} $<
|
|
||||||
|
|
||||||
${OBJ}: pinentry.h argparse.h password-cache.h memory.h util.h
|
|
||||||
|
|
||||||
pinentry: pinentry.o argparse.o password-cache.o secmem.o util.o
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@echo cleaning
|
|
||||||
@rm -f ${OBJ}
|
|
||||||
|
|
||||||
.PHONY: all clean pinentry
|
|
|
@ -1,91 +0,0 @@
|
||||||
/* STL allocator for secmem
|
|
||||||
* Copyright (C) 2008 Marc Mutz <marc@kdab.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SECMEM_SECMEMPP_H__
|
|
||||||
#define __SECMEM_SECMEMPP_H__
|
|
||||||
|
|
||||||
#include "secmem/memory.h"
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace secmem {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class alloc {
|
|
||||||
public:
|
|
||||||
// type definitions:
|
|
||||||
typedef size_t size_type;
|
|
||||||
typedef ptrdiff_t difference_type;
|
|
||||||
typedef T* pointer;
|
|
||||||
typedef const T* const_pointer;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T value_type;
|
|
||||||
|
|
||||||
// rebind
|
|
||||||
template <typename U>
|
|
||||||
struct rebind {
|
|
||||||
typedef alloc<U> other;
|
|
||||||
};
|
|
||||||
|
|
||||||
// address
|
|
||||||
pointer address( reference value ) const {
|
|
||||||
return &value;
|
|
||||||
}
|
|
||||||
const_pointer address( const_reference value ) const {
|
|
||||||
return &value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (trivial) ctors and dtors
|
|
||||||
alloc() {}
|
|
||||||
alloc( const alloc & ) {}
|
|
||||||
template <typename U> alloc( const alloc<U> & ) {}
|
|
||||||
// copy ctor is ok
|
|
||||||
~alloc() {}
|
|
||||||
|
|
||||||
// de/allocation
|
|
||||||
size_type max_size() const {
|
|
||||||
return secmem_get_max_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer allocate( size_type n, void * =0 ) {
|
|
||||||
return static_cast<pointer>( secmem_malloc( n * sizeof(T) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocate( pointer p, size_type ) {
|
|
||||||
secmem_free( p );
|
|
||||||
}
|
|
||||||
|
|
||||||
// de/construct
|
|
||||||
void construct( pointer p, const T & value ) {
|
|
||||||
void * loc = p;
|
|
||||||
new (loc)T(value);
|
|
||||||
}
|
|
||||||
void destruct( pointer p ) {
|
|
||||||
p->~T();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// equality comparison
|
|
||||||
template <typename T1,typename T2>
|
|
||||||
bool operator==( const alloc<T1> &, const alloc<T2> & ) { return true; }
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
bool operator!=( const alloc<T1> &, const alloc<T2> & ) { return false; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __SECMEM_SECMEMPP_H__ */
|
|
6
test
6
test
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [[ $1 -eq 1 ]]; then
|
if [ $1 -eq 1 ]; then
|
||||||
|
|
||||||
echo "SETTITLE title
|
echo "SETTITLE title
|
||||||
SETPROMPT prompt
|
SETPROMPT prompt
|
||||||
|
@ -8,7 +8,7 @@ SETDESC PROMPT
|
||||||
GETPIN
|
GETPIN
|
||||||
BYE" | ./pinentry-dmenu
|
BYE" | ./pinentry-dmenu
|
||||||
|
|
||||||
elif [[ $1 -eq 2 ]]; then
|
elif [ $1 -eq 2 ]; then
|
||||||
|
|
||||||
echo "SETTITLE title
|
echo "SETTITLE title
|
||||||
SETPROMPT confirm
|
SETPROMPT confirm
|
||||||
|
@ -16,7 +16,7 @@ SETDESC CONFIRM
|
||||||
confirm
|
confirm
|
||||||
BYE" | ./pinentry-dmenu
|
BYE" | ./pinentry-dmenu
|
||||||
|
|
||||||
elif [[ $1 -eq 3 ]]; then
|
elif [ $1 -eq 3 ]; then
|
||||||
|
|
||||||
echo "SETTITLE title
|
echo "SETTITLE title
|
||||||
SETPROMPT prompt
|
SETPROMPT prompt
|
||||||
|
|
23
util.c
23
util.c
|
@ -6,18 +6,9 @@
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
void *
|
|
||||||
ecalloc(size_t nmemb, size_t size)
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
if (!(p = calloc(nmemb, size)))
|
|
||||||
die("calloc:");
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
die(const char *fmt, ...) {
|
die(const char *fmt, ...)
|
||||||
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
@ -33,3 +24,13 @@ die(const char *fmt, ...) {
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ecalloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (!(p = calloc(nmemb, size)))
|
||||||
|
die("calloc:");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
1
util.h
1
util.h
|
@ -3,6 +3,7 @@
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
||||||
|
#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
|
||||||
|
|
||||||
void die(const char *fmt, ...);
|
void die(const char *fmt, ...);
|
||||||
void *ecalloc(size_t nmemb, size_t size);
|
void *ecalloc(size_t nmemb, size_t size);
|
||||||
|
|
Reference in New Issue