Xinqi Bao's Git
projects
/
st.git
/ blobdiff
summary
|
log
|
commit
|
diff
|
tree
raw
|
inline
| side by side
Changing the license to MIT/X.
[st.git]
/
st.c
diff --git
a/st.c
b/st.c
index
5703e96
..
f063029
100644
(file)
--- a/
st.c
+++ b/
st.c
@@
-72,8
+72,6
@@
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
#define IS_SET(flag) (term.mode & (flag))
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000)
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
#define IS_SET(flag) (term.mode & (flag))
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000)
-#define X2COL(x) (((x) - BORDER)/xw.cw)
-#define Y2ROW(y) (((y) - BORDER)/xw.ch)
#define VT102ID "\033[?6c"
#define VT102ID "\033[?6c"
@@
-582,6
+580,22
@@
selinit(void) {
sel.xtarget = XA_STRING;
}
sel.xtarget = XA_STRING;
}
+static int
+x2col(int x) {
+ x -= borderpx;
+ x /= xw.cw;
+
+ return LIMIT(x, 0, term.col-1);
+}
+
+static int
+y2row(int y) {
+ y -= borderpx;
+ y /= xw.ch;
+
+ return LIMIT(y, 0, term.row-1);
+}
+
static inline bool
selected(int x, int y) {
int bx, ex;
static inline bool
selected(int x, int y) {
int bx, ex;
@@
-603,8
+617,9
@@
getbuttoninfo(XEvent *e, int *b, int *x, int *y) {
if(b)
*b = e->xbutton.button;
if(b)
*b = e->xbutton.button;
- *x = X2COL(e->xbutton.x);
- *y = Y2ROW(e->xbutton.y);
+ *x = x2col(e->xbutton.x);
+ *y = y2row(e->xbutton.y);
+
sel.b.x = sel.by < sel.ey ? sel.bx : sel.ex;
sel.b.y = MIN(sel.by, sel.ey);
sel.e.x = sel.by < sel.ey ? sel.ex : sel.bx;
sel.b.x = sel.by < sel.ey ? sel.bx : sel.ex;
sel.b.y = MIN(sel.by, sel.ey);
sel.e.x = sel.by < sel.ey ? sel.ex : sel.bx;
@@
-613,8
+628,8
@@
getbuttoninfo(XEvent *e, int *b, int *x, int *y) {
void
mousereport(XEvent *e) {
void
mousereport(XEvent *e) {
- int x =
X2COL
(e->xbutton.x);
- int y =
Y2ROW
(e->xbutton.y);
+ int x =
x2col
(e->xbutton.x);
+ int y =
y2row
(e->xbutton.y);
int button = e->xbutton.button;
int state = e->xbutton.state;
char buf[] = { '\033', '[', 'M', 0, 32+x+1, 32+y+1 };
int button = e->xbutton.button;
int state = e->xbutton.state;
char buf[] = { '\033', '[', 'M', 0, 32+x+1, 32+y+1 };
@@
-656,16
+671,16
@@
bpress(XEvent *e) {
draw();
}
sel.mode = 1;
draw();
}
sel.mode = 1;
- sel.ex = sel.bx =
X2COL
(e->xbutton.x);
- sel.ey = sel.by =
Y2ROW
(e->xbutton.y);
+ sel.ex = sel.bx =
x2col
(e->xbutton.x);
+ sel.ey = sel.by =
y2row
(e->xbutton.y);
}
}
void
selcopy(void) {
}
}
void
selcopy(void) {
- char *str, *ptr;
+ char *str, *ptr
, *p
;
int x, y, bufsize, is_selected = 0, size;
int x, y, bufsize, is_selected = 0, size;
- Glyph *gp;
+ Glyph *gp
, *last
;
if(sel.bx == -1) {
str = NULL;
if(sel.bx == -1) {
str = NULL;
@@
-675,15
+690,19
@@
selcopy(void) {
/* append every set & selected glyph to the selection */
for(y = 0; y < term.row; y++) {
/* append every set & selected glyph to the selection */
for(y = 0; y < term.row; y++) {
- for(x = 0; x < term.col; x++) {
- gp = &term.line[y][x];
+ gp = &term.line[y][0];
+ last = gp + term.col;
+
+ while(--last >= gp && !(last->state & GLYPH_SET))
+ /* nothing */;
- if(!(is_selected = selected(x, y))
- || !(gp->state & GLYPH_SET)) {
+ for(x = 0; gp <= last; x++, ++gp) {
+ if(!(is_selected = selected(x, y)))
continue;
continue;
- }
- size = utf8size(gp->c);
- memcpy(ptr, gp->c, size);
+
+ p = (gp->state & GLYPH_SET) ? gp->c : " ";
+ size = utf8size(p);
+ memcpy(ptr, p, size);
ptr += size;
}
/* \n at the end of every selected line except for the last one */
ptr += size;
}
/* \n at the end of every selected line except for the last one */
@@
-799,13
+818,13
@@
brelease(XEvent *e) {
sel.bx = -1;
gettimeofday(&now, NULL);
sel.bx = -1;
gettimeofday(&now, NULL);
- if(TIMEDIFF(now, sel.tclick2) <=
TRIPLECLICK_TIMEOUT
) {
+ if(TIMEDIFF(now, sel.tclick2) <=
tripleclicktimeout
) {
/* triple click on the line */
sel.b.x = sel.bx = 0;
sel.e.x = sel.ex = term.col;
sel.b.y = sel.e.y = sel.ey;
selcopy();
/* triple click on the line */
sel.b.x = sel.bx = 0;
sel.e.x = sel.ex = term.col;
sel.b.y = sel.e.y = sel.ey;
selcopy();
- } else if(TIMEDIFF(now, sel.tclick1) <=
DOUBLECLICK_TIMEOUT
) {
+ } else if(TIMEDIFF(now, sel.tclick1) <=
doubleclicktimeout
) {
/* double click to select word */
sel.bx = sel.ex;
while(sel.bx > 0 && term.line[sel.ey][sel.bx-1].state & GLYPH_SET &&
/* double click to select word */
sel.bx = sel.ex;
while(sel.bx > 0 && term.line[sel.ey][sel.bx-1].state & GLYPH_SET &&
@@
-890,8
+909,8
@@
execsh(void) {
signal(SIGTERM, SIG_DFL);
signal(SIGALRM, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGALRM, SIG_DFL);
- DEFAULT(envshell,
SHELL
);
-
putenv("TERM="TNAME
);
+ DEFAULT(envshell,
shell
);
+
setenv("TERM", termname, 1
);
args = opt_cmd ? opt_cmd : (char *[]){envshell, "-i", NULL};
execvp(args[0], args);
exit(EXIT_FAILURE);
args = opt_cmd ? opt_cmd : (char *[]){envshell, "-i", NULL};
execvp(args[0], args);
exit(EXIT_FAILURE);
@@
-1041,12
+1060,12
@@
treset(void) {
term.c = (TCursor){{
.mode = ATTR_NULL,
term.c = (TCursor){{
.mode = ATTR_NULL,
- .fg =
DefaultFG
,
- .bg =
DefaultBG
+ .fg =
defaultfg
,
+ .bg =
defaultbg
}, .x = 0, .y = 0, .state = CURSOR_DEFAULT};
memset(term.tabs, 0, term.col * sizeof(*term.tabs));
}, .x = 0, .y = 0, .state = CURSOR_DEFAULT};
memset(term.tabs, 0, term.col * sizeof(*term.tabs));
- for(i =
TAB; i < term.col; i += TAB
)
+ for(i =
tabspaces; i < term.col; i += tabspaces
)
term.tabs[i] = 1;
term.top = 0;
term.bot = term.row - 1;
term.tabs[i] = 1;
term.top = 0;
term.bot = term.row - 1;
@@
-1306,8
+1325,8
@@
tsetattr(int *attr, int l) {
case 0:
term.c.attr.mode &= ~(ATTR_REVERSE | ATTR_UNDERLINE | ATTR_BOLD \
| ATTR_ITALIC | ATTR_BLINK);
case 0:
term.c.attr.mode &= ~(ATTR_REVERSE | ATTR_UNDERLINE | ATTR_BOLD \
| ATTR_ITALIC | ATTR_BLINK);
- term.c.attr.fg =
DefaultFG
;
- term.c.attr.bg =
DefaultBG
;
+ term.c.attr.fg =
defaultfg
;
+ term.c.attr.bg =
defaultbg
;
break;
case 1:
term.c.attr.mode |= ATTR_BOLD;
break;
case 1:
term.c.attr.mode |= ATTR_BOLD;
@@
-1357,7
+1376,7
@@
tsetattr(int *attr, int l) {
}
break;
case 39:
}
break;
case 39:
- term.c.attr.fg =
DefaultFG
;
+ term.c.attr.fg =
defaultfg
;
break;
case 48:
if(i + 2 < l && attr[i + 1] == 5) {
break;
case 48:
if(i + 2 < l && attr[i + 1] == 5) {
@@
-1376,7
+1395,7
@@
tsetattr(int *attr, int l) {
}
break;
case 49:
}
break;
case 49:
- term.c.attr.bg =
DefaultBG
;
+ term.c.attr.bg =
defaultbg
;
break;
default:
if(BETWEEN(attr[i], 30, 37)) {
break;
default:
if(BETWEEN(attr[i], 30, 37)) {
@@
-2087,7
+2106,7
@@
tresize(int col, int row) {
memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
while(--bp > term.tabs && !*bp)
/* nothing */ ;
memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
while(--bp > term.tabs && !*bp)
/* nothing */ ;
- for(bp +=
TAB; bp < term.tabs + col; bp += TAB
)
+ for(bp +=
tabspaces; bp < term.tabs + col; bp += tabspaces
)
*bp = 1;
}
/* update terminal size */
*bp = 1;
}
/* update terminal size */
@@
-2103,8
+2122,8
@@
tresize(int col, int row) {
void
xresize(int col, int row) {
void
xresize(int col, int row) {
- xw.tw = MAX(1, 2*
BORDER
+ col * xw.cw);
- xw.th = MAX(1, 2*
BORDER
+ row * xw.ch);
+ xw.tw = MAX(1, 2*
borderpx
+ col * xw.cw);
+ xw.th = MAX(1, 2*
borderpx
+ row * xw.ch);
XftDrawChange(xw.xft_draw, xw.buf);
}
XftDrawChange(xw.xft_draw, xw.buf);
}
@@
-2150,9
+2169,9
@@
xloadcols(void) {
void
xtermclear(int col1, int row1, int col2, int row2) {
XftDrawRect(xw.xft_draw,
void
xtermclear(int col1, int row1, int col2, int row2) {
XftDrawRect(xw.xft_draw,
- &dc.xft_col[IS_SET(MODE_REVERSE) ?
DefaultFG : DefaultBG
],
-
BORDER
+ col1 * xw.cw,
-
BORDER
+ row1 * xw.ch,
+ &dc.xft_col[IS_SET(MODE_REVERSE) ?
defaultfg : defaultbg
],
+
borderpx
+ col1 * xw.cw,
+
borderpx
+ row1 * xw.ch,
(col2-col1+1) * xw.cw,
(row2-row1+1) * xw.ch);
}
(col2-col1+1) * xw.cw,
(row2-row1+1) * xw.ch);
}
@@
-2163,13
+2182,13
@@
xtermclear(int col1, int row1, int col2, int row2) {
void
xclear(int x1, int y1, int x2, int y2) {
XftDrawRect(xw.xft_draw,
void
xclear(int x1, int y1, int x2, int y2) {
XftDrawRect(xw.xft_draw,
- &dc.xft_col[IS_SET(MODE_REVERSE) ?
DefaultFG : DefaultBG
],
+ &dc.xft_col[IS_SET(MODE_REVERSE) ?
defaultfg : defaultbg
],
x1, y1, x2-x1, y2-y1);
}
void
xhints(void) {
x1, y1, x2-x1, y2-y1);
}
void
xhints(void) {
- XClassHint class = {opt_class ? opt_class :
TNAME, TNAME
};
+ XClassHint class = {opt_class ? opt_class :
termname, termname
};
XWMHints wm = {.flags = InputHint, .input = 1};
XSizeHints *sizeh = NULL;
XWMHints wm = {.flags = InputHint, .input = 1};
XSizeHints *sizeh = NULL;
@@
-2180,8
+2199,8
@@
xhints(void) {
sizeh->width = xw.w;
sizeh->height_inc = xw.ch;
sizeh->width_inc = xw.cw;
sizeh->width = xw.w;
sizeh->height_inc = xw.ch;
sizeh->width_inc = xw.cw;
- sizeh->base_height = 2*
BORDER
;
- sizeh->base_width = 2*
BORDER
;
+ sizeh->base_height = 2*
borderpx
;
+ sizeh->base_width = 2*
borderpx
;
} else {
sizeh->flags = PMaxSize | PMinSize;
sizeh->min_width = sizeh->max_width = xw.fw;
} else {
sizeh->flags = PMaxSize | PMinSize;
sizeh->min_width = sizeh->max_width = xw.fw;
@@
-2222,7
+2241,12
@@
xloadfonts(char *fontstr, int fontsize) {
FcResult result;
double fontval;
FcResult result;
double fontval;
- pattern = FcNameParse((FcChar8 *)fontstr);
+ if(fontstr[0] == '-') {
+ pattern = XftXlfdParse(fontstr, False, False);
+ } else {
+ pattern = FcNameParse((FcChar8 *)fontstr);
+ }
+
if(!pattern)
die("st: can't open font %s\n", fontstr);
if(!pattern)
die("st: can't open font %s\n", fontstr);
@@
-2289,7
+2313,7
@@
xinit(void) {
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
/* font */
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
/* font */
- usedfont = (opt_font == NULL)?
FONT
: opt_font;
+ usedfont = (opt_font == NULL)?
font
: opt_font;
xloadfonts(usedfont, 0);
/* colors */
xloadfonts(usedfont, 0);
/* colors */
@@
-2309,14
+2333,14
@@
xinit(void) {
xw.w = xw.fw;
} else {
/* window - default size */
xw.w = xw.fw;
} else {
/* window - default size */
- xw.h = 2*
BORDER
+ term.row * xw.ch;
- xw.w = 2*
BORDER
+ term.col * xw.cw;
+ xw.h = 2*
borderpx
+ term.row * xw.ch;
+ xw.w = 2*
borderpx
+ term.col * xw.cw;
xw.fx = 0;
xw.fy = 0;
}
xw.fx = 0;
xw.fy = 0;
}
- attrs.background_pixel = dc.xft_col[
DefaultBG
].pixel;
- attrs.border_pixel = dc.xft_col[
DefaultBG
].pixel;
+ attrs.background_pixel = dc.xft_col[
defaultbg
].pixel;
+ attrs.border_pixel = dc.xft_col[
defaultbg
].pixel;
attrs.bit_gravity = NorthWestGravity;
attrs.event_mask = FocusChangeMask | KeyPressMask
| ExposureMask | VisibilityChangeMask | StructureNotifyMask
attrs.bit_gravity = NorthWestGravity;
attrs.event_mask = FocusChangeMask | KeyPressMask
| ExposureMask | VisibilityChangeMask | StructureNotifyMask
@@
-2366,7
+2390,7
@@
xinit(void) {
void
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
void
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
- int winx =
BORDER + x * xw.cw, winy = BORDER
+ y * xw.ch,
+ int winx =
borderpx + x * xw.cw, winy = borderpx
+ y * xw.ch,
width = charlen * xw.cw;
Font *font = &dc.font;
XGlyphInfo extents;
width = charlen * xw.cw;
Font *font = &dc.font;
XGlyphInfo extents;
@@
-2374,9
+2398,6
@@
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
*temp, revfg, revbg;
XRenderColor colfg, colbg;
*temp, revfg, revbg;
XRenderColor colfg, colbg;
- if(base.mode & ATTR_REVERSE)
- temp = fg, fg = bg, bg = temp;
-
if(base.mode & ATTR_BOLD) {
if(BETWEEN(base.fg, 0, 7)) {
/* basic system colors */
if(base.mode & ATTR_BOLD) {
if(BETWEEN(base.fg, 0, 7)) {
/* basic system colors */
@@
-2399,12
+2420,12
@@
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
if(base.mode & ATTR_ITALIC)
font = &dc.ifont;
if(base.mode & ATTR_ITALIC)
font = &dc.ifont;
- if(
base.mode & (ATTR_ITALIC|ATTR_ITALIC
))
+ if(
(base.mode & ATTR_ITALIC) && (base.mode & ATTR_BOLD
))
font = &dc.ibfont;
if(IS_SET(MODE_REVERSE)) {
font = &dc.ibfont;
if(IS_SET(MODE_REVERSE)) {
- if(fg == &dc.xft_col[
DefaultFG
]) {
- fg = &dc.xft_col[
DefaultBG
];
+ if(fg == &dc.xft_col[
defaultfg
]) {
+ fg = &dc.xft_col[
defaultbg
];
} else {
colfg.red = ~fg->color.red;
colfg.green = ~fg->color.green;
} else {
colfg.red = ~fg->color.red;
colfg.green = ~fg->color.green;
@@
-2414,8
+2435,8
@@
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
fg = &revfg;
}
fg = &revfg;
}
- if(bg == &dc.xft_col[
DefaultBG
]) {
- bg = &dc.xft_col[
DefaultFG
];
+ if(bg == &dc.xft_col[
defaultbg
]) {
+ bg = &dc.xft_col[
defaultfg
];
} else {
colbg.red = ~bg->color.red;
colbg.green = ~bg->color.green;
} else {
colbg.red = ~bg->color.red;
colbg.green = ~bg->color.green;
@@
-2426,13
+2447,16
@@
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
}
}
}
}
+ if(base.mode & ATTR_REVERSE)
+ temp = fg, fg = bg, bg = temp;
+
XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen,
&extents);
width = extents.xOff;
/* Intelligent cleaning up of the borders. */
if(x == 0) {
XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen,
&extents);
width = extents.xOff;
/* Intelligent cleaning up of the borders. */
if(x == 0) {
- xclear(0, (y == 0)? 0 : winy,
BORDER
,
+ xclear(0, (y == 0)? 0 : winy,
borderpx
,
winy + xw.ch + (y == term.row-1)? xw.h : 0);
}
if(x + charlen >= term.col-1) {
winy + xw.ch + (y == term.row-1)? xw.h : 0);
}
if(x + charlen >= term.col-1) {
@@
-2440,7
+2464,7
@@
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
(y == term.row-1)? xw.h : (winy + xw.ch));
}
if(y == 0)
(y == term.row-1)? xw.h : (winy + xw.ch));
}
if(y == 0)
- xclear(winx, 0, winx + width,
BORDER
);
+ xclear(winx, 0, winx + width,
borderpx
);
if(y == term.row-1)
xclear(winx, winy + xw.ch, winx + width, xw.h);
if(y == term.row-1)
xclear(winx, winy + xw.ch, winx + width, xw.h);
@@
-2458,7
+2482,7
@@
void
xdrawcursor(void) {
static int oldx = 0, oldy = 0;
int sl;
xdrawcursor(void) {
static int oldx = 0, oldy = 0;
int sl;
- Glyph g = {{' '}, ATTR_NULL,
DefaultBG, DefaultCS
, 0};
+ Glyph g = {{' '}, ATTR_NULL,
defaultbg, defaultcs
, 0};
LIMIT(oldx, 0, term.col-1);
LIMIT(oldy, 0, term.row-1);
LIMIT(oldx, 0, term.col-1);
LIMIT(oldy, 0, term.row-1);
@@
-2478,10
+2502,10
@@
xdrawcursor(void) {
/* draw the new one */
if(!(term.c.state & CURSOR_HIDE)) {
if(!(xw.state & WIN_FOCUSED))
/* draw the new one */
if(!(term.c.state & CURSOR_HIDE)) {
if(!(xw.state & WIN_FOCUSED))
- g.bg =
DefaultUCS
;
+ g.bg =
defaultucs
;
if(IS_SET(MODE_REVERSE))
if(IS_SET(MODE_REVERSE))
- g.mode |= ATTR_REVERSE, g.fg =
DefaultCS, g.bg = DefaultFG
;
+ g.mode |= ATTR_REVERSE, g.fg =
defaultcs, g.bg = defaultfg
;
sl = utf8size(g.c);
xdraws(g.c, g, term.c.x, term.c.y, 1, sl);
sl = utf8size(g.c);
xdraws(g.c, g, term.c.x, term.c.y, 1, sl);
@@
-2598,9
+2622,11
@@
xseturgency(int add) {
void
focus(XEvent *ev) {
if(ev->type == FocusIn) {
void
focus(XEvent *ev) {
if(ev->type == FocusIn) {
+ XSetICFocus(xw.xic);
xw.state |= WIN_FOCUSED;
xseturgency(0);
} else {
xw.state |= WIN_FOCUSED;
xseturgency(0);
} else {
+ XUnsetICFocus(xw.xic);
xw.state &= ~WIN_FOCUSED;
}
}
xw.state &= ~WIN_FOCUSED;
}
}
@@
-2668,6
+2694,9
@@
kpress(XEvent *ev) {
selpaste();
break;
case XK_Return:
selpaste();
break;
case XK_Return:
+ if(meta)
+ ttywrite("\033", 1);
+
if(IS_SET(MODE_CRLF)) {
ttywrite("\r\n", 2);
} else {
if(IS_SET(MODE_CRLF)) {
ttywrite("\r\n", 2);
} else {
@@
-2714,10
+2743,8
@@
cresize(int width, int height)
if(height != 0)
xw.h = height;
if(height != 0)
xw.h = height;
- col = (xw.w - 2*BORDER) / xw.cw;
- row = (xw.h - 2*BORDER) / xw.ch;
- if(col == term.col && row == term.row)
- return;
+ col = (xw.w - 2*borderpx) / xw.cw;
+ row = (xw.h - 2*borderpx) / xw.ch;
tresize(col, row);
xresize(col, row);
tresize(col, row);
xresize(col, row);
@@
-2770,7
+2797,7
@@
run(void) {
while(XPending(xw.dpy)) {
XNextEvent(xw.dpy, &ev);
while(XPending(xw.dpy)) {
XNextEvent(xw.dpy, &ev);
- if(XFilterEvent(&ev,
xw.win
))
+ if(XFilterEvent(&ev,
None
))
continue;
if(handler[ev.type])
(handler[ev.type])(&ev);
continue;
if(handler[ev.type])
(handler[ev.type])(&ev);
@@
-2845,6
+2872,7
@@
main(int argc, char *argv[]) {
run:
setlocale(LC_CTYPE, "");
run:
setlocale(LC_CTYPE, "");
+ XSetLocaleModifiers("");
tnew(80, 24);
xinit();
ttynew();
tnew(80, 24);
xinit();
ttynew();