|
|
|
@@ -14,6 +14,7 @@
|
|
|
|
|
#include <X11/keysym.h>
|
|
|
|
|
#include <X11/Xft/Xft.h>
|
|
|
|
|
#include <X11/XKBlib.h>
|
|
|
|
|
#include <X11/Xresource.h>
|
|
|
|
|
|
|
|
|
|
char *argv0;
|
|
|
|
|
#include "arg.h"
|
|
|
|
@@ -45,6 +46,19 @@ typedef struct {
|
|
|
|
|
signed char appcursor; /* application cursor */
|
|
|
|
|
} Key;
|
|
|
|
|
|
|
|
|
|
/* Xresources preferences */
|
|
|
|
|
enum resource_type {
|
|
|
|
|
STRING = 0,
|
|
|
|
|
INTEGER = 1,
|
|
|
|
|
FLOAT = 2
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
char *name;
|
|
|
|
|
enum resource_type type;
|
|
|
|
|
void *dst;
|
|
|
|
|
} ResourcePref;
|
|
|
|
|
|
|
|
|
|
/* X modifiers */
|
|
|
|
|
#define XK_ANY_MOD UINT_MAX
|
|
|
|
|
#define XK_NO_MOD 0
|
|
|
|
@@ -81,7 +95,6 @@ typedef XftGlyphFontSpec GlyphFontSpec;
|
|
|
|
|
typedef struct {
|
|
|
|
|
int tw, th; /* tty width and height */
|
|
|
|
|
int w, h; /* window width and height */
|
|
|
|
|
int hborderpx, vborderpx;
|
|
|
|
|
int ch; /* char height */
|
|
|
|
|
int cw; /* char width */
|
|
|
|
|
int mode; /* window state/mode flags */
|
|
|
|
@@ -332,7 +345,7 @@ ttysend(const Arg *arg)
|
|
|
|
|
int
|
|
|
|
|
evcol(XEvent *e)
|
|
|
|
|
{
|
|
|
|
|
int x = e->xbutton.x - win.hborderpx;
|
|
|
|
|
int x = e->xbutton.x - borderpx;
|
|
|
|
|
LIMIT(x, 0, win.tw - 1);
|
|
|
|
|
return x / win.cw;
|
|
|
|
|
}
|
|
|
|
@@ -340,7 +353,7 @@ evcol(XEvent *e)
|
|
|
|
|
int
|
|
|
|
|
evrow(XEvent *e)
|
|
|
|
|
{
|
|
|
|
|
int y = e->xbutton.y - win.vborderpx;
|
|
|
|
|
int y = e->xbutton.y - borderpx;
|
|
|
|
|
LIMIT(y, 0, win.th - 1);
|
|
|
|
|
return y / win.ch;
|
|
|
|
|
}
|
|
|
|
@@ -740,9 +753,6 @@ cresize(int width, int height)
|
|
|
|
|
col = MAX(1, col);
|
|
|
|
|
row = MAX(1, row);
|
|
|
|
|
|
|
|
|
|
win.hborderpx = (win.w - col * win.cw) / 2;
|
|
|
|
|
win.vborderpx = (win.h - row * win.ch) / 2;
|
|
|
|
|
|
|
|
|
|
tresize(col, row);
|
|
|
|
|
xresize(col, row);
|
|
|
|
|
ttyresize(win.tw, win.th);
|
|
|
|
@@ -863,8 +873,8 @@ xclear(int x1, int y1, int x2, int y2)
|
|
|
|
|
void
|
|
|
|
|
xhints(void)
|
|
|
|
|
{
|
|
|
|
|
XClassHint class = {opt_name ? opt_name : termname,
|
|
|
|
|
opt_class ? opt_class : termname};
|
|
|
|
|
XClassHint class = {opt_name ? opt_name : "st",
|
|
|
|
|
opt_class ? opt_class : "St"};
|
|
|
|
|
XWMHints wm = {.flags = InputHint, .input = 1};
|
|
|
|
|
XSizeHints *sizeh;
|
|
|
|
|
|
|
|
|
@@ -873,8 +883,8 @@ xhints(void)
|
|
|
|
|
sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
|
|
|
|
|
sizeh->height = win.h;
|
|
|
|
|
sizeh->width = win.w;
|
|
|
|
|
sizeh->height_inc = 1;
|
|
|
|
|
sizeh->width_inc = 1;
|
|
|
|
|
sizeh->height_inc = win.ch;
|
|
|
|
|
sizeh->width_inc = win.cw;
|
|
|
|
|
sizeh->base_height = 2 * borderpx;
|
|
|
|
|
sizeh->base_width = 2 * borderpx;
|
|
|
|
|
sizeh->min_height = win.ch + 2 * borderpx;
|
|
|
|
@@ -1139,8 +1149,6 @@ xinit(int cols, int rows)
|
|
|
|
|
pid_t thispid = getpid();
|
|
|
|
|
XColor xmousefg, xmousebg;
|
|
|
|
|
|
|
|
|
|
if (!(xw.dpy = XOpenDisplay(NULL)))
|
|
|
|
|
die("can't open display\n");
|
|
|
|
|
xw.scr = XDefaultScreen(xw.dpy);
|
|
|
|
|
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
|
|
|
|
|
|
|
|
@@ -1156,8 +1164,8 @@ xinit(int cols, int rows)
|
|
|
|
|
xloadcols();
|
|
|
|
|
|
|
|
|
|
/* adjust fixed window geometry */
|
|
|
|
|
win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw;
|
|
|
|
|
win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch;
|
|
|
|
|
win.w = 2 * borderpx + cols * win.cw;
|
|
|
|
|
win.h = 2 * borderpx + rows * win.ch;
|
|
|
|
|
if (xw.gm & XNegative)
|
|
|
|
|
xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
|
|
|
|
|
if (xw.gm & YNegative)
|
|
|
|
@@ -1246,7 +1254,7 @@ xinit(int cols, int rows)
|
|
|
|
|
int
|
|
|
|
|
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp;
|
|
|
|
|
float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
|
|
|
|
|
ushort mode, prevmode = USHRT_MAX;
|
|
|
|
|
Font *font = &dc.font;
|
|
|
|
|
int frcflags = FRC_NORMAL;
|
|
|
|
@@ -1379,7 +1387,7 @@ void
|
|
|
|
|
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
|
|
|
|
|
int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch,
|
|
|
|
|
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
|
|
|
|
|
width = charlen * win.cw;
|
|
|
|
|
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
|
|
|
|
XRenderColor colfg, colbg;
|
|
|
|
@@ -1469,17 +1477,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
|
|
|
|
|
|
|
|
|
/* Intelligent cleaning up of the borders. */
|
|
|
|
|
if (x == 0) {
|
|
|
|
|
xclear(0, (y == 0)? 0 : winy, win.hborderpx,
|
|
|
|
|
xclear(0, (y == 0)? 0 : winy, borderpx,
|
|
|
|
|
winy + win.ch +
|
|
|
|
|
((winy + win.ch >= win.vborderpx + win.th)? win.h : 0));
|
|
|
|
|
((winy + win.ch >= borderpx + win.th)? win.h : 0));
|
|
|
|
|
}
|
|
|
|
|
if (winx + width >= win.hborderpx + win.tw) {
|
|
|
|
|
if (winx + width >= borderpx + win.tw) {
|
|
|
|
|
xclear(winx + width, (y == 0)? 0 : winy, win.w,
|
|
|
|
|
((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch)));
|
|
|
|
|
((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
|
|
|
|
|
}
|
|
|
|
|
if (y == 0)
|
|
|
|
|
xclear(winx, 0, winx + width, win.vborderpx);
|
|
|
|
|
if (winy + win.ch >= win.vborderpx + win.th)
|
|
|
|
|
xclear(winx, 0, winx + width, borderpx);
|
|
|
|
|
if (winy + win.ch >= borderpx + win.th)
|
|
|
|
|
xclear(winx, winy + win.ch, winx + width, win.h);
|
|
|
|
|
|
|
|
|
|
/* Clean up the region we want to draw to. */
|
|
|
|
@@ -1573,35 +1581,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
|
|
|
|
case 3: /* Blinking Underline */
|
|
|
|
|
case 4: /* Steady Underline */
|
|
|
|
|
XftDrawRect(xw.draw, &drawcol,
|
|
|
|
|
win.hborderpx + cx * win.cw,
|
|
|
|
|
win.vborderpx + (cy + 1) * win.ch - \
|
|
|
|
|
borderpx + cx * win.cw,
|
|
|
|
|
borderpx + (cy + 1) * win.ch - \
|
|
|
|
|
cursorthickness,
|
|
|
|
|
win.cw, cursorthickness);
|
|
|
|
|
break;
|
|
|
|
|
case 5: /* Blinking bar */
|
|
|
|
|
case 6: /* Steady bar */
|
|
|
|
|
XftDrawRect(xw.draw, &drawcol,
|
|
|
|
|
win.hborderpx + cx * win.cw,
|
|
|
|
|
win.vborderpx + cy * win.ch,
|
|
|
|
|
borderpx + cx * win.cw,
|
|
|
|
|
borderpx + cy * win.ch,
|
|
|
|
|
cursorthickness, win.ch);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
XftDrawRect(xw.draw, &drawcol,
|
|
|
|
|
win.hborderpx + cx * win.cw,
|
|
|
|
|
win.vborderpx + cy * win.ch,
|
|
|
|
|
borderpx + cx * win.cw,
|
|
|
|
|
borderpx + cy * win.ch,
|
|
|
|
|
win.cw - 1, 1);
|
|
|
|
|
XftDrawRect(xw.draw, &drawcol,
|
|
|
|
|
win.hborderpx + cx * win.cw,
|
|
|
|
|
win.vborderpx + cy * win.ch,
|
|
|
|
|
borderpx + cx * win.cw,
|
|
|
|
|
borderpx + cy * win.ch,
|
|
|
|
|
1, win.ch - 1);
|
|
|
|
|
XftDrawRect(xw.draw, &drawcol,
|
|
|
|
|
win.hborderpx + (cx + 1) * win.cw - 1,
|
|
|
|
|
win.vborderpx + cy * win.ch,
|
|
|
|
|
borderpx + (cx + 1) * win.cw - 1,
|
|
|
|
|
borderpx + cy * win.ch,
|
|
|
|
|
1, win.ch - 1);
|
|
|
|
|
XftDrawRect(xw.draw, &drawcol,
|
|
|
|
|
win.hborderpx + cx * win.cw,
|
|
|
|
|
win.vborderpx + (cy + 1) * win.ch - 1,
|
|
|
|
|
borderpx + cx * win.cw,
|
|
|
|
|
borderpx + (cy + 1) * win.ch - 1,
|
|
|
|
|
win.cw, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -2018,6 +2026,59 @@ run(void)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
|
|
|
|
{
|
|
|
|
|
char **sdst = dst;
|
|
|
|
|
int *idst = dst;
|
|
|
|
|
float *fdst = dst;
|
|
|
|
|
|
|
|
|
|
char fullname[256];
|
|
|
|
|
char fullclass[256];
|
|
|
|
|
char *type;
|
|
|
|
|
XrmValue ret;
|
|
|
|
|
|
|
|
|
|
snprintf(fullname, sizeof(fullname), "%s.%s",
|
|
|
|
|
opt_name ? opt_name : "st", name);
|
|
|
|
|
snprintf(fullclass, sizeof(fullclass), "%s.%s",
|
|
|
|
|
opt_class ? opt_class : "St", name);
|
|
|
|
|
fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
XrmGetResource(db, fullname, fullclass, &type, &ret);
|
|
|
|
|
if (ret.addr == NULL || strncmp("String", type, 64))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
switch (rtype) {
|
|
|
|
|
case STRING:
|
|
|
|
|
*sdst = ret.addr;
|
|
|
|
|
break;
|
|
|
|
|
case INTEGER:
|
|
|
|
|
*idst = strtoul(ret.addr, NULL, 10);
|
|
|
|
|
break;
|
|
|
|
|
case FLOAT:
|
|
|
|
|
*fdst = strtof(ret.addr, NULL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
config_init(void)
|
|
|
|
|
{
|
|
|
|
|
char *resm;
|
|
|
|
|
XrmDatabase db;
|
|
|
|
|
ResourcePref *p;
|
|
|
|
|
|
|
|
|
|
XrmInitialize();
|
|
|
|
|
resm = XResourceManagerString(xw.dpy);
|
|
|
|
|
if (!resm)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
db = XrmGetStringDatabase(resm);
|
|
|
|
|
for (p = resources; p < resources + LEN(resources); p++)
|
|
|
|
|
resource_load(db, p->name, p->type, p->dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
usage(void)
|
|
|
|
|
{
|
|
|
|
@@ -2091,6 +2152,11 @@ run:
|
|
|
|
|
|
|
|
|
|
setlocale(LC_CTYPE, "");
|
|
|
|
|
XSetLocaleModifiers("");
|
|
|
|
|
|
|
|
|
|
if(!(xw.dpy = XOpenDisplay(NULL)))
|
|
|
|
|
die("Can't open display\n");
|
|
|
|
|
|
|
|
|
|
config_init();
|
|
|
|
|
cols = MAX(cols, 1);
|
|
|
|
|
rows = MAX(rows, 1);
|
|
|
|
|
tnew(cols, rows);
|
|
|
|
|