Working patched implementation of st
This commit is contained in:
parent
9846a56bd7
commit
b8616f7b15
10 changed files with 625 additions and 309 deletions
274
x.c
274
x.c
|
@ -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"
|
||||
|
@ -34,6 +35,7 @@ typedef struct {
|
|||
void (*func)(const Arg *);
|
||||
const Arg arg;
|
||||
uint release;
|
||||
int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
|
||||
} MouseShortcut;
|
||||
|
||||
typedef struct {
|
||||
|
@ -45,10 +47,23 @@ 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
|
||||
#define XK_SWITCH_MOD (1<<13|1<<14)
|
||||
#define XK_SWITCH_MOD (1<<13)
|
||||
|
||||
/* function definitions used in config.h */
|
||||
static void clipcopy(const Arg *);
|
||||
|
@ -93,7 +108,7 @@ typedef struct {
|
|||
Window win;
|
||||
Drawable buf;
|
||||
GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
|
||||
Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
|
||||
Atom xembed, wmdeletewin, netwmname, netwmpid;
|
||||
struct {
|
||||
XIM xim;
|
||||
XIC xic;
|
||||
|
@ -105,6 +120,7 @@ typedef struct {
|
|||
XSetWindowAttributes attrs;
|
||||
int scr;
|
||||
int isfixed; /* is fixed geometry? */
|
||||
int depth; /* bit depth */
|
||||
int l, t; /* left and top offset */
|
||||
int gm; /* geometry mask */
|
||||
} XWindow;
|
||||
|
@ -156,7 +172,7 @@ static void xresize(int, int);
|
|||
static void xhints(void);
|
||||
static int xloadcolor(int, const char *, Color *);
|
||||
static int xloadfont(Font *, FcPattern *);
|
||||
static void xloadfonts(const char *, double);
|
||||
static void xloadfonts(char *, double);
|
||||
static void xunloadfont(Font *);
|
||||
static void xunloadfonts(void);
|
||||
static void xsetenv(void);
|
||||
|
@ -243,6 +259,7 @@ static char *usedfont = NULL;
|
|||
static double usedfontsize = 0;
|
||||
static double defaultfontsize = 0;
|
||||
|
||||
static char *opt_alpha = NULL;
|
||||
static char *opt_class = NULL;
|
||||
static char **opt_cmd = NULL;
|
||||
static char *opt_embed = NULL;
|
||||
|
@ -252,7 +269,7 @@ static char *opt_line = NULL;
|
|||
static char *opt_name = NULL;
|
||||
static char *opt_title = NULL;
|
||||
|
||||
static uint buttons; /* bit field of pressed buttons */
|
||||
static int oldbutton = 3; /* button event on startup: 3 = release */
|
||||
|
||||
void
|
||||
clipcopy(const Arg *dummy)
|
||||
|
@ -364,68 +381,59 @@ mousesel(XEvent *e, int done)
|
|||
void
|
||||
mousereport(XEvent *e)
|
||||
{
|
||||
int len, btn, code;
|
||||
int x = evcol(e), y = evrow(e);
|
||||
int state = e->xbutton.state;
|
||||
int len, x = evcol(e), y = evrow(e),
|
||||
button = e->xbutton.button, state = e->xbutton.state;
|
||||
char buf[40];
|
||||
static int ox, oy;
|
||||
|
||||
if (e->type == MotionNotify) {
|
||||
/* from urxvt */
|
||||
if (e->xbutton.type == MotionNotify) {
|
||||
if (x == ox && y == oy)
|
||||
return;
|
||||
if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
|
||||
return;
|
||||
/* MODE_MOUSEMOTION: no reporting if no button is pressed */
|
||||
if (IS_SET(MODE_MOUSEMOTION) && buttons == 0)
|
||||
/* MOUSE_MOTION: no reporting if no button is pressed */
|
||||
if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
|
||||
return;
|
||||
/* Set btn to lowest-numbered pressed button, or 12 if no
|
||||
* buttons are pressed. */
|
||||
for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++)
|
||||
;
|
||||
code = 32;
|
||||
|
||||
button = oldbutton + 32;
|
||||
ox = x;
|
||||
oy = y;
|
||||
} else {
|
||||
btn = e->xbutton.button;
|
||||
/* Only buttons 1 through 11 can be encoded */
|
||||
if (btn < 1 || btn > 11)
|
||||
return;
|
||||
if (e->type == ButtonRelease) {
|
||||
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;
|
||||
/* Don't send release events for the scroll wheel */
|
||||
if (btn == 4 || btn == 5)
|
||||
if (button == 64 || button == 65)
|
||||
return;
|
||||
}
|
||||
code = 0;
|
||||
}
|
||||
|
||||
ox = x;
|
||||
oy = y;
|
||||
|
||||
/* Encode btn into code. If no button is pressed for a motion event in
|
||||
* MODE_MOUSEMANY, then encode it as a release. */
|
||||
if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12)
|
||||
code += 3;
|
||||
else if (btn >= 8)
|
||||
code += 128 + btn - 8;
|
||||
else if (btn >= 4)
|
||||
code += 64 + btn - 4;
|
||||
else
|
||||
code += btn - 1;
|
||||
|
||||
if (!IS_SET(MODE_MOUSEX10)) {
|
||||
code += ((state & ShiftMask ) ? 4 : 0)
|
||||
+ ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */
|
||||
+ ((state & ControlMask) ? 16 : 0);
|
||||
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",
|
||||
code, x+1, y+1,
|
||||
e->type == ButtonRelease ? 'm' : 'M');
|
||||
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+code, 32+x+1, 32+y+1);
|
||||
32+button, 32+x+1, 32+y+1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -455,6 +463,7 @@ mouseaction(XEvent *e, uint release)
|
|||
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
|
||||
if (ms->release == release &&
|
||||
ms->button == e->xbutton.button &&
|
||||
(!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
|
||||
(match(ms->mod, state) || /* exact or forced */
|
||||
match(ms->mod, state & ~forcemousemod))) {
|
||||
ms->func(&(ms->arg));
|
||||
|
@ -468,13 +477,9 @@ mouseaction(XEvent *e, uint release)
|
|||
void
|
||||
bpress(XEvent *e)
|
||||
{
|
||||
int btn = e->xbutton.button;
|
||||
struct timespec now;
|
||||
int snap;
|
||||
|
||||
if (1 <= btn && btn <= 11)
|
||||
buttons |= 1 << (btn-1);
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
|
@ -483,7 +488,7 @@ bpress(XEvent *e)
|
|||
if (mouseaction(e, 0))
|
||||
return;
|
||||
|
||||
if (btn == Button1) {
|
||||
if (e->xbutton.button == Button1) {
|
||||
/*
|
||||
* If the user clicks below predefined timeouts specific
|
||||
* snapping behaviour is exposed.
|
||||
|
@ -697,11 +702,6 @@ xsetsel(char *str)
|
|||
void
|
||||
brelease(XEvent *e)
|
||||
{
|
||||
int btn = e->xbutton.button;
|
||||
|
||||
if (1 <= btn && btn <= 11)
|
||||
buttons &= ~(1 << (btn-1));
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
|
@ -709,7 +709,7 @@ brelease(XEvent *e)
|
|||
|
||||
if (mouseaction(e, 1))
|
||||
return;
|
||||
if (btn == Button1)
|
||||
if (e->xbutton.button == Button1)
|
||||
mousesel(e, 1);
|
||||
}
|
||||
|
||||
|
@ -752,7 +752,7 @@ xresize(int col, int row)
|
|||
|
||||
XFreePixmap(xw.dpy, xw.buf);
|
||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||
DefaultDepth(xw.dpy, xw.scr));
|
||||
xw.depth);
|
||||
XftDrawChange(xw.draw, xw.buf);
|
||||
xclear(0, 0, win.w, win.h);
|
||||
|
||||
|
@ -812,28 +812,22 @@ xloadcols(void)
|
|||
else
|
||||
die("could not allocate color %d\n", i);
|
||||
}
|
||||
|
||||
/* set alpha value of bg color */
|
||||
if (opt_alpha)
|
||||
alpha = strtof(opt_alpha, NULL);
|
||||
dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha);
|
||||
dc.col[defaultbg].pixel &= 0x00FFFFFF;
|
||||
dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24;
|
||||
loaded = 1;
|
||||
}
|
||||
|
||||
int
|
||||
xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b)
|
||||
{
|
||||
if (!BETWEEN(x, 0, dc.collen - 1))
|
||||
return 1;
|
||||
|
||||
*r = dc.col[x].color.red >> 8;
|
||||
*g = dc.col[x].color.green >> 8;
|
||||
*b = dc.col[x].color.blue >> 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xsetcolorname(int x, const char *name)
|
||||
{
|
||||
Color ncolor;
|
||||
|
||||
if (!BETWEEN(x, 0, dc.collen - 1))
|
||||
if (!BETWEEN(x, 0, dc.collen))
|
||||
return 1;
|
||||
|
||||
if (!xloadcolor(x, name, &ncolor))
|
||||
|
@ -859,8 +853,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;
|
||||
|
||||
|
@ -981,7 +975,7 @@ xloadfont(Font *f, FcPattern *pattern)
|
|||
}
|
||||
|
||||
void
|
||||
xloadfonts(const char *fontstr, double fontsize)
|
||||
xloadfonts(char *fontstr, double fontsize)
|
||||
{
|
||||
FcPattern *pattern;
|
||||
double fontval;
|
||||
|
@ -989,7 +983,7 @@ xloadfonts(const char *fontstr, double fontsize)
|
|||
if (fontstr[0] == '-')
|
||||
pattern = XftXlfdParse(fontstr, False, False);
|
||||
else
|
||||
pattern = FcNameParse((const FcChar8 *)fontstr);
|
||||
pattern = FcNameParse((FcChar8 *)fontstr);
|
||||
|
||||
if (!pattern)
|
||||
die("can't open font %s\n", fontstr);
|
||||
|
@ -1134,11 +1128,21 @@ xinit(int cols, int rows)
|
|||
Window parent;
|
||||
pid_t thispid = getpid();
|
||||
XColor xmousefg, xmousebg;
|
||||
XWindowAttributes attr;
|
||||
XVisualInfo vis;
|
||||
|
||||
if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||
die("can't open display\n");
|
||||
xw.scr = XDefaultScreen(xw.dpy);
|
||||
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||
|
||||
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) {
|
||||
parent = XRootWindow(xw.dpy, xw.scr);
|
||||
xw.depth = 32;
|
||||
} else {
|
||||
XGetWindowAttributes(xw.dpy, parent, &attr);
|
||||
xw.depth = attr.depth;
|
||||
}
|
||||
|
||||
XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis);
|
||||
xw.vis = vis.visual;
|
||||
|
||||
/* font */
|
||||
if (!FcInit())
|
||||
|
@ -1148,7 +1152,7 @@ xinit(int cols, int rows)
|
|||
xloadfonts(usedfont, 0);
|
||||
|
||||
/* colors */
|
||||
xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||
xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
|
||||
xloadcols();
|
||||
|
||||
/* adjust fixed window geometry */
|
||||
|
@ -1168,19 +1172,15 @@ xinit(int cols, int rows)
|
|||
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
|
||||
xw.attrs.colormap = xw.cmap;
|
||||
|
||||
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
|
||||
parent = XRootWindow(xw.dpy, xw.scr);
|
||||
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
|
||||
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||
win.w, win.h, 0, xw.depth, InputOutput,
|
||||
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||
| CWEventMask | CWColormap, &xw.attrs);
|
||||
|
||||
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||
gcvalues.graphics_exposures = False;
|
||||
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
||||
&gcvalues);
|
||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||
DefaultDepth(xw.dpy, xw.scr));
|
||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
|
||||
dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);
|
||||
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||
|
||||
|
@ -1217,7 +1217,6 @@ xinit(int cols, int rows)
|
|||
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
|
||||
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
|
||||
xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
|
||||
xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False);
|
||||
XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
|
||||
|
||||
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
|
||||
|
@ -1493,12 +1492,12 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
|||
|
||||
/* Render underline and strikethrough. */
|
||||
if (base.mode & ATTR_UNDERLINE) {
|
||||
XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
|
||||
XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
|
||||
width, 1);
|
||||
}
|
||||
|
||||
if (base.mode & ATTR_STRUCK) {
|
||||
XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3,
|
||||
XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
|
||||
width, 1);
|
||||
}
|
||||
|
||||
|
@ -1611,29 +1610,14 @@ xsetenv(void)
|
|||
setenv("WINDOWID", buf, 1);
|
||||
}
|
||||
|
||||
void
|
||||
xseticontitle(char *p)
|
||||
{
|
||||
XTextProperty prop;
|
||||
DEFAULT(p, opt_title);
|
||||
|
||||
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
||||
&prop) != Success)
|
||||
return;
|
||||
XSetWMIconName(xw.dpy, xw.win, &prop);
|
||||
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname);
|
||||
XFree(prop.value);
|
||||
}
|
||||
|
||||
void
|
||||
xsettitle(char *p)
|
||||
{
|
||||
XTextProperty prop;
|
||||
DEFAULT(p, opt_title);
|
||||
|
||||
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
||||
&prop) != Success)
|
||||
return;
|
||||
Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
||||
&prop);
|
||||
XSetWMName(xw.dpy, xw.win, &prop);
|
||||
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
|
||||
XFree(prop.value);
|
||||
|
@ -1833,7 +1817,7 @@ void
|
|||
kpress(XEvent *ev)
|
||||
{
|
||||
XKeyEvent *e = &ev->xkey;
|
||||
KeySym ksym = NoSymbol;
|
||||
KeySym ksym;
|
||||
char buf[64], *customkey;
|
||||
int len;
|
||||
Rune c;
|
||||
|
@ -1843,12 +1827,15 @@ kpress(XEvent *ev)
|
|||
if (IS_SET(MODE_KBDLOCK))
|
||||
return;
|
||||
|
||||
if (xw.ime.xic) {
|
||||
if (xw.ime.xic)
|
||||
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
|
||||
if (status == XBufferOverflow)
|
||||
return;
|
||||
} else {
|
||||
else
|
||||
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
|
||||
if ( IS_SET(MODE_KBDSELECT) ) {
|
||||
if ( match(XK_NO_MOD, e->state) ||
|
||||
(XK_Shift_L | XK_Shift_R) & e->state )
|
||||
win.mode ^= trt_kbdselect(ksym, buf, len);
|
||||
return;
|
||||
}
|
||||
/* 1. shortcuts */
|
||||
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
|
||||
|
@ -2014,6 +2001,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)
|
||||
{
|
||||
|
@ -2027,6 +2067,14 @@ usage(void)
|
|||
" [stty_args ...]\n", argv0, argv0);
|
||||
}
|
||||
|
||||
void toggle_winmode(int flag) {
|
||||
win.mode ^= flag;
|
||||
}
|
||||
|
||||
void keyboard_select(const Arg *dummy) {
|
||||
win.mode ^= trt_kbdselect(-1, NULL, 0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -2038,6 +2086,9 @@ main(int argc, char *argv[])
|
|||
case 'a':
|
||||
allowaltscreen = 0;
|
||||
break;
|
||||
case 'A':
|
||||
opt_alpha = EARGF(usage());
|
||||
break;
|
||||
case 'c':
|
||||
opt_class = EARGF(usage());
|
||||
break;
|
||||
|
@ -2087,6 +2138,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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue