summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--config.def.h64
-rw-r--r--st.c2026
-rw-r--r--st.h272
-rw-r--r--win.h29
-rw-r--r--x.c1766
6 files changed, 2168 insertions, 1994 deletions
diff --git a/Makefile b/Makefile
index fb026c4..d8595fe 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
include config.mk
-SRC = st.c
+SRC = st.c x.c
OBJ = ${SRC:.c=.o}
all: options st
@@ -21,6 +21,9 @@ config.h:
@echo CC $<
@${CC} -c ${CFLAGS} $<
+st.o: config.h st.h win.h
+x.o: arg.h st.h win.h
+
${OBJ}: config.h config.mk
st: ${OBJ}
diff --git a/config.def.h b/config.def.h
index a719e36..fd80923 100644
--- a/config.def.h
+++ b/config.def.h
@@ -5,8 +5,8 @@
*
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
-static char font[] = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
-static int borderpx = 2;
+char font[] = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
+int borderpx = 2;
/*
* What program is execed by st depends of these precedence rules:
@@ -24,8 +24,8 @@ static char stty_args[] = "stty raw pass8 nl -echo -iexten -cstopb 38400";
static char vtiden[] = "\033[?6c";
/* Kerning / character bounding-box multipliers */
-static float cwscale = 1.0;
-static float chscale = 1.0;
+float cwscale = 1.0;
+float chscale = 1.0;
/*
* word delimiter string
@@ -35,26 +35,26 @@ static float chscale = 1.0;
static char worddelimiters[] = " ";
/* selection timeouts (in milliseconds) */
-static unsigned int doubleclicktimeout = 300;
-static unsigned int tripleclicktimeout = 600;
+unsigned int doubleclicktimeout = 300;
+unsigned int tripleclicktimeout = 600;
/* alt screens */
-static int allowaltscreen = 1;
+int allowaltscreen = 1;
/* frames per second st should at maximum draw to the screen */
-static unsigned int xfps = 120;
-static unsigned int actionfps = 30;
+unsigned int xfps = 120;
+unsigned int actionfps = 30;
/*
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
* attribute.
*/
-static unsigned int blinktimeout = 800;
+unsigned int blinktimeout = 800;
/*
* thickness of underline and bar cursors
*/
-static unsigned int cursorthickness = 2;
+unsigned int cursorthickness = 2;
/*
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
@@ -63,7 +63,7 @@ static unsigned int cursorthickness = 2;
static int bellvolume = 0;
/* default TERM value */
-static char termname[] = "st-256color";
+char termname[] = "st-256color";
/*
* spaces per tab
@@ -83,7 +83,7 @@ static char termname[] = "st-256color";
static unsigned int tabspaces = 8;
/* Terminal colors (16 first used in escape sequence) */
-static const char *colorname[] = {
+const char *colorname[] = {
/* 8 normal colors */
"black",
"red3",
@@ -116,10 +116,10 @@ static const char *colorname[] = {
* Default colors (colorname index)
* foreground, background, cursor, reverse cursor
*/
-static unsigned int defaultfg = 7;
-static unsigned int defaultbg = 0;
-static unsigned int defaultcs = 256;
-static unsigned int defaultrcs = 257;
+unsigned int defaultfg = 7;
+unsigned int defaultbg = 0;
+unsigned int defaultcs = 256;
+unsigned int defaultrcs = 257;
/*
* Default shape of cursor
@@ -128,33 +128,33 @@ static unsigned int defaultrcs = 257;
* 6: Bar ("|")
* 7: Snowman ("☃")
*/
-static unsigned int cursorshape = 2;
+unsigned int cursorshape = 2;
/*
* Default columns and rows numbers
*/
-static unsigned int cols = 80;
-static unsigned int rows = 24;
+unsigned int cols = 80;
+unsigned int rows = 24;
/*
* Default colour and shape of the mouse cursor
*/
-static unsigned int mouseshape = XC_xterm;
-static unsigned int mousefg = 7;
-static unsigned int mousebg = 0;
+unsigned int mouseshape = XC_xterm;
+unsigned int mousefg = 7;
+unsigned int mousebg = 0;
/*
* Color used to display font attributes when fontconfig selected a font which
* doesn't match the ones requested.
*/
-static unsigned int defaultattr = 11;
+unsigned int defaultattr = 11;
/*
* Internal mouse shortcuts.
* Beware that overloading Button1 will disable the selection.
*/
-static MouseShortcut mshortcuts[] = {
+MouseShortcut mshortcuts[] = {
/* button mask string */
{ Button4, XK_ANY_MOD, "\031" },
{ Button5, XK_ANY_MOD, "\005" },
@@ -163,15 +163,15 @@ static MouseShortcut mshortcuts[] = {
/* Internal keyboard shortcuts. */
#define MODKEY Mod1Mask
-static Shortcut shortcuts[] = {
+Shortcut shortcuts[] = {
/* mask keysym function argument */
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
- { MODKEY|ShiftMask, XK_Prior, xzoom, {.f = +1} },
- { MODKEY|ShiftMask, XK_Next, xzoom, {.f = -1} },
- { MODKEY|ShiftMask, XK_Home, xzoomreset, {.f = 0} },
+ { MODKEY|ShiftMask, XK_Prior, zoom, {.f = +1} },
+ { MODKEY|ShiftMask, XK_Next, zoom, {.f = -1} },
+ { MODKEY|ShiftMask, XK_Home, zoomreset, {.f = 0} },
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
{ MODKEY|ShiftMask, XK_Insert, clippaste, {.i = 0} },
{ MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} },
@@ -222,7 +222,7 @@ static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
* Note that if you want to use ShiftMask with selmasks, set this to an other
* modifier, set to 0 to not use it.
*/
-static uint forceselmod = ShiftMask;
+uint forceselmod = ShiftMask;
/*
* This is the huge key array which defines all compatibility to the Linux
@@ -451,7 +451,7 @@ static Key key[] = {
* ButtonRelease and MotionNotify.
* If no match is found, regular selection is used.
*/
-static uint selmasks[] = {
+uint selmasks[] = {
[SEL_RECTANGULAR] = Mod1Mask,
};
@@ -459,7 +459,7 @@ static uint selmasks[] = {
* Printable characters in ASCII, used to estimate the advance width
* of single wide characters.
*/
-static char ascii_printable[] =
+char ascii_printable[] =
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~";
diff --git a/st.c b/st.c
index fbcd9e0..1e4196e 100644
--- a/st.c
+++ b/st.c
@@ -21,23 +21,21 @@
#include <time.h>
#include <unistd.h>
#include <libgen.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/Xft/Xft.h>
-#include <X11/XKBlib.h>
#include <fontconfig/fontconfig.h>
#include <wchar.h>
-#include "arg.h"
+/* X11 */
+#include <X11/cursorfont.h>
+#include <X11/Xft/Xft.h>
char *argv0;
#define Glyph Glyph_
#define Font Font_
+#include "win.h"
+#include "st.h"
+
#if defined(__linux)
#include <pty.h>
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
@@ -46,67 +44,24 @@ char *argv0;
#include <libutil.h>
#endif
-
-/* XEMBED messages */
-#define XEMBED_FOCUS_IN 4
-#define XEMBED_FOCUS_OUT 5
-
/* Arbitrary sizes */
#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
#define ESC_BUF_SIZ (128*UTF_SIZ)
#define ESC_ARG_SIZ 16
#define STR_BUF_SIZ ESC_BUF_SIZ
#define STR_ARG_SIZ ESC_ARG_SIZ
-#define XK_ANY_MOD UINT_MAX
-#define XK_NO_MOD 0
-#define XK_SWITCH_MOD (1<<13)
/* macros */
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define MAX(a, b) ((a) < (b) ? (b) : (a))
-#define LEN(a) (sizeof(a) / sizeof(a)[0])
#define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
-#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
-#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL)
-#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
-#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \
- (a).bg != (b).bg)
-#define IS_SET(flag) ((term.mode & (flag)) != 0)
-#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
- (t1.tv_nsec-t2.tv_nsec)/1E6)
-#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
-
-#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
-#define IS_TRUECOL(x) (1 << 24 & (x))
-#define TRUERED(x) (((x) & 0xff0000) >> 8)
-#define TRUEGREEN(x) (((x) & 0xff00))
-#define TRUEBLUE(x) (((x) & 0xff) << 8)
/* constants */
#define ISO14755CMD "dmenu -w %lu -p codepoint: </dev/null"
-enum glyph_attribute {
- ATTR_NULL = 0,
- ATTR_BOLD = 1 << 0,
- ATTR_FAINT = 1 << 1,
- ATTR_ITALIC = 1 << 2,
- ATTR_UNDERLINE = 1 << 3,
- ATTR_BLINK = 1 << 4,
- ATTR_REVERSE = 1 << 5,
- ATTR_INVISIBLE = 1 << 6,
- ATTR_STRUCK = 1 << 7,
- ATTR_WRAP = 1 << 8,
- ATTR_WIDE = 1 << 9,
- ATTR_WDUMMY = 1 << 10,
- ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
-};
-
enum cursor_movement {
CURSOR_SAVE,
CURSOR_LOAD
@@ -118,34 +73,6 @@ enum cursor_state {
CURSOR_ORIGIN = 2
};
-enum term_mode {
- MODE_WRAP = 1 << 0,
- MODE_INSERT = 1 << 1,
- MODE_APPKEYPAD = 1 << 2,
- MODE_ALTSCREEN = 1 << 3,
- MODE_CRLF = 1 << 4,
- MODE_MOUSEBTN = 1 << 5,
- MODE_MOUSEMOTION = 1 << 6,
- MODE_REVERSE = 1 << 7,
- MODE_KBDLOCK = 1 << 8,
- MODE_HIDE = 1 << 9,
- MODE_ECHO = 1 << 10,
- MODE_APPCURSOR = 1 << 11,
- MODE_MOUSESGR = 1 << 12,
- MODE_8BIT = 1 << 13,
- MODE_BLINK = 1 << 14,
- MODE_FBLINK = 1 << 15,
- MODE_FOCUS = 1 << 16,
- MODE_MOUSEX10 = 1 << 17,
- MODE_MOUSEMANY = 1 << 18,
- MODE_BRCKTPASTE = 1 << 19,
- MODE_PRINT = 1 << 20,
- MODE_UTF8 = 1 << 21,
- MODE_SIXEL = 1 << 22,
- MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
- |MODE_MOUSEMANY,
-};
-
enum charset {
CS_GRAPHIC0,
CS_GRAPHIC1,
@@ -167,53 +94,6 @@ enum escape_state {
ESC_DCS =128,
};
-enum window_state {
- WIN_VISIBLE = 1,
- WIN_FOCUSED = 2
-};
-
-enum selection_mode {
- SEL_IDLE = 0,
- SEL_EMPTY = 1,
- SEL_READY = 2
-};
-
-enum selection_type {
- SEL_REGULAR = 1,
- SEL_RECTANGULAR = 2
-};
-
-enum selection_snap {
- SNAP_WORD = 1,
- SNAP_LINE = 2
-};
-
-typedef unsigned char uchar;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-typedef unsigned short ushort;
-
-typedef uint_least32_t Rune;
-
-typedef XftDraw *Draw;
-typedef XftColor Color;
-
-typedef struct {
- Rune u; /* character code */
- ushort mode; /* attribute flags */
- uint32_t fg; /* foreground */
- uint32_t bg; /* background */
-} Glyph;
-
-typedef Glyph *Line;
-
-typedef struct {
- Glyph attr; /* current char attributes */
- int x;
- int y;
- char state;
-} TCursor;
-
/* CSI Escape sequence structs */
/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
typedef struct {
@@ -235,56 +115,6 @@ typedef struct {
int narg; /* nb of args */
} STREscape;
-/* Internal representation of the screen */
-typedef struct {
- int row; /* nb row */
- int col; /* nb col */
- Line *line; /* screen */
- Line *alt; /* alternate screen */
- int *dirty; /* dirtyness of lines */
- XftGlyphFontSpec *specbuf; /* font spec buffer used for rendering */
- TCursor c; /* cursor */
- int top; /* top scroll limit */
- int bot; /* bottom scroll limit */
- int mode; /* terminal mode flags */
- int esc; /* escape state flags */
- char trantbl[4]; /* charset table translation */
- int charset; /* current charset */
- int icharset; /* selected charset for sequence */
- int numlock; /* lock numbers in keyboard */
- int *tabs;
-} Term;
-
-/* Purely graphic info */
-typedef struct {
- Display *dpy;
- Colormap cmap;
- Window win;
- Drawable buf;
- Atom xembed, wmdeletewin, netwmname, netwmpid;
- XIM xim;
- XIC xic;
- Draw draw;
- Visual *vis;
- XSetWindowAttributes attrs;
- int scr;
- int isfixed; /* is fixed geometry? */
- int l, t; /* left and top offset */
- int gm; /* geometry mask */
- int tw, th; /* tty width and height */
- int w, h; /* window width and height */
- int ch; /* char height */
- int cw; /* char width */
- char state; /* focus, redraw, visible */
- int cursor; /* cursor style */
-} XWindow;
-
-typedef struct {
- uint b;
- uint mask;
- char *s;
-} MouseShortcut;
-
typedef struct {
KeySym k;
uint mask;
@@ -295,89 +125,26 @@ typedef struct {
signed char crlf; /* crlf mode */
} Key;
-typedef struct {
- int mode;
- int type;
- int snap;
- /*
- * Selection variables:
- * nb – normalized coordinates of the beginning of the selection
- * ne – normalized coordinates of the end of the selection
- * ob – original coordinates of the beginning of the selection
- * oe – original coordinates of the end of the selection
- */
- struct {
- int x, y;
- } nb, ne, ob, oe;
-
- char *primary, *clipboard;
- Atom xtarget;
- int alt;
- struct timespec tclick1;
- struct timespec tclick2;
-} Selection;
-
-typedef union {
- int i;
- uint ui;
- float f;
- const void *v;
-} Arg;
-
-typedef struct {
- uint mod;
- KeySym keysym;
- void (*func)(const Arg *);
- const Arg arg;
-} Shortcut;
-
/* function definitions used in config.h */
static void clipcopy(const Arg *);
static void clippaste(const Arg *);
static void numlock(const Arg *);
static void selpaste(const Arg *);
-static void xzoom(const Arg *);
-static void xzoomabs(const Arg *);
-static void xzoomreset(const Arg *);
+static void zoom(const Arg *);
+static void zoomabs(const Arg *);
+static void zoomreset(const Arg *);
static void printsel(const Arg *);
static void printscreen(const Arg *) ;
static void iso14755(const Arg *);
static void toggleprinter(const Arg *);
static void sendbreak(const Arg *);
-/* Config.h for applying patches and the configuration. */
+/* config.h for applying patches and the configuration. */
#include "config.h"
-/* Font structure */
-typedef struct {
- int height;
- int width;
- int ascent;
- int descent;
- int badslant;
- int badweight;
- short lbearing;
- short rbearing;
- XftFont *match;
- FcFontSet *set;
- FcPattern *pattern;
-} Font;
-
-/* Drawing Context */
-typedef struct {
- Color col[MAX(LEN(colorname), 256)];
- Font font, bfont, ifont, ibfont;
- GC gc;
-} DC;
-
-static void die(const char *, ...);
-static void draw(void);
-static void redraw(void);
-static void drawregion(int, int, int, int);
static void execsh(void);
static void stty(void);
static void sigchld(int);
-static void run(void);
static void csidump(void);
static void csihandle(void);
@@ -389,7 +156,6 @@ static void strhandle(void);
static void strparse(void);
static void strreset(void);
-static int tattrset(int);
static void tprinter(char *, size_t);
static void tdumpsel(void);
static void tdumpline(int);
@@ -403,7 +169,6 @@ static void tinsertblankline(int);
static int tlinelen(int);
static void tmoveto(int, int);
static void tmoveato(int, int);
-static void tnew(int, int);
static void tnewline(int);
static void tputtab(int);
static void tputc(Rune);
@@ -415,8 +180,6 @@ static void tsetattr(int *, int);
static void tsetchar(Rune, Glyph *, int, int);
static void tsetscroll(int, int);
static void tswapscreen(void);
-static void tsetdirt(int, int);
-static void tsetdirtattr(int);
static void tsetmode(int, int, int *, int);
static void tfulldirt(void);
static void techo(Rune);
@@ -425,151 +188,53 @@ static void tdectest(char );
static void tdefutf8(char);
static int32_t tdefcolor(int *, int *, int);
static void tdeftran(char);
-static inline int match(uint, uint);
-static void ttynew(void);
-static size_t ttyread(void);
-static void ttyresize(void);
-static void ttysend(char *, size_t);
-static void ttywrite(const char *, size_t);
static void tstrsequence(uchar);
-static inline ushort sixd_to_16bit(int);
-static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
-static void xdrawglyph(Glyph, int, int);
-static void xhints(void);
-static void xclear(int, int, int, int);
-static void xdrawcursor(void);
-static void xinit(void);
-static void xloadcols(void);
-static int xsetcolorname(int, const char *);
-static int xgeommasktogravity(int);
-static int xloadfont(Font *, FcPattern *);
-static void xloadfonts(char *, double);
-static void xsettitle(char *);
-static void xresettitle(void);
-static void xsetpointermotion(int);
-static void xseturgency(int);
-static void xsetsel(char *, Time);
-static void xunloadfont(Font *);
-static void xunloadfonts(void);
-static void xresize(int, int);
-
-static void expose(XEvent *);
-static void visibility(XEvent *);
-static void unmap(XEvent *);
-static char *kmap(KeySym, uint);
-static void kpress(XEvent *);
-static void cmessage(XEvent *);
-static void cresize(int, int);
-static void resize(XEvent *);
-static void focus(XEvent *);
-static void brelease(XEvent *);
-static void bpress(XEvent *);
-static void bmotion(XEvent *);
-static void propnotify(XEvent *);
-static void selnotify(XEvent *);
-static void selclear(XEvent *);
-static void selrequest(XEvent *);
-
-static void selinit(void);
-static void selnormalize(void);
-static inline int selected(int, int);
-static char *getsel(void);
-static void selcopy(Time);
static void selscroll(int, int);
static void selsnap(int *, int *, int);
-static int x2col(int);
-static int y2row(int);
-static void getbuttoninfo(XEvent *);
-static void mousereport(XEvent *);
-static size_t utf8decode(char *, Rune *, size_t);
static Rune utf8decodebyte(char, size_t *);
-static size_t utf8encode(Rune, char *);
static char utf8encodebyte(Rune, size_t);
static char *utf8strchr(char *s, Rune u);
static size_t utf8validate(Rune *, size_t);
static ssize_t xwrite(int, const char *, size_t);
-static void *xmalloc(size_t);
static void *xrealloc(void *, size_t);
-static char *xstrdup(char *);
-
-static void usage(void);
-
-static void (*handler[LASTEvent])(XEvent *) = {
- [KeyPress] = kpress,
- [ClientMessage] = cmessage,
- [ConfigureNotify] = resize,
- [VisibilityNotify] = visibility,
- [UnmapNotify] = unmap,
- [Expose] = expose,
- [FocusIn] = focus,
- [FocusOut] = focus,
- [MotionNotify] = bmotion,
- [ButtonPress] = bpress,
- [ButtonRelease] = brelease,
-/*
- * Uncomment if you want the selection to disappear when you select something
- * different in another window.
- */
-/* [SelectionClear] = selclear, */
- [SelectionNotify] = selnotify,
-/*
- * PropertyNotify is only turned on when there is some INCR transfer happening
- * for the selection retrieval.
- */
- [PropertyNotify] = propnotify,
- [SelectionRequest] = selrequest,
-};
/* Globals */
-static DC dc;
-static XWindow xw;
-static Term term;
+TermWindow win;
+Term term;
+Selection sel;
+int cmdfd;
+pid_t pid;
+char **opt_cmd = NULL;
+char *opt_class = NULL;
+char *opt_embed = NULL;
+char *opt_font = NULL;
+char *opt_io = NULL;
+char *opt_line = NULL;
+char *opt_name = NULL;
+char *opt_title = NULL;
+int oldbutton = 3; /* button event on startup: 3 = release */
+
static CSIEscape csiescseq;
static STREscape strescseq;
-static int cmdfd;
-static pid_t pid;
-static Selection sel;
static int iofd = 1;
-static char **opt_cmd = NULL;
-static char *opt_class = NULL;
-static char *opt_embed = NULL;
-static char *opt_font = NULL;
-static char *opt_io = NULL;
-static char *opt_line = NULL;
-static char *opt_name = NULL;
-static char *opt_title = NULL;
-static int oldbutton = 3; /* button event on startup: 3 = release */
-
-static char *usedfont = NULL;
-static double usedfontsize = 0;
-static double defaultfontsize = 0;
+
+char *usedfont = NULL;
+double usedfontsize = 0;
+double defaultfontsize = 0;
static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-/* Font Ring Cache */
-enum {
- FRC_NORMAL,
- FRC_ITALIC,
- FRC_BOLD,
- FRC_ITALICBOLD
-};
-
-typedef struct {
- XftFont *font;
- int flags;
- Rune unicodep;
-} Fontcache;
-
-/* Fontcache is an array now. A new font will be appended to the array. */
-static Fontcache frc[16];
-static int frclen = 0;
+/* config.h array lengths */
+size_t colornamelen = LEN(colorname);
+size_t mshortcutslen = LEN(mshortcuts);
+size_t shortcutslen = LEN(shortcuts);
+size_t selmaskslen = LEN(selmasks);
ssize_t
xwrite(int fd, const char *s, size_t len)
@@ -714,16 +379,13 @@ selinit(void)
sel.ob.x = -1;
sel.primary = NULL;
sel.clipboard = NULL;
- sel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
- if (sel.xtarget == None)
- sel.xtarget = XA_STRING;
}
int
x2col(int x)
{
x -= borderpx;
- x /= xw.cw;
+ x /= win.cw;
return LIMIT(x, 0, term.col-1);
}
@@ -732,7 +394,7 @@ int
y2row(int y)
{
y -= borderpx;
- y /= xw.ch;
+ y /= win.ch;
return LIMIT(y, 0, term.row-1);
}
@@ -867,141 +529,6 @@ selsnap(int *x, int *y, int direction)
}
}
-void
-getbuttoninfo(XEvent *e)
-{
- int type;
- uint state = e->xbutton.state & ~(Button1Mask | forceselmod);
-
- sel.alt = IS_SET(MODE_ALTSCREEN);
-
- sel.oe.x = x2col(e->xbutton.x);
- sel.oe.y = y2row(e->xbutton.y);
- selnormalize();
-
- sel.type = SEL_REGULAR;
- for (type = 1; type < LEN(selmasks); ++type) {
- if (match(selmasks[type], state)) {
- sel.type = type;
- break;
- }
- }
-}
-
-void
-mousereport(XEvent *e)
-{
- int x = x2col(e->xbutton.x), y = y2row(e->xbutton.y),
- button = e->xbutton.button, state = e->xbutton.state,
- len;
- char buf[40];
- static int ox, oy;
-
- /* from urxvt */
- if (e->xbutton.type == MotionNotify) {
- if (x == ox && y == oy)
- return;
- if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
- return;
- /* MOUSE_MOTION: no reporting if no button is pressed */
- if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
- return;
-
- button = oldbutton + 32;
- ox = x;
- oy = y;
- } else {
- if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) {
- button = 3;
- } else {
- button -= Button1;
- if (button >= 3)
- button += 64 - 3;
- }
- if (e->xbutton.type == ButtonPress) {
- oldbutton = button;
- ox = x;
- oy = y;
- } else if (e->xbutton.type == ButtonRelease) {
- oldbutton = 3;
- /* MODE_MOUSEX10: no button release reporting */
- if (IS_SET(MODE_MOUSEX10))
- return;
- if (button == 64 || button == 65)
- return;
- }
- }
-
- if (!IS_SET(MODE_MOUSEX10)) {
- button += ((state & ShiftMask ) ? 4 : 0)
- + ((state & Mod4Mask ) ? 8 : 0)
- + ((state & ControlMask) ? 16 : 0);
- }
-
- if (IS_SET(MODE_MOUSESGR)) {
- len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
- button, x+1, y+1,
- e->xbutton.type == ButtonRelease ? 'm' : 'M');
- } else if (x < 223 && y < 223) {
- len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
- 32+button, 32+x+1, 32+y+1);
- } else {
- return;
- }
-
- ttywrite(buf, len);
-}
-
-void
-bpress(XEvent *e)
-{
- struct timespec now;
- MouseShortcut *ms;
-
- if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
- mousereport(e);
- return;
- }
-
- for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
- if (e->xbutton.button == ms->b
- && match(ms->mask, e->xbutton.state)) {
- ttysend(ms->s, strlen(ms->s));
- return;
- }
- }
-
- if (e->xbutton.button == Button1) {
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- /* Clear previous selection, logically and visually. */
- selclear(NULL);
- sel.mode = SEL_EMPTY;
- sel.type = SEL_REGULAR;
- sel.oe.x = sel.ob.x = x2col(e->xbutton.x);
- sel.oe.y = sel.ob.y = y2row(e->xbutton.y);
-
- /*
- * If the user clicks below predefined timeouts specific
- * snapping behaviour is exposed.
- */
- if (TIMEDIFF(now, sel.tclick2) <= tripleclicktimeout) {
- sel.snap = SNAP_LINE;
- } else if (TIMEDIFF(now, sel.tclick1) <= doubleclicktimeout) {
- sel.snap = SNAP_WORD;
- } else {
- sel.snap = 0;
- }
- selnormalize();
-
- if (sel.snap != 0)
- sel.mode = SEL_READY;
- tsetdirt(sel.nb.y, sel.ne.y);
- sel.tclick2 = sel.tclick1;
- sel.tclick1 = now;
- }
-}
-
char *
getsel(void)
{
@@ -1057,148 +584,25 @@ getsel(void)
}
void
-selcopy(Time t)
-{
- xsetsel(getsel(), t);
-}
-
-void
-propnotify(XEvent *e)
-{
- XPropertyEvent *xpev;
- Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
-
- xpev = &e->xproperty;
- if (xpev->state == PropertyNewValue &&
- (xpev->atom == XA_PRIMARY ||
- xpev->atom == clipboard)) {
- selnotify(e);
- }
-}
-
-void
-selnotify(XEvent *e)
-{
- ulong nitems, ofs, rem;
- int format;
- uchar *data, *last, *repl;
- Atom type, incratom, property;
-
- incratom = XInternAtom(xw.dpy, "INCR", 0);
-
- ofs = 0;
- if (e->type == SelectionNotify) {
- property = e->xselection.property;
- } else if(e->type == PropertyNotify) {
- property = e->xproperty.atom;
- } else {
- return;
- }
- if (property == None)
- return;
-
- do {
- if (XGetWindowProperty(xw.dpy, xw.win, property, ofs,
- BUFSIZ/4, False, AnyPropertyType,
- &type, &format, &nitems, &rem,
- &data)) {
- fprintf(stderr, "Clipboard allocation failed\n");
- return;
- }
-
- if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
- /*
- * If there is some PropertyNotify with no data, then
- * this is the signal of the selection owner that all
- * data has been transferred. We won't need to receive
- * PropertyNotify events anymore.
- */
- MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
- &xw.attrs);
- }
-
- if (type == incratom) {
- /*
- * Activate the PropertyNotify events so we receive
- * when the selection owner does send us the next
- * chunk of data.
- */
- MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
- &xw.attrs);
-
- /*
- * Deleting the property is the transfer start signal.
- */
- XDeleteProperty(xw.dpy, xw.win, (int)property);
- continue;
- }
-
- /*
- * As seen in getsel:
- * Line endings are inconsistent in the terminal and GUI world
- * copy and pasting. When receiving some selection data,
- * replace all '\n' with '\r'.
- * FIXME: Fix the computer world.
- */
- repl = data;
- last = data + nitems * format / 8;
- while ((repl = memchr(repl, '\n', last - repl))) {
- *repl++ = '\r';
- }
-
- if (IS_SET(MODE_BRCKTPASTE) && ofs == 0)
- ttywrite("\033[200~", 6);
- ttysend((char *)data, nitems * format / 8);
- if (IS_SET(MODE_BRCKTPASTE) && rem == 0)
- ttywrite("\033[201~", 6);
- XFree(data);
- /* number of 32-bit chunks returned */
- ofs += nitems * format / 32;
- } while (rem > 0);
-
- /*
- * Deleting the property again tells the selection owner to send the
- * next data chunk in the property.
- */
- XDeleteProperty(xw.dpy, xw.win, (int)property);
-}
-
-void
selpaste(const Arg *dummy)
{
- XConvertSelection(xw.dpy, XA_PRIMARY, sel.xtarget, XA_PRIMARY,
- xw.win, CurrentTime);
+ xselpaste();
}
void
clipcopy(const Arg *dummy)
{
- Atom clipboard;
-
- if (sel.clipboard != NULL)
- free(sel.clipboard);
-
- if (sel.primary != NULL) {
- sel.clipboard = xstrdup(sel.primary);
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
- }
+ xclipcopy();
}
void
clippaste(const Arg *dummy)
{
- Atom clipboard;
-
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XConvertSelection(xw.dpy, clipboard, sel.xtarget, clipboard,
- xw.win, CurrentTime);
+ xclippaste();
}
void
-selclear(XEvent *e)
+selclear(void)
{
if (sel.ob.x == -1)
return;
@@ -1208,120 +612,6 @@ selclear(XEvent *e)
}
void
-selrequest(XEvent *e)
-{
- XSelectionRequestEvent *xsre;
- XSelectionEvent xev;
- Atom xa_targets, string, clipboard;
- char *seltext;
-
- xsre = (XSelectionRequestEvent *) e;
- xev.type = SelectionNotify;
- xev.requestor = xsre->requestor;
- xev.selection = xsre->selection;
- xev.target = xsre->target;
- xev.time = xsre->time;
- if (xsre->property == None)
- xsre->property = xsre->target;
-
- /* reject */
- xev.property = None;
-
- xa_targets = XInternAtom(xw.dpy, "TARGETS", 0);
- if (xsre->target == xa_targets) {
- /* respond with the supported type */
- string = sel.xtarget;
- XChangeProperty(xsre->display, xsre->requestor, xsre->property,
- XA_ATOM, 32, PropModeReplace,
- (uchar *) &string, 1);
- xev.property = xsre->property;
- } else if (xsre->target == sel.xtarget || xsre->target == XA_STRING) {
- /*
- * xith XA_STRING non ascii characters may be incorrect in the
- * requestor. It is not our problem, use utf8.
- */
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- if (xsre->selection == XA_PRIMARY) {
- seltext = sel.primary;
- } else if (xsre->selection == clipboard) {
- seltext = sel.clipboard;
- } else {
- fprintf(stderr,
- "Unhandled clipboard selection 0x%lx\n",
- xsre->selection);
- return;
- }
- if (seltext != NULL) {
- XChangeProperty(xsre->display, xsre->requestor,
- xsre->property, xsre->target,
- 8, PropModeReplace,
- (uchar *)seltext, strlen(seltext));
- xev.property = xsre->property;
- }
- }
-
- /* all done, send a notification to the listener */
- if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev))
- fprintf(stderr, "Error sending SelectionNotify event\n");
-}
-
-void
-xsetsel(char *str, Time t)
-{
- free(sel.primary);
- sel.primary = str;
-
- XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
- if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
- selclear(0);
-}
-
-void
-brelease(XEvent *e)
-{
- if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
- mousereport(e);
- return;
- }
-
- if (e->xbutton.button == Button2) {
- selpaste(NULL);
- } else if (e->xbutton.button == Button1) {
- if (sel.mode == SEL_READY) {
- getbuttoninfo(e);
- selcopy(e->xbutton.time);
- } else
- selclear(NULL);
- sel.mode = SEL_IDLE;
- tsetdirt(sel.nb.y, sel.ne.y);
- }
-}
-
-void
-bmotion(XEvent *e)
-{
- int oldey, oldex, oldsby, oldsey;
-
- if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
- mousereport(e);
- return;
- }
-
- if (!sel.mode)
- return;
-
- sel.mode = SEL_READY;
- oldey = sel.oe.y;
- oldex = sel.oe.x;
- oldsby = sel.nb.y;
- oldsey = sel.ne.y;
- getbuttoninfo(e);
-
- if (oldey != sel.oe.y || oldex != sel.oe.x)
- tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
-}
-
-void
die(const char *errstr, ...)
{
va_list ap;
@@ -1337,7 +627,6 @@ execsh(void)
{
char **args, *sh, *prog;
const struct passwd *pw;
- char buf[sizeof(long) * 8 + 1];
errno = 0;
if ((pw = getpwuid(getuid())) == NULL) {
@@ -1358,8 +647,6 @@ execsh(void)
prog = sh;
args = (opt_cmd) ? opt_cmd : (char *[]) {prog, NULL};