Browse Source

Suckless Utilities

main
Yigit Colakoglu 4 years ago
parent
commit
91d61dd69d
43 changed files with 1848 additions and 1015 deletions
  1. +26
    -0
      .config/isync/mbsyncrc
  2. +23
    -0
      .config/msmtp/config
  3. +2
    -1
      .config/mutt/accounts/2-yigit@yigitcolakoglu.com.muttrc
  4. +44
    -44
      .config/weechat/irc.conf
  5. +4
    -4
      .config/weechat/sec.conf
  6. +7
    -6
      .local/src/dmenu/colors.h
  7. +1
    -0
      .local/src/dmenu/config.h
  8. +2
    -1
      .local/src/dmenu/dmenu.c
  9. +2
    -4
      .local/src/dwm/config.def.h
  10. +2
    -4
      .local/src/dwm/config.h
  11. +14
    -16
      .local/src/dwm/dwm.c
  12. +60
    -0
      .local/src/sent/.gitignore
  13. +29
    -0
      .local/src/sent/LICENSE
  14. +60
    -0
      .local/src/sent/Makefile
  15. +59
    -0
      .local/src/sent/README.md
  16. +49
    -0
      .local/src/sent/arg.h
  17. +56
    -0
      .local/src/sent/config.def.h
  18. +56
    -0
      .local/src/sent/config.h
  19. +30
    -0
      .local/src/sent/config.mk
  20. +421
    -0
      .local/src/sent/drw.c
  21. +57
    -0
      .local/src/sent/drw.h
  22. BIN
      .local/src/sent/sent
  23. +68
    -0
      .local/src/sent/sent.1
  24. +710
    -0
      .local/src/sent/sent.c
  25. BIN
      .local/src/sent/transparent_test.ff
  26. +35
    -0
      .local/src/sent/util.c
  27. +8
    -0
      .local/src/sent/util.h
  28. +1
    -1
      .local/src/st/config.h
  29. BIN
      .local/src/st/st
  30. +21
    -4
      .local/src/st/st.c
  31. +1
    -1
      .local/src/st/st.c.orig
  32. BIN
      .local/src/st/st.o
  33. +0
    -138
      .local/src/surf/surf-0.6-navhist.diff
  34. +0
    -59
      .local/src/surf/surf-0.7-omnibar.diff
  35. +0
    -93
      .local/src/surf/surf-2.0-externalpipe.diff
  36. +0
    -24
      .local/src/surf/surf-2.0-homepage.diff
  37. +0
    -42
      .local/src/surf/surf-bookmarks-20170722-723ff26.diff
  38. +0
    -67
      .local/src/surf/surf-clipboard-20200112-a6a8878.diff
  39. +0
    -107
      .local/src/surf/surf-history-20181009-2b71a22.diff
  40. +0
    -134
      .local/src/surf/surf-modal-20190209-d068a38.diff
  41. +0
    -101
      .local/src/surf/surf-multijs-20190325-d068a38.diff
  42. +0
    -26
      .local/src/surf/surf-spacesearch-20170408-b814567.diff
  43. +0
    -138
      .local/src/surf/surf-tip-navhist.diff

+ 26
- 0
.config/isync/mbsyncrc View File

@ -24,3 +24,29 @@ MaxMessages 0
ExpireUnread no
# End profile
IMAPStore yigit@yigitcolakoglu.com-remote
Host mail.privateemail.com
Port 993
User yigit@yigitcolakoglu.com
PassCmd "pass Email/privateemail.com/yigit@yigitcolakoglu.com"
AuthMechs LOGIN
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
MaildirStore yigit@yigitcolakoglu.com-local
Subfolders Verbatim
Path /home/yigit/.local/share/mail/yigit@yigitcolakoglu.com/
Inbox /home/yigit/.local/share/mail/yigit@yigitcolakoglu.com/INBOX
Channel yigit@yigitcolakoglu.com
Expunge Both
Far :yigit@yigitcolakoglu.com-remote:
Near :yigit@yigitcolakoglu.com-local:
Patterns * !"[Gmail]/All Mail"
Create Both
SyncState *
MaxMessages 0
ExpireUnread no
# End profile

+ 23
- 0
.config/msmtp/config View File

@ -9,3 +9,26 @@ tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /home/yigit/.config/msmtp/msmtp.log
account yigit@yigitcolakoglu.com
host mail.privateemail.com
port 587
from yigit@yigitcolakoglu.com
user yigit@yigitcolakoglu.com
passwordeval "pass Email/privateemail.com/yigit@yigitcolakoglu.com"
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /home/yigit/.config/msmtp/msmtp.log
# default for git email-send
account default
host mail.privateemail.com
port 587
from yigit@yigitcolakoglu.com
user yigit@yigitcolakoglu.com
passwordeval "pass Email/privateemail.com/yigit@yigitcolakoglu.com"
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /home/yigit/.config/msmtp/msmtp.log

+ 2
- 1
.config/mutt/accounts/2-yigit@yigitcolakoglu.com.muttrc View File

@ -8,6 +8,7 @@ set folder = "/home/yigit/.local/share/mail/yigit@yigitcolakoglu.com"
set header_cache = /home/yigit/.cache/mutt-wizard/yigit@yigitcolakoglu.com/headers
set message_cachedir = /home/yigit/.cache/mutt-wizard/yigit@yigitcolakoglu.com/bodies
set mbox_type = Maildir
set signature = "/home/yigit/.config/mutt/accounts/2-yigit@yigitcolakoglu.com.sig"
bind index,pager gg noop
@ -35,7 +36,7 @@ macro index,pager Cs ";<copy-message>=Sent<enter>" "copy mail to sent"
macro index,pager gt "<change-folder>=Trash/Mailspring/Snoozed<enter>" "go to trash"
macro index,pager Mt ";<save-message>=Trash/Mailspring/Snoozed<enter>" "move mail to trash"
macro index,pager Ct ";<copy-message>=Trash/Mailspring/Snoozed<enter>" "copy mail to trash"
set trash = "+Trash/Mailspring/Snoozed"
set trash = "+Trash"
set postponed = "+Drafts"
macro index,pager gd "<change-folder>=Drafts<enter>" "go to drafts"
macro index,pager Md ";<save-message>=Drafts<enter>" "move mail to drafts"


+ 44
- 44
.config/weechat/irc.conf View File

@ -203,50 +203,6 @@ freenode.notify
freenode.split_msg_max_length
freenode.charset_message
freenode.default_chantypes
oftc.addresses = "irc.oftc.net/6697"
oftc.proxy
oftc.ipv6
oftc.ssl = on
oftc.ssl_cert
oftc.ssl_password
oftc.ssl_priorities
oftc.ssl_dhkey_size
oftc.ssl_fingerprint
oftc.ssl_verify
oftc.password
oftc.capabilities
oftc.sasl_mechanism = plain
oftc.sasl_username = "Fr1nge"
oftc.sasl_password = "${sec.data.oftc_password}"
oftc.sasl_key
oftc.sasl_timeout
oftc.sasl_fail
oftc.autoconnect = on
oftc.autoreconnect
oftc.autoreconnect_delay
oftc.nicks = "Fr1nge,theFr1nge"
oftc.nicks_alternate
oftc.username = "Fr1nge"
oftc.realname = "Yigit Colakoglu"
oftc.local_hostname
oftc.usermode
oftc.command
oftc.command_delay
oftc.autojoin = "#suckless"
oftc.autorejoin
oftc.autorejoin_delay
oftc.connection_timeout
oftc.anti_flood_prio_high
oftc.anti_flood_prio_low
oftc.away_check
oftc.away_check_max_nicks
oftc.msg_kick
oftc.msg_part
oftc.msg_quit
oftc.notify
oftc.split_msg_max_length
oftc.charset_message
oftc.default_chantypes
rizon.addresses = "irc.rizon.net/6697"
rizon.proxy
rizon.ipv6
@ -291,3 +247,47 @@ rizon.notify
rizon.split_msg_max_length
rizon.charset_message
rizon.default_chantypes
oftc.addresses = "irc.oftc.net/6697"
oftc.proxy
oftc.ipv6
oftc.ssl = on
oftc.ssl_cert = "%h/certs/Fr1nge.pem"
oftc.ssl_password
oftc.ssl_priorities
oftc.ssl_dhkey_size
oftc.ssl_fingerprint
oftc.ssl_verify = on
oftc.password
oftc.capabilities
oftc.sasl_mechanism
oftc.sasl_username
oftc.sasl_password
oftc.sasl_key
oftc.sasl_timeout
oftc.sasl_fail
oftc.autoconnect = on
oftc.autoreconnect
oftc.autoreconnect_delay
oftc.nicks = "Fr1nge"
oftc.nicks_alternate
oftc.username
oftc.realname
oftc.local_hostname
oftc.usermode
oftc.command
oftc.command_delay
oftc.autojoin = "#suckless"
oftc.autorejoin
oftc.autorejoin_delay
oftc.connection_timeout
oftc.anti_flood_prio_high
oftc.anti_flood_prio_low
oftc.away_check
oftc.away_check_max_nicks
oftc.msg_kick
oftc.msg_part
oftc.msg_quit
oftc.notify
oftc.split_msg_max_length
oftc.charset_message
oftc.default_chantypes

+ 4
- 4
.config/weechat/sec.conf View File

@ -17,7 +17,7 @@ salt = on
[data]
__passphrase__ = on
oftc_password = "FFCB9AADF837EE7AE670326367FCDCBFBDF39D98C76E1302BE6DECE7F598B2CC8E8E577F058A2458AC35AD522E9B8D99E5C13A8CA38507"
sec.data.oftc_password = "AC02B320FCBEA984F00FE8FDE315B5CED3D529040022131F87CB33A1611EE4F21ED49F1290573437031444ABC70E6ABE0E4C7AEAB53564218B112C2243EACBA65CF4"
freenode = "EF3D92B85A003280767BE887892D3337B4331BED353F6CC641C2F818828A89C0EB71A394DD949C6DAFA7A362F55D24957CDC49454E631D4E5FD045"
rizon_password = "7B2C30B10D8FFDF2EF3E534E4E16A24B22552821133EF2D255B8096B951A51C02EEA146FF399EDABBF4D939F6D31972CEC286C58F5E088A10882CB3075EC66CE8CB0"
oftc_password = "70C3CF933D3572EC9EF6750DF5607BB04EAF8D6946DFF1A7C4BB030F6E6C17BCC3CC81CC74B0D9CD65CC23B2BE7640B5B8630BB07DE7A7"
sec.data.oftc_password = "B5CA63A28408814651F7E78A706B7E31F7E4C07B668A413670739685EE6512E0E94533B127BB0E8AF166B3BA840967DC8B6A4DE0ABC84FD223B646D8AF4F1D036375"
freenode = "42DBF5F6CE3313286C09FE4F3032B8D1E1287BBCCCE314A66C45D173B20E4B8AB59A746C4508AFA4C2D3C29B5E2114DA912D6CFF508B2E6BF60193"
rizon_password = "D070CB7362FD22623DD406217F2A46299287A8FCE804E73B19AE4DCF52EB47DF329B3FF4CB0297398A5E87E34F38DF951B74687F3419A778D5A9B924EBB748C36BFA"

+ 7
- 6
.local/src/dmenu/colors.h View File

@ -1,19 +1,20 @@
/* This file is used for color settings */
static const unsigned int border_width = 0; /* Fix border transparency */
static const char *colors[SchemeLast][2] = {
/* fg bg */
[SchemeNorm] = { "#e5e9f0", "#0f111a" },
[SchemeSel] = { "#0f111a", "#bf616a" },
[SchemeOut] = { "#000000", "#00ffff" },
[SchemeNormHighlight] = { "#81a1c1", "#0f111a" },
[SchemeSelHighlight] = { "#88c0d0", "#bf616a" },
[SchemeNorm] = { "#e5e9f0", "#0f111a", "#bf616a" },
[SchemeSel] = { "#0f111a", "#bf616a", "#bf616a" },
[SchemeOut] = { "#000000", "#00ffff", "#bf616a" },
[SchemeNormHighlight] = { "#81a1c1", "#0f111a", "#bf616a" },
[SchemeSelHighlight] = { "#88c0d0", "#bf616a", "#bf616a" },
};
static double opacity = 1.0; /* -o option; defines alpha translucency */
static const unsigned int baralpha = 0xFF;
static const unsigned int borderalpha = OPAQUE;
static const unsigned int borderalpha = 0xFF;
static const unsigned int alphas[][3] = {


+ 1
- 0
.local/src/dmenu/config.h View File

@ -7,6 +7,7 @@ static const char *fonts[] = {
"CaskaydiaCove Nerd Font Mono:size=10",
"Symbola:pixelsize=16:antialias=true:autohint=true",
};
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
static const unsigned int min_lineheight = 27;
static unsigned int lineheight = 27;


+ 2
- 1
.local/src/dmenu/dmenu.c View File

@ -929,9 +929,10 @@ setup(void)
swa.border_pixel = 0;
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
depth, InputOutput, visual,
CWOverrideRedirect | CWBackPixel | CWColormap | CWEventMask | CWBorderPixel, &swa);
XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
XSetClassHint(dpy, win, &ch);


+ 2
- 4
.local/src/dwm/config.def.h View File

@ -44,10 +44,8 @@ static const char *colors[][3] = {
};
/* tagging */
static const char *tags[][9] = {
[VacantTags] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"},
[BusyTags] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}
};
static const char *tags[9] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
static const char *busytags[9] = {"A", "B", "C", "D", "E", "F", "G", "H", "I"};
static const Rule rules[] = {
/* xprop(1):


+ 2
- 4
.local/src/dwm/config.h View File

@ -10,10 +10,8 @@ static const char *layoutmenu_cmd = "layoutmenu.sh";
unsigned const int swallowfloating = 0;
/* tagging */
static const char *tags[][9] = {
[VacantTags] = {"", "", "", "", "", "", "", "", ""},
[BusyTags] = {"", "", "", "", "", "", "", "", ""}
};
static const char *tags[9] = {"", "", "", "", "", "", "", "", ""};
static const char *busytags[9] = {"", "", "", "", "", "", "", "", ""};
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */


+ 14
- 16
.local/src/dwm/dwm.c View File

@ -61,10 +61,10 @@
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define NUMTAGS (LENGTH(tags[VacantTags]) + LENGTH(scratchpads))
#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads))
#define TAGMASK ((1 << NUMTAGS) - 1)
#define SPTAG(i) ((1 << LENGTH(tags[VacantTags])) << (i))
#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags[VacantTags]))
#define SPTAG(i) ((1 << LENGTH(tags)) << (i))
#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
/* enums */
@ -76,7 +76,6 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkClientWin,
ClkRootWin, ClkLast }; /* clicks */
enum { VacantTags, BusyTags }; /* Tag Types */
typedef union {
int i;
unsigned int ui;
@ -328,7 +327,7 @@ static xcb_connection_t *xcon;
#include "rules.h"
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags[VacantTags]) > 31 ? -1 : 1]; };
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
/* function implementations */
void
@ -572,13 +571,12 @@ buttonpress(XEvent *e)
for (c = m->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
do {
/* do not reserve space for vacant tags */
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
x += TEXTW(tags[VacantTags][i]);
x += TEXTW(tags[i]);
else
x += TEXTW(tags[BusyTags][i]);
} while (ev->x >= x && ++i < LENGTH(tags[VacantTags]));
if (i < LENGTH(tags[VacantTags])) {
x += TEXTW(busytags[i]);
} while (ev->x >= x && ++i < LENGTH(tags));
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
} else if (ev->x < x + blw)
@ -603,9 +601,9 @@ buttonpress(XEvent *e)
i = -1;
if (xc >= ev->x && dwmblockssig != -1) break;
dwmblockssig = ch;
}
}
}
}
}
} else if ((c = wintoclient(ev->window))) {
focus(c);
restack(selmon);
@ -1113,14 +1111,14 @@ drawbar(Monitor *m)
urg |= c->tags;
}
x = 0;
for (i = 0; i < LENGTH(tags[VacantTags]); i++) {
for (i = 0; i < LENGTH(tags); i++) {
/* do not draw vacant tags */
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]);
w = bh;
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[VacantTags][i], urg & 1 << i);
if (!(occ & 1 << i))
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
else
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[BusyTags][i], urg & 1 << i);
drw_text(drw, x, 0, w, bh, lrpad / 2, busytags[i], urg & 1 << i);
/** if (occ & 1 << i) */
/** drw_rect(drw, x + boxw, 0, w - ( 2 * boxw + 1), boxw, */


+ 60
- 0
.local/src/sent/.gitignore View File

@ -0,0 +1,60 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
dwm
dwm-msg
*.orig
*.rej
.ccls-cache

+ 29
- 0
.local/src/sent/LICENSE View File

@ -0,0 +1,29 @@
ISC-License
(c) 2014-2017 Markus Teich <markus.teich@stusta.mhn.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
(c) 2016,2017 Laslo Hunhold <dev@frign.de>
(c) 2016 ssd <ssd@mailless.org>
(c) 2016 Hiltjo Posthuma <hiltjo@codemadness.org>
(c) 2015 David Phillips <dbphillipsnz@gmail.com>
(c) 2015 Grant Mathews <grant.m.mathews@gmail.com>
(c) 2015 Dimitris Papastamos <sin@2f30.org>
(c) 2015 Alexis <surryhill@gmail.com>
(c) 2015 Quentin Rameau <quinq@fifth.space>
(c) 2015 Ivan Tham <pickfire@riseup.net>
(c) 2015 Jan Christoph Ebersbach <jceb@e-jc.de>
(c) 2015 Tony Lainson <t.lainson@gmail.com>
(c) 2015 Szabolcs Nagy <nsz@port70.net>
(c) 2015 Jonas Jelten <jj@sft.mx>

+ 60
- 0
.local/src/sent/Makefile View File

@ -0,0 +1,60 @@
# sent - plain text presentation tool
# See LICENSE file for copyright and license details.
include config.mk
SRC = sent.c drw.c util.c
OBJ = ${SRC:.c=.o}
all: options sent
options:
@echo sent build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
config.h:
cp config.def.h config.h
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk
sent: ${OBJ}
@echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
cscope: ${SRC} config.h
@echo cScope
@cscope -R -b || echo cScope not installed
clean:
@echo cleaning
@rm -f sent ${OBJ} sent-${VERSION}.tar.gz
dist: clean
@echo creating dist tarball
@mkdir -p sent-${VERSION}
@cp -R LICENSE Makefile config.mk config.def.h ${SRC} sent-${VERSION}
@tar -cf sent-${VERSION}.tar sent-${VERSION}
@gzip sent-${VERSION}.tar
@rm -rf sent-${VERSION}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f sent ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/sent
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
@cp sent.1 ${DESTDIR}${MANPREFIX}/man1/sent.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/sent.1
uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/sent
.PHONY: all options clean dist install uninstall cscope

+ 59
- 0
.local/src/sent/README.md View File

@ -0,0 +1,59 @@
sent is a simple plaintext presentation tool.
sent does not need latex, libreoffice or any other fancy file format, it uses
plaintext files to describe the slides and can include images via farbfeld.
Every paragraph represents a slide in the presentation.
The presentation is displayed in a simple X11 window. The content of each slide
is automatically scaled to fit the window and centered so you also don't have to
worry about alignment. Instead you can really concentrate on the content.
Dependencies
You need Xlib and Xft to build sent and the farbfeld[0] tools installed to use
images in your presentations.
Demo
To get a little demo, just type
make && ./sent example
You can navigate with the arrow keys and quit with `q`.
Usage
sent [FILE]
If FILE is omitted or equals `-`, stdin will be read. Produce image slides by
prepending a `@` in front of the filename as a single paragraph. Lines starting
with `#` will be ignored. A `\` at the beginning of the line escapes `@` and
`#`. A presentation file could look like this:
sent
@nyan.png
depends on
- Xlib
- Xft
- farbfeld
sent FILENAME
one slide per paragraph
# This is a comment and will not be part of the presentation
\# This and the next line start with backslashes
\@FILE.png
thanks / questions?
Development
sent is developed at http://tools.suckless.org/sent
0: http://tools.suckless.org/farbfeld/

+ 49
- 0
.local/src/sent/arg.h View File

@ -0,0 +1,49 @@
/*
* ISC-License
*
* Copyright 2017 Laslo Hunhold <dev@frign.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef ARG_H
#define ARG_H
extern char *argv0;
/* int main(int argc, char *argv[]) */
#define ARGBEGIN for (argv0 = *argv, *argv ? (argc--, argv++) : ((void *)0); \
*argv && (*argv)[0] == '-' && (*argv)[1]; argc--, argv++) { \
int i_, argused_; \
if ((*argv)[1] == '-' && !(*argv)[2]) { \
argc--, argv++; \
break; \
} \
for (i_ = 1, argused_ = 0; (*argv)[i_]; i_++) { \
switch((*argv)[i_])
#define ARGEND if (argused_) { \
if ((*argv)[i_ + 1]) { \
break; \
} else { \
argc--, argv++; \
break; \
} \
} \
} \
}
#define ARGC() ((*argv)[i_])
#define ARGF_(x) (((*argv)[i_ + 1]) ? (argused_ = 1, &((*argv)[i_ + 1])) : \
(*(argv + 1)) ? (argused_ = 1, *(argv + 1)) : (x))
#define EARGF(x) ARGF_(((x), exit(1), (char *)0))
#define ARGF() ARGF_((char *)0)
#endif

+ 56
- 0
.local/src/sent/config.def.h View File

@ -0,0 +1,56 @@
/* See LICENSE file for copyright and license details. */
static char *fontfallbacks[] = {
"dejavu sans",
"roboto",
"ubuntu",
};
#define NUMFONTSCALES 42
#define FONTSZ(x) ((int)(10.0 * powf(1.1288, (x)))) /* x in [0, NUMFONTSCALES-1] */
static const char *colors[] = {
"#000000", /* foreground color */
"#FFFFFF", /* background color */
};
static const float linespacing = 1.4;
/* how much screen estate is to be used at max for the content */
static const float usablewidth = 0.75;
static const float usableheight = 0.75;
static Mousekey mshortcuts[] = {
/* button function argument */
{ Button1, advance, {.i = +1} },
{ Button3, advance, {.i = -1} },
{ Button4, advance, {.i = -1} },
{ Button5, advance, {.i = +1} },
};
static Shortcut shortcuts[] = {
/* keysym function argument */
{ XK_Escape, quit, {0} },
{ XK_q, quit, {0} },
{ XK_Right, advance, {.i = +1} },
{ XK_Left, advance, {.i = -1} },
{ XK_Return, advance, {.i = +1} },
{ XK_space, advance, {.i = +1} },
{ XK_BackSpace, advance, {.i = -1} },
{ XK_l, advance, {.i = +1} },
{ XK_h, advance, {.i = -1} },
{ XK_j, advance, {.i = +1} },
{ XK_k, advance, {.i = -1} },
{ XK_Down, advance, {.i = +1} },
{ XK_Up, advance, {.i = -1} },
{ XK_Next, advance, {.i = +1} },
{ XK_Prior, advance, {.i = -1} },
{ XK_n, advance, {.i = +1} },
{ XK_p, advance, {.i = -1} },
{ XK_r, reload, {0} },
};
static Filter filters[] = {
{ "\\.ff$", "cat" },
{ "\\.ff.bz2$", "bunzip2" },
{ "\\.[a-z0-9]+$", "2ff" },
};

+ 56
- 0
.local/src/sent/config.h View File

@ -0,0 +1,56 @@
/* See LICENSE file for copyright and license details. */
static char *fontfallbacks[] = {
"dejavu sans",
"roboto",
"ubuntu",
};
#define NUMFONTSCALES 42
#define FONTSZ(x) ((int)(10.0 * powf(1.1288, (x)))) /* x in [0, NUMFONTSCALES-1] */
static const char *colors[] = {
"#FFFFFF", /* foreground color */
"#000000", /* background color */
};
static const float linespacing = 1.4;
/* how much screen estate is to be used at max for the content */
static const float usablewidth = 0.75;
static const float usableheight = 0.75;
static Mousekey mshortcuts[] = {
/* button function argument */
{ Button1, advance, {.i = +1} },
{ Button3, advance, {.i = -1} },
{ Button4, advance, {.i = -1} },
{ Button5, advance, {.i = +1} },
};
static Shortcut shortcuts[] = {
/* keysym function argument */
{ XK_Escape, quit, {0} },
{ XK_q, quit, {0} },
{ XK_Right, advance, {.i = +1} },
{ XK_Left, advance, {.i = -1} },
{ XK_Return, advance, {.i = +1} },
{ XK_space, advance, {.i = +1} },
{ XK_BackSpace, advance, {.i = -1} },
{ XK_l, advance, {.i = +1} },
{ XK_h, advance, {.i = -1} },
{ XK_j, advance, {.i = +1} },
{ XK_k, advance, {.i = -1} },
{ XK_Down, advance, {.i = +1} },
{ XK_Up, advance, {.i = -1} },
{ XK_Next, advance, {.i = +1} },
{ XK_Prior, advance, {.i = -1} },
{ XK_n, advance, {.i = +1} },
{ XK_p, advance, {.i = -1} },
{ XK_r, reload, {0} },
};
static Filter filters[] = {
{ "\\.ff$", "cat" },
{ "\\.ff.bz2$", "bunzip2" },
{ "\\.[a-z0-9]+$", "2ff" },
};

+ 30
- 0
.local/src/sent/config.mk View File

@ -0,0 +1,30 @@
# sent version
VERSION = 1
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# includes and libs
INCS = -I. -I/usr/include -I/usr/include/freetype2 -I${X11INC}
LIBS = -L/usr/lib -lc -lm -L${X11LIB} -lXft -lfontconfig -lX11
# OpenBSD (uncomment)
#INCS = -I. -I${X11INC} -I${X11INC}/freetype2
# FreeBSD (uncomment)
#INCS = -I. -I/usr/local/include -I/usr/local/include/freetype2 -I${X11INC}
#LIBS = -L/usr/local/lib -lc -lm -L${X11LIB} -lXft -lfontconfig -lX11
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_XOPEN_SOURCE=600
CFLAGS += -g -std=c99 -pedantic -Wall ${INCS} ${CPPFLAGS}
LDFLAGS += -g ${LIBS}
#CFLAGS += -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
#LDFLAGS += ${LIBS}
# compiler and linker
CC ?= cc

+ 421
- 0
.local/src/sent/drw.c View File

@ -0,0 +1,421 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
static long
utf8decodebyte(const char c, size_t *i)
{
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
return (unsigned char)c & ~utfmask[*i];
return 0;
}
static size_t
utf8validate(long *u, size_t i)
{
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
*u = UTF_INVALID;
for (i = 1; *u > utfmax[i]; ++i)
;
return i;
}
static size_t
utf8decode(const char *c, long *u, size_t clen)
{
size_t i, j, len, type;
long udecoded;
*u = UTF_INVALID;
if (!clen)
return 0;
udecoded = utf8decodebyte(c[0], &len);
if (!BETWEEN(len, 1, UTF_SIZ))
return 1;
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
if (type)
return j;
}
if (j < len)
return 0;
*u = udecoded;
utf8validate(u, len);
return len;
}
Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
drw->screen = screen;
drw->root = root;
drw->w = w;
drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
}
void
drw_resize(Drw *drw, unsigned int w, unsigned int h)
{
if (!drw)
return;
drw->w = w;
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
}
void
drw_free(Drw *drw)
{
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
free(drw);
}
/* This function is an implementation detail. Library users should use
* drw_fontset_create instead.
*/
static Fnt *
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
Fnt *font;
XftFont *xfont = NULL;
FcPattern *pattern = NULL;
if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield the
* same substitution results as using the pattern returned by
* FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
XftFontClose(drw->dpy, xfont);
return NULL;
}
} else if (fontpattern) {
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL;
}
} else {
die("no font specified.");
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
font->h = xfont->ascent + xfont->descent;
font->dpy = drw->dpy;
return font;
}
static void
xfont_free(Fnt *font)
{
if (!font)
return;
if (font->pattern)
FcPatternDestroy(font->pattern);
XftFontClose(font->dpy, font->xfont);
free(font);
}
Fnt*
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{
Fnt *cur, *ret = NULL;
size_t i;
if (!drw || !fonts)
return NULL;
for (i = 1; i <= fontcount; i++) {
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
}
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
if (drw)
drw->fonts = set;
}
void
drw_setscheme(Drw *drw, Clr *scm)
{
if (drw)
drw->scheme = scm;
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
if (!drw || !drw->scheme)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
}
int
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;
unsigned int ew;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
size_t i, len;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
FcCharSet *fccharset;
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
int charexists = 0;
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
return 0;
if (!render) {
w = ~w;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad;
w -= lpad;
}
usedfont = drw->fonts;
while (1) {
utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
} else {
nextfont = curfont;
}
break;
}
}
if (!charexists || nextfont)
break;
else
charexists = 0;
}
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) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
}
x += ew;
w -= ew;
}
}
if (!*text) {
break;
} else if (nextfont) {
charexists = 0;
usedfont = nextfont;
} else {
/* Regardless of whether or not a fallback font is found, the
* character must be drawn. */
charexists = 1;
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
/* Refer to the comment in xfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
}
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
FcCharSetDestroy(fccharset);
FcPatternDestroy(fcpattern);
if (match) {
usedfont = xfont_create(drw, NULL, match);
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
xfont_free(usedfont);
usedfont = drw->fonts;
}
}
}
}
if (d)
XftDrawDestroy(d);
return x + (render ? w : 0);
}
void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{
if (!drw)
return;
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False);
}
unsigned int
drw_fontset_getwidth(Drw *drw, const char *text)
{
if (!drw || !drw->fonts || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{
XGlyphInfo ext;
if (!font || !text)
return;
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
if (w)
*w = ext.xOff;
if (h)
*h = font->h;
}
Cur *
drw_cur_create(Drw *drw, int shape)
{
Cur *cur;
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
return NULL;
cur->cursor = XCreateFontCursor(drw->dpy, shape);
return cur;
}
void
drw_cur_free(Drw *drw, Cur *cursor)
{
if (!cursor)
return;
XFreeCursor(drw->dpy, cursor->cursor);
free(cursor);
}

+ 57
- 0
.local/src/sent/drw.h View File

@ -0,0 +1,57 @@
/* See LICENSE file for copyright and license details. */
typedef struct {
Cursor cursor;
} Cur;
typedef struct Fnt {
Display *dpy;
unsigned int h;
XftFont *xfont;
FcPattern *pattern;
struct Fnt *next;
} Fnt;
enum { ColFg, ColBg }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
unsigned int w, h;
Display *dpy;
int screen;
Window root;
Drawable drawable;
GC gc;
Clr *scheme;
Fnt *fonts;
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);
void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
/* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);

BIN
.local/src/sent/sent View File


+ 68
- 0
.local/src/sent/sent.1 View File

@ -0,0 +1,68 @@
.Dd 2016-08-12
.Dt SENT 1
.Sh NAME
.Nm sent
.Nd simple plaintext presentation tool
.Sh SYNOPSIS
.Nm
.Op Fl v
.Op Ar file
.Sh DESCRIPTION
.Nm
is a simple plain text presentation tool for X. sent does not need LaTeX,
LibreOffice or any other fancy file format. Instead, sent reads plain text
describing the slides. sent can also draw images.
.Pp
Every paragraph represents a slide in the presentation. Especially for
presentations using the Takahashi method this is very nice and allows
you to write the presentation for a quick lightning talk within a
few minutes.
.Sh OPTIONS
.Bl -tag -width Ds
.It Fl v
Print version information to stdout and exit.
.El
.Sh USAGE
.Bl -tag -width Ds
.It Em Mouse commands
.Bl -tag -width Ds
.It Sy Button1 | Button5
Go to next slide, if existent.
.It Sy Button3 | Button4
Go to previous slide, if existent.
.El
.It Em Keyboard commands
.Bl -tag -width Ds
.It Sy Escape | q
Quit.
.It Sy r
Reload the slides. Only works on file input.
.It Sy Right | Return | Space | l | j | Down | Next | n
Go to next slide, if existent.
.It Sy Left | Backspace | h | k | Up | Prior | p
Go to previous slide, if existent.
.El
.El
.Sh FORMAT
The presentation file is made up of at least one paragraph, with an
empty line separating two slides.
Each input line is interpreted literally, except from control characters
at the beginning of lines described as follows:
.Bl -tag -width Ds
.It Sy @
Create individual slide containing the image pointed to by the filename
following the
.Sy @ .
.It Sy #
Ignore this input line.
.It Sy \e
Create input line using the characters following the
.Sy \e
without interpreting them.
.El
.Sh CUSTOMIZATION
.Nm
can be customized by creating a custom config.h and (re)compiling the
source code. This keeps it fast, secure and simple.
.Sh SEE ALSO
.Xr 2ff 1

+ 710
- 0
.local/src/sent/sent.c View File

@ -0,0 +1,710 @@
/* See LICENSE file for copyright and license details. */
#include <sys/types.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xft/Xft.h>
#include "arg.h"
#include "util.h"
#include "drw.h"
char *argv0;
/* macros */
#define LEN(a) (sizeof(a) / sizeof(a)[0])
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
#define MAXFONTSTRLEN 128
typedef enum {
NONE = 0,
SCALED = 1,
} imgstate;
typedef struct {
unsigned char *buf;
unsigned int bufwidth, bufheight;
imgstate state;
XImage *ximg;
int numpasses;
} Image;
typedef struct {
char *regex;
char *bin;
} Filter;
typedef struct {
unsigned int linecount;
char **lines;
Image *img;
char *embed;
} Slide;
/* Purely graphic info */
typedef struct {
Display *dpy;
Window win;
Atom wmdeletewin, netwmname;
Visual *vis;
XSetWindowAttributes attrs;
int scr;
int w, h;
int uw, uh; /* usable dimensions for drawing text and images */
} XWindow;
typedef union {
int i;
unsigned int ui;
float f;
const void *v;
} Arg;
typedef struct {
unsigned int b;
void (*func)(const Arg *);
const Arg arg;
} Mousekey;
typedef struct {
KeySym keysym;
void (*func)(const Arg *);
const Arg arg;
} Shortcut;
static void fffree(Image *img);
static void ffload(Slide *s);
static void ffprepare(Image *img);
static void ffscale(Image *img);
static void ffdraw(Image *img);
static void getfontsize(Slide *s, unsigned int *width, unsigned int *height);
static void cleanup(int slidesonly);
static void reload(const Arg *arg);
static void load(FILE *fp);
static void advance(const Arg *arg);
static void quit(const Arg *arg);
static void resize(int width, int height);
static void run();
static void usage();
static void xdraw();
static void xhints();
static void xinit();
static void xloadfonts();
static void bpress(XEvent *);
static void cmessage(XEvent *);
static void expose(XEvent *);
static void kpress(XEvent *);
static void configure(XEvent *);
/* config.h for applying patches and the configuration. */
#include "config.h"
/* Globals */
static const char *fname = NULL;
static Slide *slides = NULL;
static int idx = 0;
static int slidecount = 0;
static XWindow xw;
static Drw *d = NULL;
static Clr *sc;
static Fnt *fonts[NUMFONTSCALES];
static int running = 1;
static void (*handler[LASTEvent])(XEvent *) = {
[ButtonPress] = bpress,
[ClientMessage] = cmessage,
[ConfigureNotify] = configure,
[Expose] = expose,
[KeyPress] = kpress,
};
int
filter(int fd, const char *cmd)
{
int fds[2];
if (pipe(fds) < 0)
die("sent: Unable to create pipe:");
switch (fork()) {
case -1:
die("sent: Unable to fork:");
case 0:
dup2(fd, 0);
dup2(fds[1], 1);
close(fds[0]);
close(fds[1]);
execlp("sh", "sh", "-c", cmd, (char *)0);
fprintf(stderr, "sent: execlp sh -c '%s': %s\n", cmd, strerror(errno));
_exit(1);
}
close(fds[1]);
return fds[0];
}
void
fffree(Image *img)
{
free(img->buf);
if (img->ximg)
XDestroyImage(img->ximg);
free(img);
}
void
ffload(Slide *s)
{
uint32_t y, x;
uint16_t *row;
uint8_t opac, fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
size_t rowlen, off, nbytes, i;
ssize_t count;
unsigned char hdr[16];
char *bin = NULL;
char *filename;
regex_t regex;
int fdin, fdout;
if (s->img || !(filename = s->embed) || !s->embed[0])
return; /* already done */
for (i = 0; i < LEN(filters); i++) {
if (regcomp(&regex, filters[i].regex,
REG_NOSUB | REG_EXTENDED | REG_ICASE)) {
fprintf(stderr, "sent: Invalid regex '%s'\n", filters[i].regex);
continue;
}
if (!regexec(&regex, filename, 0, NULL, 0)) {
bin = filters[i].bin;
regfree(&regex);
break;
}
regfree(&regex);
}
if (!bin)
die("sent: Unable to find matching filter for '%s'", filename);
if ((fdin = open(filename, O_RDONLY)) < 0)
die("sent: Unable to open '%s':", filename);
if ((fdout = filter(fdin, bin)) < 0)
die("sent: Unable to filter '%s':", filename);
close(fdin);
if (read(fdout, hdr, 16) != 16)
die("sent: Unable to read filtered file '%s':", filename);
if (memcmp("farbfeld", hdr, 8))
die("sent: Filtered file '%s' has no valid farbfeld header", filename);
s->img = ecalloc(1, sizeof(Image));
s->img->bufwidth = ntohl(*(uint32_t *)&hdr[8]);
s->img->bufheight = ntohl(*(uint32_t *)&hdr[12]);
if (s->img->buf)
free(s->img->buf);
/* internally the image is stored in 888 format */
s->img->buf = ecalloc(s->img->bufwidth * s->img->bufheight, strlen("888"));
/* scratch buffer to read row by row */
rowlen = s->img->bufwidth * 2 * strlen("RGBA");
row = ecalloc(1, rowlen);
/* extract window background color channels for transparency */
bg_r = (sc[ColBg].pixel >> 16) % 256;
bg_g = (sc[ColBg].pixel >> 8) % 256;
bg_b = (sc[ColBg].pixel >> 0) % 256;
for (off = 0, y = 0; y < s->img->bufheight; y++) {
nbytes = 0;
while (nbytes < rowlen) {
count = read(fdout, (char *)row + nbytes, rowlen - nbytes);
if (count < 0)
die("sent: Unable to read from pipe:");
nbytes += count;
}
for (x = 0; x < rowlen / 2; x += 4) {
fg_r = ntohs(row[x + 0]) / 257;
fg_g = ntohs(row[x + 1]) / 257;
fg_b = ntohs(row[x + 2]) / 257;
opac = ntohs(row[x + 3]) / 257;
/* blend opaque part of image data with window background color to
* emulate transparency */
s->img->buf[off++] = (fg_r * opac + bg_r * (255 - opac)) / 255;
s->img->buf[off++] = (fg_g * opac + bg_g * (255 - opac)) / 255;
s->img->buf[off++] = (fg_b * opac + bg_b * (255 - opac)) / 255;
}
}
free(row);
close(fdout);
}
void
ffprepare(Image *img)
{
int depth = DefaultDepth(xw.dpy, xw.scr);
int width = xw.uw;
int height = xw.uh;
if (xw.uw * img->bufheight > xw.uh * img->bufwidth)
width = img->bufwidth * xw.uh / img->bufheight;
else
height = img->bufheight * xw.uw / img->bufwidth;
if (depth < 24)
die("sent: Display color depths < 24 not supported");
if (!(img->ximg = XCreateImage(xw.dpy, CopyFromParent, depth, ZPixmap, 0,
NULL, width, height, 32, 0)))
die("sent: Unable to create XImage");
img->ximg->data = ecalloc(height, img->ximg->bytes_per_line);
if (!XInitImage(img->ximg))
die("sent: Unable to initiate XImage");
ffscale(img);
img->state |= SCALED;
}
void
ffscale(Image *img)
{
unsigned int x, y;
unsigned int width = img->ximg->width;
unsigned int height = img->ximg->height;
char* newBuf = img->ximg->data;
unsigned char* ibuf;
unsigned int jdy = img->ximg->bytes_per_line / 4 - width;
unsigned int dx = (img->bufwidth << 10) / width;
for (y = 0; y < height; y++) {
unsigned int bufx = img->bufwidth / width;
ibuf = &img->buf[y * img->bufheight / height * img->bufwidth * 3];
for (x = 0; x < width; x++) {
*newBuf++ = (ibuf[(bufx >> 10)*3+2]);
*newBuf++ = (ibuf[(bufx >> 10)*3+1]);
*newBuf++ = (ibuf[(bufx >> 10)*3+0]);
newBuf++;
bufx += dx;
}
newBuf += jdy;
}
}
void
ffdraw(Image *img)
{
int xoffset = (xw.w - img->ximg->width) / 2;
int yoffset = (xw.h - img->ximg->height) / 2;
XPutImage(xw.dpy, xw.win, d->gc, img->ximg, 0, 0,
xoffset, yoffset, img->ximg->width, img->ximg->height);
XFlush(xw.dpy);
}
void
getfontsize(Slide *s, unsigned int *width, unsigned int *height)
{
int i, j;
unsigned int curw, newmax;
float lfac = linespacing * (s->linecount - 1) + 1;
/* fit height */
for (j = NUMFONTSCALES - 1; j >= 0; j--)
if (fonts[j]->h * lfac <= xw.uh)
break;
LIMIT(j, 0, NUMFONTSCALES - 1);
drw_setfontset(d, fonts[j]);
/* fit width */
*width = 0;
for (i = 0; i < s->linecount; i++) {
curw = drw_fontset_getwidth(d, s->lines[i]);
newmax = (curw >= *width);
while (j > 0 && curw > xw.uw) {
drw_setfontset(d, fonts[--j]);
curw = drw_fontset_getwidth(d, s->lines[i]);
}
if (newmax)
*width = curw;
}
*height = fonts[j]->h * lfac;
}
void
cleanup(int slidesonly)
{
unsigned int i, j;
if (!slidesonly) {
for (i = 0; i < NUMFONTSCALES; i++)
drw_fontset_free(fonts[i]);
free(sc);
drw_free(d);
XDestroyWindow(xw.dpy, xw.win);
XSync(xw.dpy, False);
XCloseDisplay(xw.dpy);
}
if (slides) {
for (i = 0; i < slidecount; i++) {
for (j = 0; j < slides[i].linecount; j++)
free(slides[i].lines[j]);
free(slides[i].lines);
if (slides[i].img)
fffree(slides[i].img);
}
if (!slidesonly) {
free(slides);
slides = NULL;
}
}
}
void
reload(const Arg *arg)
{
FILE *fp = NULL;
unsigned int i;
if (!fname) {
fprintf(stderr, "sent: Cannot reload from stdin. Use a file!\n");
return;
}
cleanup(1);
slidecount = 0;
if (!(fp = fopen(fname, "r")))
die("sent: Unable to open '%s' for reading:", fname);
load(fp);
fclose(fp);
LIMIT(idx, 0, slidecount-1);
for (i = 0; i < slidecount; i++)
ffload(&slides[i]);
xdraw();
}
void
load(FILE *fp)
{
static size_t size = 0;
size_t blen, maxlines;
char buf[BUFSIZ], *p;
Slide *s;
/* read each line from fp and add it to the item list */
while (1) {
/* eat consecutive empty lines */
while ((p = fgets(buf, sizeof(buf), fp)))
if (strcmp(buf, "\n") != 0 && buf[0] != '#')
break;
if (!p)
break;
if ((slidecount+1) * sizeof(*slides) >= size)
if (!(slides = realloc(slides, (size += BUFSIZ))))
die("sent: Unable to reallocate %u bytes:", size);
/* read one slide */
maxlines = 0;
memset((s = &slides[slidecount]), 0, sizeof(Slide));
do {
/* if there's a leading null, we can't do blen-1 */
if (buf[0] == '\0')
continue;
if (buf[0] == '#')
continue;
/* grow lines array */
if (s->linecount >= maxlines) {
maxlines = 2 * s->linecount + 1;
if (!(s->lines = realloc(s->lines, maxlines * sizeof(s->lines[0]))))
die("sent: Unable to reallocate %u bytes:", maxlines * sizeof(s->lines[0]));
}
blen = strlen(buf);
if (!(s->lines[s->linecount] = strdup(buf)))
die("sent: Unable to strdup:");
if (s->lines[s->linecount][blen-1] == '\n')
s->lines[s->linecount][blen-1] = '\0';
/* mark as image slide if first line of a slide starts with @ */
if (s->linecount == 0 && s->lines[0][0] == '@')
s->embed = &s->lines[0][1];
if (s->lines[s->linecount][0] == '\\')
memmove(s->lines[s->linecount], &s->lines[s->linecount][1], blen);
s->linecount++;
} while ((p = fgets(buf, sizeof(buf), fp)) && strcmp(buf, "\n") != 0);
slidecount++;
if (!p)
break;
}
if (!slidecount)
die("sent: No slides in file");
}
void
advance(const Arg *arg)
{
int new_idx = idx + arg->i;
LIMIT(new_idx, 0, slidecount-1);
if (new_idx != idx) {
if (slides[idx].img)
slides[idx].img->state &= ~SCALED;
idx = new_idx;
xdraw();
}
}
void
quit(const Arg *arg)
{
running = 0;
}
void
resize(int width, int height)
{
xw.w = width;
xw.h = height;
xw.uw = usablewidth * width;
xw.uh = usableheight * height;
drw_resize(d, width, height);
}
void
run()
{
XEvent ev;
/* Waiting for window mapping */
while (1) {
XNextEvent(xw.dpy, &ev);
if (ev.type == ConfigureNotify) {
resize(ev.xconfigure.width, ev.xconfigure.height);
} else if (ev.type == MapNotify) {
break;
}
}
while (running) {
XNextEvent(xw.dpy, &ev);
if (handler[ev.type])
(handler[ev.type])(&ev);
}
}
void
xdraw()
{
unsigned int height, width, i;
Image *im = slides[idx].img;
getfontsize(&slides[idx], &width, &height);
XClearWindow(xw.dpy, xw.win);
if (!im) {
drw_rect(d, 0, 0, xw.w, xw.h, 1, 1);
for (i = 0; i < slides[idx].linecount; i++)
drw_text(d,
(xw.w - width) / 2,
(xw.h - height) / 2 + i * linespacing * d->fonts->h,
width,
d->fonts->h,
0,
slides[idx].lines[i],
0);
drw_map(d, xw.win, 0, 0, xw.w, xw.h);
} else {
if (!(im->state & SCALED))
ffprepare(im);
ffdraw(im);
}
}
void
xhints()
{
XClassHint class = {.res_name = "sent", .res_class = "presenter"};
XWMHints wm = {.flags = InputHint, .input = True};
XSizeHints *sizeh = NULL;
if (!(sizeh = XAllocSizeHints()))
die("sent: Unable to allocate size hints");
sizeh->flags = PSize;
sizeh->height = xw.h;
sizeh->width = xw.w;
XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, &class);
XFree(sizeh);
}
void
xinit()
{
XTextProperty prop;
unsigned int i;
if (!(xw.dpy = XOpenDisplay(NULL)))
die("sent: Unable to open display");
xw.scr = XDefaultScreen(xw.dpy);
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
resize(DisplayWidth(xw.dpy, xw.scr), DisplayHeight(xw.dpy, xw.scr));
xw.attrs.bit_gravity = CenterGravity;
xw.attrs.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask |
ButtonMotionMask | ButtonPressMask;
xw.win = XCreateWindow(xw.dpy, XRootWindow(xw.dpy, xw.scr), 0, 0,
xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr),
InputOutput, xw.vis, CWBitGravity | CWEventMask,
&xw.attrs);
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
if (!(d = drw_create(xw.dpy, xw.scr, xw.win, xw.w, xw.h)))
die("sent: Unable to create drawing context");
sc = drw_scm_create(d, colors, 2);
drw_setscheme(d, sc);
XSetWindowBackground(xw.dpy, xw.win, sc[ColBg].pixel);
xloadfonts();
for (i = 0; i < slidecount; i++)
ffload(&slides[i]);
XStringListToTextProperty(&argv0, 1, &prop);
XSetWMName(xw.dpy, xw.win, &prop);
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
XFree(prop.value);
XMapWindow(xw.dpy, xw.win);
xhints();
XSync(xw.dpy, False);
}
void
xloadfonts()
{
int i, j;
char *fstrs[LEN(fontfallbacks)];
for (j = 0; j < LEN(fontfallbacks); j++) {
fstrs[j] = ecalloc(1, MAXFONTSTRLEN);
}
for (i = 0; i < NUMFONTSCALES; i++) {
for (j = 0; j < LEN(fontfallbacks); j++) {
if (MAXFONTSTRLEN < snprintf(fstrs[j], MAXFONTSTRLEN, "%s:size=%d", fontfallbacks[j], FONTSZ(i)))
die("sent: Font string too long");
}
if (!(fonts[i] = drw_fontset_create(d, (const char**)fstrs, LEN(fstrs))))
die("sent: Unable to load any font for size %d", FONTSZ(i));
}
for (j = 0; j < LEN(fontfallbacks); j++)
if (fstrs[j])
free(fstrs[j]);
}
void
bpress(XEvent *e)
{
unsigned int i;
for (i = 0; i < LEN(mshortcuts); i++)
if (e->xbutton.button == mshortcuts[i].b && mshortcuts[i].func)
mshortcuts[i].func(&(mshortcuts[i].arg));
}
void
cmessage(XEvent *e)
{
if (e->xclient.data.l[0] == xw.wmdeletewin)
running = 0;
}
void
expose(XEvent *e)
{
if (0 == e->xexpose.count)
xdraw();
}
void
kpress(XEvent *e)
{
unsigned int i;
KeySym sym;
sym = XkbKeycodeToKeysym(xw.dpy, (KeyCode)e->xkey.keycode, 0, 0);
for (i = 0; i < LEN(shortcuts); i++)
if (sym == shortcuts[i].keysym && shortcuts[i].func)
shortcuts[i].func(&(shortcuts[i].arg));
}
void
configure(XEvent *e)
{
resize(e->xconfigure.width, e->xconfigure.height);
if (slides[idx].img)
slides[idx].img->state &= ~SCALED;
xdraw();
}
void
usage()
{
die("usage: %s [file]", argv0);
}
int
main(int argc, char *argv[])
{
FILE *fp = NULL;
ARGBEGIN {
case 'v':
fprintf(stderr, "sent-"VERSION"\n");
return 0;
default:
usage();
} ARGEND
if (!argv[0] || !strcmp(argv[0], "-"))
fp = stdin;
else if (!(fp = fopen(fname = argv[0], "r")))
die("sent: Unable to open '%s' for reading:", fname);
load(fp);
fclose(fp);
xinit();
run();
cleanup(0);
return 0;
}

BIN
.local/src/sent/transparent_test.ff View File


+ 35
- 0
.local/src/sent/util.c View File

@ -0,0 +1,35 @@
/* See LICENSE file for copyright and license details. */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}
void
die(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
fputc(' ', stderr);
perror(NULL);
} else {
fputc('\n', stderr);
}
exit(1);
}

+ 8
- 0
.local/src/sent/util.h View File

@ -0,0 +1,8 @@
/* See LICENSE file for copyright and license details. */
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);

+ 1
- 1
.local/src/st/config.h View File

@ -149,7 +149,7 @@ static unsigned int defaultunderline = 7;
* 6: Bar ("|")
* 7: Snowman ("")
*/
static unsigned int cursorshape = 2;
static unsigned int cursorshape = 0;
/*
* Default columns and rows numbers


BIN
.local/src/st/st View File


+ 21
- 4
.local/src/st/st.c View File

@ -46,6 +46,7 @@
#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \
term.scr + HISTSIZE + 1) % HISTSIZE] : \
term.line[(y) - term.scr])
#define TLINE_HIST(y) ((y) <= HISTSIZE-term.row+2 ? term.hist[(y)] : term.line[(y-HISTSIZE+term.row-3)])
enum term_mode {
MODE_WRAP = 1 << 0,
@ -429,6 +430,20 @@ tlinelen(int y)
return i;
}
int
tlinehistlen(int y)
{
int i = term.col;
if (TLINE_HIST(y)[i - 1].mode & ATTR_WRAP)
return i;
while (i > 0 && TLINE_HIST(y)[i - 1].u == ' ')
--i;
return i;
}
void
selstart(int col, int row, int snap)
{
@ -2034,16 +2049,18 @@ externalpipe(const Arg *arg)
/* ignore sigpipe for now, in case child exists early */
oldsigpipe = signal(SIGPIPE, SIG_IGN);
newline = 0;
for (n = 0; n < term.row; n++) {
bp = term.line[n];
lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
for (n = 0; n <= HISTSIZE + 2; n++) {
bp = TLINE_HIST(n);
lastpos = MIN(tlinehistlen(n) + 1, term.col) - 1;
if (lastpos < 0)
break;
if (lastpos == 0)
continue;
end = &bp[lastpos + 1];
for (; bp < end; ++bp)
if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
break;
if ((newline = term.line[n][lastpos].mode & ATTR_WRAP))
if ((newline = TLINE_HIST(n)[lastpos].mode & ATTR_WRAP))
continue;
if (xwrite(to[1], "\n", 1) < 0)
break;


+ 1
- 1
.local/src/st/st.c.orig View File

@ -200,7 +200,6 @@ static void tsetscroll(int, int);
static void tswapscreen(void);
static void tsetmode(int, int, int *, int);
static int twrite(const char *, int, int);
static void tfulldirt(void);
static void tcontrolcode(uchar );
static void tdectest(char );
static void tdefutf8(char);
@ -734,6 +733,7 @@ sigchld(int a)
if (p == 0 && waitpid(-1 ,&stat, WNOHANG) < 0)
/* Changed from wait(&stat) to waitpid(-1, &stat, WNOHANG) */
/* Otherwise the terminal would hang after calling iso4755 */
/* the issue is caused by a conflict between the patches iso4755 and externalpipe */
die("wait: %s\n", strerror(errno));
signal(SIGCHLD, sigchld);


BIN
.local/src/st/st.o View File


+ 0
- 138
.local/src/surf/surf-0.6-navhist.diff View File

@ -1,138 +0,0 @@
diff --git a/config.def.h b/config.def.h
index a221c86..9840736 100644
--- a/config.def.h
+++ b/config.def.h
@@ -32,6 +32,16 @@ static Bool hidebackground = FALSE;
} \
}
+#define SELNAV { \
+ .v = (char *[]){ "/bin/sh", "-c", \
+ "prop=\"`xprop -id $0 _SURF_HIST" \
+ " | sed -e 's/^.[^\"]*\"//' -e 's/\"$//' -e 's/\\\\\\n/\\n/g'" \
+ " | dmenu -i -l 10`\"" \
+ " && xprop -id $0 -f _SURF_NAV 8s -set _SURF_NAV \"$prop\"", \
+ winid, NULL \
+ } \
+}
+
/* DOWNLOAD(URI, referer) */
#define DOWNLOAD(d, r) { \
.v = (char *[]){ "/bin/sh", "-c", \
@@ -67,6 +77,7 @@ static Key keys[] = {
{ MODKEY, GDK_l, navigate, { .i = +1 } },
{ MODKEY, GDK_h, navigate, { .i = -1 } },
+ { MODKEY|GDK_SHIFT_MASK,GDK_h, selhist, SELNAV },
{ MODKEY, GDK_j, scroll_v, { .i = +1 } },
{ MODKEY, GDK_k, scroll_v, { .i = -1 } },
diff --git a/surf.c b/surf.c
index cebd469..8b6d751 100644
--- a/surf.c
+++ b/surf.c
@@ -32,7 +32,7 @@ char *argv0;
#define COOKIEJAR_TYPE (cookiejar_get_type ())
#define COOKIEJAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COOKIEJAR_TYPE, CookieJar))
-enum { AtomFind, AtomGo, AtomUri, AtomLast };
+enum { AtomFind, AtomGo, AtomUri, AtomHist, AtomNav, AtomLast };
typedef union Arg Arg;
union Arg {
@@ -137,6 +137,8 @@ static void loadstatuschange(WebKitWebView *view, GParamSpec *pspec,
Client *c);
static void loaduri(Client *c, const Arg *arg);
static void navigate(Client *c, const Arg *arg);
+static void selhist(Client *c, const Arg *arg);
+static void navhist(Client *c, const Arg *arg);
static Client *newclient(void);
static void newwindow(Client *c, const Arg *arg, gboolean noembed);
static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
@@ -649,6 +651,59 @@ navigate(Client *c, const Arg *arg) {
webkit_web_view_go_back_or_forward(c->view, steps);
}
+static void
+selhist(Client *c, const Arg *arg) {
+ WebKitWebBackForwardList *lst;
+ WebKitWebHistoryItem *cur;
+ gint i;
+ gchar *out;
+ gchar *tmp;
+ gchar *line;
+
+ out = g_strdup("");
+
+ if(!(lst = webkit_web_view_get_back_forward_list(c->view)))
+ return;
+
+ for(i = webkit_web_back_forward_list_get_back_length(lst); i > 0; i--) {
+ if(!(cur = webkit_web_back_forward_list_get_nth_item(lst, -i)))
+ break;
+ line = g_strdup_printf("%d: %s\n", -i,
+ webkit_web_history_item_get_original_uri(cur));
+ tmp = g_strconcat(out, line, NULL);
+ g_free(out);
+ out = tmp;
+ }
+
+ if((cur = webkit_web_back_forward_list_get_nth_item(lst, 0))) {
+ line = g_strdup_printf("%d: %s", 0,
+ webkit_web_history_item_get_original_uri(cur));
+ tmp = g_strconcat(out, line, NULL);
+ g_free(out);
+ out = tmp;
+ }
+
+ for(i = 1; i <= webkit_web_back_forward_list_get_forward_length(lst); i++) {
+ if(!(cur = webkit_web_back_forward_list_get_nth_item(lst, i)))
+ break;
+ line = g_strdup_printf("\n%d: %s", i,
+ webkit_web_history_item_get_original_uri(cur));
+ tmp = g_strconcat(out, line, NULL);
+ g_free(out);
+ out = tmp;
+ }
+
+ setatom(c, AtomHist, out);
+ g_free(out);
+ spawn(c, arg);
+}
+
+static void
+navhist(Client *c, const Arg *arg) {
+ Arg a = { .i = atoi(arg->v) };
+ navigate(c, &a);
+}
+
static Client *
newclient(void) {
Client *c;
@@ -805,6 +860,7 @@ newclient(void) {
setatom(c, AtomFind, "");
setatom(c, AtomUri, "about:blank");
+ setatom(c, AtomHist, "");
if(hidebackground)
webkit_web_view_set_transparent(c->view, TRUE);
@@ -923,6 +979,9 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer d) {
arg.v = getatom(c, AtomGo);
loaduri(c, &arg);
return GDK_FILTER_REMOVE;
+ } else if(ev->atom == atoms[AtomNav]) {
+ arg.v = getatom(c, AtomNav);
+ navhist(c, &arg);
}
}
}
@@ -1004,6 +1063,8 @@ setup(void) {
atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False);
atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False);
atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False);
+ atoms[AtomHist] = XInternAtom(dpy, "_SURF_HIST", False);
+ atoms[AtomNav] = XInternAtom(dpy, "_SURF_NAV", False);
/* dirs and files */
cookiefile = buildpath(cookiefile);

+ 0
- 59
.local/src/surf/surf-0.7-omnibar.diff View File

@ -1,59 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 93a3d49..05d81de 100644
--- a/config.def.h
+++ b/config.def.h
@@ -65,6 +65,18 @@ static Bool allowgeolocation = TRUE;
} \
}
+#define ONLOAD(u) { \
+ .v = (char *[]){"/bin/sh", "-c", \
+ "~/.surf/omnibar addhist \"$0\"", u, NULL \
+ } \
+}
+
+#define GOTO { \
+ .v = (char *[]){"/bin/sh", "-c", \
+ "~/.surf/omnibar goto \"$0\" \"$1\"", winid, "_SURF_GO", NULL \
+ } \
+}
+
/* styles */
/*
* The iteration will stop at the first match, beginning at the beginning of
@@ -112,7 +124,7 @@ static Key keys[] = {
{ MODKEY, GDK_o, source, { 0 } },
{ MODKEY|GDK_SHIFT_MASK,GDK_o, inspector, { 0 } },
- { MODKEY, GDK_g, spawn, SETPROP("_SURF_URI", "_SURF_GO") },
+ { MODKEY, GDK_g, spawn, GOTO },
{ MODKEY, GDK_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") },
{ MODKEY, GDK_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") },
diff --git a/surf.c b/surf.c
index f2170a4..c8fdab3 100644
--- a/surf.c
+++ b/surf.c
@@ -789,11 +789,11 @@ loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c)
WebKitWebDataSource *src;
WebKitNetworkRequest *request;
SoupMessage *msg;
- char *uri;
+ char *uri = geturi(c);
+ Arg arg;
switch (webkit_web_view_get_load_status (c->view)) {
case WEBKIT_LOAD_COMMITTED:
- uri = geturi(c);
if (strstr(uri, "https://") == uri) {
frame = webkit_web_view_get_main_frame(c->view);
src = webkit_web_frame_get_data_source(frame);
@@ -809,6 +809,8 @@ loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c)
setstyle(c, getstyle(uri));
break;
case WEBKIT_LOAD_FINISHED:
+ arg = (Arg)ONLOAD(uri);
+ spawn(NULL, &arg);
c->progress = 100;
updatetitle(c);
if (diskcache) {

+ 0
- 93
.local/src/surf/surf-2.0-externalpipe.diff View File

@ -1,93 +0,0 @@
diff --git a/surf.c b/surf.c
index 93a1629..ba53b94 100644
--- a/surf.c
+++ b/surf.c
@@ -217,6 +217,7 @@ static void togglefullscreen(Client *c, const Arg *a);
static void togglecookiepolicy(Client *c, const Arg *a);
static void toggleinspector(Client *c, const Arg *a);
static void find(Client *c, const Arg *a);
+static void externalpipe(Client *c, const Arg *a);
/* Buttons */
static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h);
@@ -241,6 +242,80 @@ char *argv0;
/* configuration, allows nested code to access above variables */
#include "config.h"
+static void
+externalpipe_execute(char* buffer, Arg *arg) {
+ int to[2];
+ void (*oldsigpipe)(int);
+
+ if (pipe(to) == -1)
+ return;
+
+ switch (fork()) {
+ case -1:
+ close(to[0]);
+ close(to[1]);
+ return;
+ case 0:
+ dup2(to[0], STDIN_FILENO); close(to[0]); close(to[1]);
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
+ perror("failed");
+ exit(0);
+ }
+
+ close(to[0]);
+ oldsigpipe = signal(SIGPIPE, SIG_IGN);
+ write(to[1], buffer, strlen(buffer));
+ close(to[1]);
+ signal(SIGPIPE, oldsigpipe);
+}
+
+static void
+externalpipe_resource_done(WebKitWebResource *r, GAsyncResult *s, Arg *arg)
+{
+ GError *gerr = NULL;
+ guchar *buffer = webkit_web_resource_get_data_finish(r, s, NULL, &gerr);
+ if (gerr == NULL) {
+ externalpipe_execute((char *) buffer, arg);
+ } else {
+ g_error_free(gerr);
+ }
+ g_free(buffer);
+}
+
+static void
+externalpipe_js_done(WebKitWebView *wv, GAsyncResult *s, Arg *arg)
+{
+ WebKitJavascriptResult *j = webkit_web_view_run_javascript_finish(
+ wv, s, NULL);
+ if (!j) {
+ return;
+ }
+ JSCValue *v = webkit_javascript_result_get_js_value(j);
+ if (jsc_value_is_string(v)) {
+ char *buffer = jsc_value_to_string(v);
+ externalpipe_execute(buffer, arg);
+ g_free(buffer);
+ }
+ webkit_javascript_result_unref(j);
+}
+
+void
+externalpipe(Client *c, const Arg *arg)
+{
+ if (curconfig[JavaScript].val.i) {
+ webkit_web_view_run_javascript(
+ c->view, "window.document.documentElement.outerHTML",
+ NULL, externalpipe_js_done, arg);
+ } else {
+ WebKitWebResource *resource = webkit_web_view_get_main_resource(c->view);
+ if (resource != NULL) {
+ webkit_web_resource_get_data(
+ resource, NULL, externalpipe_resource_done, arg);
+ }
+ }
+}
+
void
usage(void)
{

+ 0
- 24
.local/src/surf/surf-2.0-homepage.diff View File

@ -1,24 +0,0 @@
diff --git a/config.def.h b/config.def.h
--- a/config.def.h
+++ b/config.def.h
@@ -164,3 +164,5 @@ static Button buttons[] = {
{ OnAny, 0, 9, clicknavigate, { .i = +1 }, 1 },
{ OnMedia, MODKEY, 1, clickexternplayer, { 0 }, 1 },
};
+
+#define HOMEPAGE "https://duckduckgo.com/"
diff --git a/surf.c b/surf.c
--- a/surf.c
+++ b/surf.c
@@ -1751,7 +1751,11 @@ main(int argc, char *argv[])
if (argc > 0)
arg.v = argv[0];
else
+#ifdef HOMEPAGE
+ arg.v = HOMEPAGE;
+#else
arg.v = "about:blank";
+#endif
setup();
c = newclient(NULL);

+ 0
- 42
.local/src/surf/surf-bookmarks-20170722-723ff26.diff View File

@ -1,42 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 2e735bf..43ad9ab 100644
--- a/config.def.h
+++ b/config.def.h
@@ -69,8 +69,9 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
#define SETPROP(r, s, p) { \
.v = (const char *[]){ "/bin/sh", "-c", \
"prop=\"$(printf '%b' \"$(xprop -id $1 $2 " \
- "| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\")\" " \
- "| dmenu -p \"$4\" -w $1)\" && xprop -id $1 -f $3 8s -set $3 \"$prop\"", \
+ "| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\" && cat ~/.surf/bookmarks)\" " \
+ "| dmenu -l 10 -p \"$4\" -w $1)\" && " \
+ "xprop -id $1 -f $3 8s -set $3 \"$prop\"", \
"surf-setprop", winid, r, s, p, NULL \
} \
}
@@ -101,6 +102,17 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
} \
}
+/* BM_ADD(readprop) */
+#define BM_ADD(r) {\
+ .v = (const char *[]){ "/bin/sh", "-c", \
+ "(echo $(xprop -id $0 $1) | cut -d '\"' -f2 " \
+ "| sed 's/.*https*:\\/\\/\\(www\\.\\)\\?//' && cat ~/.surf/bookmarks) " \
+ "| awk '!seen[$0]++' > ~/.surf/bookmarks.tmp && " \
+ "mv ~/.surf/bookmarks.tmp ~/.surf/bookmarks", \
+ winid, r, NULL \
+ } \
+}
+
/* styles */
/*
* The iteration will stop at the first match, beginning at the beginning of
@@ -132,6 +144,7 @@ static Key keys[] = {
{ MODKEY, GDK_KEY_g, spawn, SETPROP("_SURF_URI", "_SURF_GO", PROMPT_GO) },
{ MODKEY, GDK_KEY_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) },
{ MODKEY, GDK_KEY_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) },
+ { MODKEY, GDK_KEY_m, spawn, BM_ADD("_SURF_URI") },
{ 0, GDK_KEY_Escape, stop, { 0 } },
{ MODKEY, GDK_KEY_c, stop, { 0 } },

+ 0
- 67
.local/src/surf/surf-clipboard-20200112-a6a8878.diff View File

@ -1,67 +0,0 @@
From a6a8878bb6a203b589d559025b94a78214f22878 Mon Sep 17 00:00:00 2001
From: Olivier Moreau <m242@protonmail.com>
Date: Sun, 12 Jan 2020 11:23:11 +0000
Subject: [PATCH] Added choice between PRIMARY and CLIPBOARD Gtk selections, as
a config option
---
config.def.h | 1 +
surf.c | 11 +++++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index 34265f6..03bbe2b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -48,6 +48,7 @@ static Parameter defconfig[ParameterLast] = {
[Style] = { { .i = 1 }, },
[WebGL] = { { .i = 0 }, },
[ZoomLevel] = { { .f = 1.0 }, },
+ [ClipboardNotPrimary] = { { .i = 1 }, },
};
static UriParameters uriparams[] = {
diff --git a/surf.c b/surf.c
index 2b54e3c..b8a9b2f 100644
--- a/surf.c
+++ b/surf.c
@@ -82,6 +82,7 @@ typedef enum {
Style,
WebGL,
ZoomLevel,
+ ClipboardNotPrimary,
ParameterLast
} ParamName;
@@ -291,6 +292,7 @@ static ParamName loadcommitted[] = {
SpellLanguages,
Style,
ZoomLevel,
+ ClipboardNotPrimary,
ParameterLast
};
@@ -1816,13 +1818,18 @@ showcert(Client *c, const Arg *a)
void
clipboard(Client *c, const Arg *a)
{
+ /* User defined choice of selection, see config.h */
+ GdkAtom selection = GDK_SELECTION_PRIMARY;
+ if (curconfig[ClipboardNotPrimary].val.i > 0)
+ selection = GDK_SELECTION_CLIPBOARD;
+
if (a->i) { /* load clipboard uri */
gtk_clipboard_request_text(gtk_clipboard_get(
- GDK_SELECTION_PRIMARY),
+ selection),
pasteuri, c);
} else { /* copy uri */
gtk_clipboard_set_text(gtk_clipboard_get(
- GDK_SELECTION_PRIMARY), c->targeturi
+ selection), c->targeturi
? c->targeturi : geturi(c), -1);
}
}
--
2.24.1

+ 0
- 107
.local/src/surf/surf-history-20181009-2b71a22.diff View File

@ -1,107 +0,0 @@
diff -up surf-2.0/config.def.h surf-2.0-history/config.def.h
--- surf-2.0/config.def.h 2017-11-26 14:29:37.963786915 +0100
+++ surf-2.0-history/config.def.h 2017-11-26 19:48:31.300096237 +0100
@@ -6,6 +6,7 @@ static char *styledir = "~/.surf/s
static char *certdir = "~/.surf/certificates/";
static char *cachedir = "~/.surf/cache/";
static char *cookiefile = "~/.surf/cookies.txt";
+static char *historyfile = "~/.surf/history.txt";
/* Webkit default features */
/* Highest priority value will be used.
@@ -101,6 +102,11 @@ static WebKitFindOptions findopts = WEBK
} \
}
+#define SETURI(p) { .v = (char *[]){ "/bin/sh", "-c", \
+"prop=\"`surf_history_dmenu.sh`\" &&" \
+"xprop -id $1 -f $0 8s -set $0 \"$prop\"", \
+p, winid, NULL } }
+
/* styles */
/*
* The iteration will stop at the first match, beginning at the beginning of
@@ -181,6 +187,7 @@ static Key keys[] = {
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_b, toggle, { .i = ScrollBars } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_t, toggle, { .i = StrictTLS } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_m, toggle, { .i = Style } },
+ { MODKEY , GDK_KEY_Return, spawn, SETURI("_SURF_GO") },
};
/* button definitions */
Only in surf-2.0-history/: config.h
Only in surf-2.0: .git
Only in surf-2.0-history/: surf
diff -up surf-2.0/surf.c surf-2.0-history/surf.c
--- surf-2.0/surf.c 2017-11-26 14:29:37.963786915 +0100
+++ surf-2.0-history/surf.c 2017-11-26 14:20:36.757100476 +0100
@@ -171,6 +171,7 @@ static void newwindow(Client *c, const A
static void spawn(Client *c, const Arg *a);
static void destroyclient(Client *c);
static void cleanup(void);
+static void updatehistory(const char *u, const char *t);
/* GTK/WebKit */
static WebKitWebView *newview(Client *c, WebKitWebView *rv);
@@ -336,10 +337,11 @@ setup(void)
curconfig = defconfig;
/* dirs and files */
- cookiefile = buildfile(cookiefile);
- scriptfile = buildfile(scriptfile);
- cachedir = buildpath(cachedir);
- certdir = buildpath(certdir);
+ cookiefile = buildfile(cookiefile);
+ historyfile = buildfile(historyfile);
+ scriptfile = buildfile(scriptfile);
+ cachedir = buildpath(cachedir);
+ certdir = buildpath(certdir);
gdkkb = gdk_seat_get_keyboard(gdk_display_get_default_seat(gdpy));
@@ -1042,12 +1044,28 @@ cleanup(void)
while (clients)
destroyclient(clients);
g_free(cookiefile);
+ g_free(historyfile);
g_free(scriptfile);
g_free(stylefile);
g_free(cachedir);
XCloseDisplay(dpy);
}
+void
+updatehistory(const char *u, const char *t)
+{
+ FILE *f;
+ f = fopen(historyfile, "a+");
+
+ char b[20];
+ time_t now = time (0);
+ strftime (b, 20, "%Y-%m-%d %H:%M:%S", localtime (&now));
+ fputs(b, f);
+
+ fprintf(f, " %s %s\n", u, t);
+ fclose(f);
+}
+
WebKitWebView *
newview(Client *c, WebKitWebView *rv)
{
@@ -1417,6 +1435,7 @@ loadfailedtls(WebKitWebView *v, gchar *u
return TRUE;
}
+
void
loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client *c)
{
@@ -1445,6 +1464,7 @@ loadchanged(WebKitWebView *v, WebKitLoad
break;
case WEBKIT_LOAD_FINISHED:
seturiparameters(c, uri, loadfinished);
+ updatehistory(uri, c->title);
/* Disabled until we write some WebKitWebExtension for
* manipulating the DOM directly.
evalscript(c, "document.documentElement.style.overflow = '%s'",
Only in surf-2.0-history/: surf.o

+ 0
- 134
.local/src/surf/surf-modal-20190209-d068a38.diff View File

@ -1,134 +0,0 @@
From 74a98d9600c50d50b9323cf8e459c88eb15da557 Mon Sep 17 00:00:00 2001
From: efe <efe@efe.kim>
Date: Sat, 9 Feb 2019 13:16:51 -0500
Subject: [PATCH] Modal behaviour, 'i' to insert 'Esc' to get to the normal
mode
---
config.def.h | 53 +++++++++++++++++++++++++++-------------------------
surf.c | 14 +++++++++++++-
2 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/config.def.h b/config.def.h
index 34265f6..8b7d5a2 100644
--- a/config.def.h
+++ b/config.def.h
@@ -130,41 +130,44 @@ static SiteSpecific certs[] = {
*/
static Key keys[] = {
/* modifier keyval function arg */
- { MODKEY, GDK_KEY_g, spawn, SETPROP("_SURF_URI", "_SURF_GO", PROMPT_GO) },
- { MODKEY, GDK_KEY_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) },
- { MODKEY, GDK_KEY_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) },
+ { 0, GDK_KEY_g, spawn, SETPROP("_SURF_URI", "_SURF_GO", PROMPT_GO) },
+ { 0, GDK_KEY_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) },
+ { 0, GDK_KEY_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) },
- { 0, GDK_KEY_Escape, stop, { 0 } },
- { MODKEY, GDK_KEY_c, stop, { 0 } },
+ { 0, GDK_KEY_i, insert, { .i = 1 } },
+ { 0, GDK_KEY_Escape, insert, { .i = 0 } },
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_r, reload, { .i = 1 } },
- { MODKEY, GDK_KEY_r, reload, { .i = 0 } },
+ { 0, GDK_KEY_c, stop, { 0 } },
- { MODKEY, GDK_KEY_l, navigate, { .i = +1 } },
- { MODKEY, GDK_KEY_h, navigate, { .i = -1 } },
+ { MODKEY, GDK_KEY_r, reload, { .i = 1 } },
+ { 0, GDK_KEY_r, reload, { .i = 0 } },
+
+ { 0, GDK_KEY_l, navigate, { .i = +1 } },
+ { 0, GDK_KEY_h, navigate, { .i = -1 } },
/* vertical and horizontal scrolling, in viewport percentage */
- { MODKEY, GDK_KEY_j, scrollv, { .i = +10 } },
- { MODKEY, GDK_KEY_k, scrollv, { .i = -10 } },
- { MODKEY, GDK_KEY_space, scrollv, { .i = +50 } },
- { MODKEY, GDK_KEY_b, scrollv, { .i = -50 } },
- { MODKEY, GDK_KEY_i, scrollh, { .i = +10 } },
- { MODKEY, GDK_KEY_u, scrollh, { .i = -10 } },
+ { 0, GDK_KEY_j, scrollv, { .i = +10 } },
+ { 0, GDK_KEY_k, scrollv, { .i = -10 } },
+ { 0, GDK_KEY_space, scrollv, { .i = +50 } },
+ { 0, GDK_KEY_b, scrollv, { .i = -50 } },
+ { 0, GDK_KEY_i, scrollh, { .i = +10 } },
+ { 0, GDK_KEY_u, scrollh, { .i = -10 } },
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_j, zoom, { .i = -1 } },
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_k, zoom, { .i = +1 } },
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_q, zoom, { .i = 0 } },
- { MODKEY, GDK_KEY_minus, zoom, { .i = -1 } },
- { MODKEY, GDK_KEY_plus, zoom, { .i = +1 } },
+ { 0|GDK_SHIFT_MASK, GDK_KEY_j, zoom, { .i = -1 } },
+ { 0|GDK_SHIFT_MASK, GDK_KEY_k, zoom, { .i = +1 } },
+ { 0|GDK_SHIFT_MASK, GDK_KEY_q, zoom, { .i = 0 } },
+ { 0, GDK_KEY_minus, zoom, { .i = -1 } },
+ { 0|GDK_SHIFT_MASK, GDK_KEY_plus, zoom, { .i = +1 } },
+ { 0, GDK_KEY_equal, zoom, { .i = 0 } },
- { MODKEY, GDK_KEY_p, clipboard, { .i = 1 } },
- { MODKEY, GDK_KEY_y, clipboard, { .i = 0 } },
+ { 0, GDK_KEY_p, clipboard, { .i = 1 } },
+ { 0, GDK_KEY_y, clipboard, { .i = 0 } },
- { MODKEY, GDK_KEY_n, find, { .i = +1 } },
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_n, find, { .i = -1 } },
+ { 0, GDK_KEY_n, find, { .i = +1 } },
+ { 0|GDK_SHIFT_MASK, GDK_KEY_n, find, { .i = -1 } },
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_p, print, { 0 } },
+ { MODKEY, GDK_KEY_p, print, { 0 } },
{ MODKEY, GDK_KEY_t, showcert, { 0 } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_a, togglecookiepolicy, { 0 } },
diff --git a/surf.c b/surf.c
index 2b54e3c..f4cbe68 100644
--- a/surf.c
+++ b/surf.c
@@ -175,6 +175,7 @@ static void spawn(Client *c, const Arg *a);
static void msgext(Client *c, char type, const Arg *a);
static void destroyclient(Client *c);
static void cleanup(void);
+static int insertmode = 0;
/* GTK/WebKit */
static WebKitWebView *newview(Client *c, WebKitWebView *rv);
@@ -231,6 +232,7 @@ static void togglefullscreen(Client *c, const Arg *a);
static void togglecookiepolicy(Client *c, const Arg *a);
static void toggleinspector(Client *c, const Arg *a);
static void find(Client *c, const Arg *a);
+static void insert(Client *c, const Arg *a);
/* Buttons */
static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h);
@@ -1333,7 +1335,11 @@ winevent(GtkWidget *w, GdkEvent *e, Client *c)
updatetitle(c);
break;
case GDK_KEY_PRESS:
- if (!curconfig[KioskMode].val.i) {
+ if (!curconfig[KioskMode].val.i &&
+ !insertmode ||
+ CLEANMASK(e->key.state) == (MODKEY|GDK_SHIFT_MASK) ||
+ CLEANMASK(e->key.state) == (MODKEY) ||
+ gdk_keyval_to_lower(e->key.keyval) == (GDK_KEY_Escape)) {
for (i = 0; i < LENGTH(keys); ++i) {
if (gdk_keyval_to_lower(e->key.keyval) ==
keys[i].keyval &&
@@ -1947,6 +1953,12 @@ find(Client *c, const Arg *a)
}
}
+void
+insert(Client *c, const Arg *a)
+{
+ insertmode = (a->i);
+}
+
void
clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h)
{
--
2.20.1

+ 0
- 101
.local/src/surf/surf-multijs-20190325-d068a38.diff View File

@ -1,101 +0,0 @@
From 8d8ca34a8e61733711e23ce43b88435bfdfd4962 Mon Sep 17 00:00:00 2001
From: knary <theknary@gmail.com>
Date: Mon, 25 Mar 2019 15:03:15 -0400
Subject: [PATCH] This patch replaces scriptfile with an array of
scriptfiles[]. This allows for the inclusion of multiple javascript files
instead of filling up one file with multiple script plugins.
---
config.def.h | 4 +++-
surf.c | 23 +++++++++++++++--------
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/config.def.h b/config.def.h
index 34265f6..7d7d68e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,11 +1,13 @@
/* modifier 0 means no modifier */
static int surfuseragent = 1; /* Append Surf version to default WebKit user agent */
static char *fulluseragent = ""; /* Or override the whole user agent string */
-static char *scriptfile = "~/.surf/script.js";
static char *styledir = "~/.surf/styles/";
static char *certdir = "~/.surf/certificates/";
static char *cachedir = "~/.surf/cache/";
static char *cookiefile = "~/.surf/cookies.txt";
+static char *scriptfiles[] = {
+ "~/.surf/script.js",
+};
/* Webkit default features */
/* Highest priority value will be used.
diff --git a/surf.c b/surf.c
index 2b54e3c..34a75de 100644
--- a/surf.c
+++ b/surf.c
@@ -337,9 +337,11 @@ setup(void)
/* dirs and files */
cookiefile = buildfile(cookiefile);
- scriptfile = buildfile(scriptfile);
cachedir = buildpath(cachedir);
certdir = buildpath(certdir);
+ for (i = 0; i < LENGTH(scriptfiles); i++) {
+ scriptfiles[i] = buildfile(scriptfiles[i]);
+ }
gdkkb = gdk_seat_get_keyboard(gdk_display_get_default_seat(gdpy));
@@ -945,9 +947,11 @@ runscript(Client *c)
gchar *script;
gsize l;
- if (g_file_get_contents(scriptfile, &script, &l, NULL) && l)
- evalscript(c, "%s", script);
- g_free(script);
+ for (int i = 0; i < LENGTH(scriptfiles); i++) {
+ if (g_file_get_contents(scriptfiles[i], &script, &l, NULL) && l)
+ evalscript(c, "%s", script);
+ g_free(script);
+ }
}
void
@@ -1010,9 +1014,9 @@ newwindow(Client *c, const Arg *a, int noembed)
cmd[i++] = curconfig[Style].val.i ? "-M" : "-m" ;
cmd[i++] = curconfig[Inspector].val.i ? "-N" : "-n" ;
cmd[i++] = curconfig[Plugins].val.i ? "-P" : "-p" ;
- if (scriptfile && g_strcmp0(scriptfile, "")) {
+ if (scriptfiles[0] && g_strcmp0(scriptfiles[0], "")) {
cmd[i++] = "-r";
- cmd[i++] = scriptfile;
+ cmd[i++] = scriptfiles[0];
}
cmd[i++] = curconfig[JavaScript].val.i ? "-S" : "-s";
cmd[i++] = curconfig[StrictTLS].val.i ? "-T" : "-t";
@@ -1076,9 +1080,12 @@ cleanup(void)
close(pipein[0]);
close(pipeout[1]);
g_free(cookiefile);
- g_free(scriptfile);
g_free(stylefile);
g_free(cachedir);
+ for (int i = 0; i < LENGTH(scriptfiles); i++) {
+ g_free(scriptfiles[i]);
+ }
+
XCloseDisplay(dpy);
}
@@ -2067,7 +2074,7 @@ main(int argc, char *argv[])
defconfig[Plugins].prio = 2;
break;
case 'r':
- scriptfile = EARGF(usage());
+ scriptfiles[0] = EARGF(usage());
break;
case 's':
defconfig[JavaScript].val.i = 0;
--
2.21.0

+ 0
- 26
.local/src/surf/surf-spacesearch-20170408-b814567.diff View File

@ -1,26 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 6d3135e..75dc6a6 100644
--- a/config.def.h
+++ b/config.def.h
@@ -153,6 +153,8 @@ static Key keys[] = {
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_m, toggle, { .i = Style } },
};
+static char *searchengine = "https://duckduckgo.com/?q=";
+
/* button definitions */
/* target can be OnDoc, OnLink, OnImg, OnMedia, OnEdit, OnBar, OnSel, OnAny */
static Button buttons[] = {
diff --git a/surf.c b/surf.c
index 93a1629..c20537e 100644
--- a/surf.c
+++ b/surf.c
@@ -476,6 +476,8 @@ loaduri(Client *c, const Arg *a)
} else if (!stat(uri, &st) && (path = realpath(uri, NULL))) {
url = g_strdup_printf("file://%s", path);
free(path);
+ } else if (*uri == ' ') {
+ url = g_strdup_printf("%s%s", searchengine, uri + 1);
} else {
url = g_strdup_printf("http://%s", uri);
}

+ 0
- 138
.local/src/surf/surf-tip-navhist.diff View File

@ -1,138 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 5245129..604028f 100644
--- a/config.def.h
+++ b/config.def.h
@@ -45,6 +45,16 @@ static Bool allowgeolocation = TRUE;
} \
}
+#define SELNAV { \
+ .v = (char *[]){ "/bin/sh", "-c", \
+ "prop=\"`xprop -id $0 _SURF_HIST" \
+ " | sed -e 's/^.[^\"]*\"//' -e 's/\"$//' -e 's/\\\\\\n/\\n/g'" \
+ " | dmenu -i -l 10`\"" \
+ " && xprop -id $0 -f _SURF_NAV 8s -set _SURF_NAV \"$prop\"", \
+ winid, NULL \
+ } \
+}
+
/* DOWNLOAD(URI, referer) */
#define DOWNLOAD(d, r) { \
.v = (char *[]){ "/bin/sh", "-c", \
@@ -99,6 +109,7 @@ static Key keys[] = {
{ MODKEY, GDK_l, navigate, { .i = +1 } },
{ MODKEY, GDK_h, navigate, { .i = -1 } },
+ { MODKEY|GDK_SHIFT_MASK,GDK_h, selhist, SELNAV },
{ MODKEY, GDK_j, scroll_v, { .i = +1 } },
{ MODKEY, GDK_k, scroll_v, { .i = -1 } },
diff --git a/surf.c b/surf.c
index 0fae80b..1c09336 100644
--- a/surf.c
+++ b/surf.c
@@ -36,7 +36,7 @@ char *argv0;
#define COOKIEJAR_TYPE (cookiejar_get_type ())
#define COOKIEJAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COOKIEJAR_TYPE, CookieJar))
-enum { AtomFind, AtomGo, AtomUri, AtomLast };
+enum { AtomFind, AtomGo, AtomUri, AtomHist, AtomNav, AtomLast };
enum {
ClkDoc = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT,
ClkLink = WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK,
@@ -177,6 +177,8 @@ static void loadstatuschange(WebKitWebView *view, GParamSpec *pspec,
Client *c);
static void loaduri(Client *c, const Arg *arg);
static void navigate(Client *c, const Arg *arg);
+static void selhist(Client *c, const Arg *arg);
+static void navhist(Client *c, const Arg *arg);
static Client *newclient(void);
static void newwindow(Client *c, const Arg *arg, gboolean noembed);
static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
@@ -813,6 +815,59 @@ navigate(Client *c, const Arg *arg) {
webkit_web_view_go_back_or_forward(c->view, steps);
}
+static void
+selhist(Client *c, const Arg *arg) {
+ WebKitWebBackForwardList *lst;
+ WebKitWebHistoryItem *cur;
+ gint i;
+ gchar *out;
+ gchar *tmp;
+ gchar *line;
+
+ out = g_strdup("");
+
+ if(!(lst = webkit_web_view_get_back_forward_list(c->view)))
+ return;
+
+ for(i = webkit_web_back_forward_list_get_back_length(lst); i > 0; i--) {
+ if(!(cur = webkit_web_back_forward_list_get_nth_item(lst, -i)))
+ break;
+ line = g_strdup_printf("%d: %s\n", -i,
+ webkit_web_history_item_get_original_uri(cur));
+ tmp = g_strconcat(out, line, NULL);
+ g_free(out);
+ out = tmp;
+ }
+
+ if((cur = webkit_web_back_forward_list_get_nth_item(lst, 0))) {
+ line = g_strdup_printf("%d: %s", 0,
+ webkit_web_history_item_get_original_uri(cur));
+ tmp = g_strconcat(out, line, NULL);
+ g_free(out);
+ out = tmp;
+ }
+
+ for(i = 1; i <= webkit_web_back_forward_list_get_forward_length(lst); i++) {
+ if(!(cur = webkit_web_back_forward_list_get_nth_item(lst, i)))
+ break;
+ line = g_strdup_printf("\n%d: %s", i,
+ webkit_web_history_item_get_original_uri(cur));
+ tmp = g_strconcat(out, line, NULL);
+ g_free(out);
+ out = tmp;
+ }
+
+ setatom(c, AtomHist, out);
+ g_free(out);
+ spawn(c, arg);
+}
+
+static void
+navhist(Client *c, const Arg *arg) {
+ Arg a = { .i = atoi(arg->v) };
+ navigate(c, &a);
+}
+
static Client *
newclient(void) {
Client *c;
@@ -1014,6 +1069,7 @@ newclient(void) {
setatom(c, AtomFind, "");
setatom(c, AtomUri, "about:blank");
+ setatom(c, AtomHist, "");
if(hidebackground)
webkit_web_view_set_transparent(c->view, TRUE);
@@ -1153,6 +1209,9 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer d) {
loaduri(c, &arg);
return GDK_FILTER_REMOVE;
+ } else if(ev->atom == atoms[AtomNav]) {
+ arg.v = getatom(c, AtomNav);
+ navhist(c, &arg);
}
}
}
@@ -1247,6 +1306,8 @@ setup(void) {
atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False);
atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False);
atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False);
+ atoms[AtomHist] = XInternAtom(dpy, "_SURF_HIST", False);
+ atoms[AtomNav] = XInternAtom(dpy, "_SURF_NAV", False);
/* dirs and files */
cookiefile = buildfile(cookiefile);

Loading…
Cancel
Save