static char *argv0;
#include "arg.h"
-
-#define Glyph Glyph_
-#define Font Font_
-
#include "st.h"
#include "win.h"
typedef XftDraw *Draw;
typedef XftColor Color;
+typedef XftGlyphFontSpec GlyphFontSpec;
/* Purely graphic info */
typedef struct {
Colormap cmap;
Window win;
Drawable buf;
+ GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
Atom xembed, wmdeletewin, netwmname, netwmpid;
XIM xim;
XIC xic;
} XSelection;
/* Font structure */
+#define Font Font_
typedef struct {
int height;
int width;
static void xdrawcursor(void);
static int xgeommasktogravity(int);
static void xinit(void);
+static void cresize(int, int);
+static void xresize(int, int);
static int xloadfont(Font *, FcPattern *);
static void xloadfonts(char *, double);
static void xunloadfont(Font *);
static void xunloadfonts(void);
static void xsetenv(void);
static void xseturgency(int);
+static int x2col(int);
+static int y2row(int);
static void expose(XEvent *);
static void visibility(XEvent *);
static void selnotify(XEvent *);
static void selclear_(XEvent *);
static void selrequest(XEvent *);
-
static void selcopy(Time);
static void getbuttoninfo(XEvent *);
static void mousereport(XEvent *);
+static char *kmap(KeySym, uint);
+static int match(uint, uint);
static void run(void);
static void usage(void);
static XWindow xw;
static XSelection xsel;
+enum window_state {
+ WIN_VISIBLE = 1,
+ WIN_FOCUSED = 2
+};
+
/* Font Ring Cache */
enum {
FRC_NORMAL,
/* Fontcache is an array now. A new font will be appended to the array. */
static Fontcache frc[16];
static int frclen = 0;
+static char *usedfont = NULL;
+static double usedfontsize = 0;
+static double defaultfontsize = 0;
+
+static char *opt_class = NULL;
+static char **opt_cmd = 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;
void
zoom(const Arg *arg)
xunloadfonts();
xloadfonts(usedfont, arg->f);
cresize(0, 0);
- ttyresize();
+ ttyresize(win.tw, win.th);
redraw();
xhints();
}
}
}
+int
+x2col(int x)
+{
+ x -= borderpx;
+ x /= win.cw;
+
+ return LIMIT(x, 0, term.col-1);
+}
+
+int
+y2row(int y)
+{
+ y -= borderpx;
+ y /= win.ch;
+
+ return LIMIT(y, 0, term.row-1);
+}
+
void
getbuttoninfo(XEvent *e)
{
tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
}
+void
+cresize(int width, int height)
+{
+ int col, row;
+
+ if (width != 0)
+ win.w = width;
+ if (height != 0)
+ win.h = height;
+
+ col = (win.w - 2 * borderpx) / win.cw;
+ row = (win.h - 2 * borderpx) / win.ch;
+
+ tresize(col, row);
+ xresize(col, row);
+}
+
void
xresize(int col, int row)
{
DefaultDepth(xw.dpy, xw.scr));
XftDrawChange(xw.draw, xw.buf);
xclear(0, 0, win.w, win.h);
+
+ /* resize to new width */
+ xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
}
ushort
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
+ /* font spec buffer */
+ xw.specbuf = xmalloc(term.col * sizeof(GlyphFontSpec));
+
/* Xft rendering context */
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
xsettitle(char *p)
{
XTextProperty prop;
+ DEFAULT(p, "st");
Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
&prop);
term.dirty[y] = 0;
- specs = term.specbuf;
+ specs = xw.specbuf;
numspecs = xmakeglyphfontspecs(specs, &term.line[y][x1], x2 - x1, x1, y);
i = ox = 0;
}
}
+int
+match(uint mask, uint state)
+{
+ return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
+}
+
+char*
+kmap(KeySym k, uint state)
+{
+ Key *kp;
+ int i;
+
+ /* Check for mapped keys out of X11 function keys. */
+ for (i = 0; i < mappedkeyslen; i++) {
+ if (mappedkeys[i] == k)
+ break;
+ }
+ if (i == mappedkeyslen) {
+ if ((k & 0xFFFF) < 0xFD00)
+ return NULL;
+ }
+
+ for (kp = key; kp < key + keyslen; kp++) {
+ if (kp->k != k)
+ continue;
+
+ if (!match(kp->mask, state))
+ continue;
+
+ if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0)
+ continue;
+ if (term.numlock && kp->appkey == 2)
+ continue;
+
+ if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0)
+ continue;
+
+ if (IS_SET(MODE_CRLF) ? kp->crlf < 0 : kp->crlf > 0)
+ continue;
+
+ return kp->s;
+ }
+
+ return NULL;
+}
+
void
kpress(XEvent *ev)
{
return;
cresize(e->xconfigure.width, e->xconfigure.height);
- ttyresize();
+ ttyresize(win.tw, win.th);
}
void
} while (ev.type != MapNotify);
cresize(w, h);
- ttynew();
- ttyresize();
+ ttynew(opt_line, opt_io, opt_cmd);
+ ttyresize(win.tw, win.th);
clock_gettime(CLOCK_MONOTONIC, &last);
lastblink = last;