alot of renaming...
[k8sterm.git] / src / x11draw.c
blob9906bd0e89e503d44d976e685ccbd502a3fd49f8
1 static void k8t_DrawLine (K8Term *term, int x1, int x2, int scry, int lineno, int dontcopy) {
2 //fprintf(stderr, "%d: k8t_DrawLine: x1=%d; x2=%d; scry=%d; row:%d; lineno=%d\n", mclock_ticks(), x1, x2, scry, term->row, lineno);
3 if (term == NULL || scry < 0 || scry >= term->row) return;
4 if (scry == term->row-1 && term->cmdline.cmdMode != K8T_CMDMODE_NONE) { xdrawcmdline(term, &term->cmdline, scry); return; }
5 if (lineno < 0 || lineno >= term->linecount) {
6 k8t_DrawClear(term, 0, scry, term->col-1, scry);
7 k8t_DrawCopy(term, 0, scry, term->col, 1);
8 } else {
9 int ic, ib, ox, sl;
10 int stx, ex;
11 K8TGlyph base, new;
12 K8TLine l = term->line[lineno];
14 if (lineno < term->row && term->topline == 0) {
15 if (!term->dirty[lineno]) return;
16 if (!dontcopy) {
17 // fix 'dirty' flag for line
18 if (term->dirty[lineno]&0x02) {
19 // mark full line as dirty
20 stx = 0;
21 ex = term->col;
22 term->dirty[lineno] = 0;
23 } else {
24 term->dirty[lineno] = 0;
25 if (x1 > 0) for (int x = 0; x < x1; ++x) if (l[x].state&K8T_GLYPH_DIRTY) { term->dirty[lineno] = 1; break; }
26 if (!term->dirty[lineno] && x2 < term->col) for (int x = x2; x < term->col; ++x) if (l[x].state&K8T_GLYPH_DIRTY) { term->dirty[lineno] = 1; break; }
28 // find dirty region
29 for (stx = x1; stx < x2; ++stx) if (l[stx].state&K8T_GLYPH_DIRTY) break;
30 for (ex = x2; ex > stx; --ex) if (l[ex-1].state&K8T_GLYPH_DIRTY) break;
31 if (stx >= x2 || ex <= stx) return; // nothing to do
33 } else {
34 // 'dontcopy' means that the whole screen is dirty
35 stx = 0;
36 ex = term->col;
37 term->dirty[lineno] = 0;
39 } else {
40 //if (lineno < term->row) term->dirty[lineno] = 0;
41 stx = 0;
42 ex = term->col;
45 base = l[stx];
46 if (term->sel.bx != -1 && k8t_isSelected(term, stx, lineno)) base.attr ^= K8T_ATTR_REVERSE;
47 ic = ib = 0;
48 ox = stx;
49 //k8t_DrawClear(term, stx, scry, ex-1, scry); //k8: actually, we don't need this for good monospace fonts, so...
50 for (int x = stx; x < ex; ++x) {
51 new = l[x];
52 l[x].state &= ~K8T_GLYPH_DIRTY; //!
53 if (term->sel.bx != -1 && k8t_isSelected(term, x, lineno)) new.attr ^= K8T_ATTR_REVERSE;
54 if (ib > 0 && (K8T_ATTRCMP(base, new) || ib >= DRAW_BUF_SIZ-UTF_SIZ)) {
55 // flush k8t_Draw buffer
56 k8t_DrawString(term, term->drawbuf, &base, ox, scry, ic, ib);
57 ic = ib = 0;
59 if (ib == 0) { ox = x; base = new; }
60 sl = k8t_UTF8Size(new.c);
61 memcpy(term->drawbuf+ib, new.c, sl);
62 ib += sl;
63 ++ic;
65 if (ib > 0) k8t_DrawString(term, term->drawbuf, &base, ox, scry, ic, ib);
66 //k8t_DrawCopy(term, 0, scry, term->col, 1);
67 //if (term->c.y == lineno && term->c.x >= stx && term->c.x < ex) k8t_DrawCursor();
68 if (!dontcopy) k8t_DrawCopy(term, stx, scry, ex-stx, 1);
73 static void k8t_DrawRegion (K8Term *term, int x1, int y1, int x2, int y2, int forced) {
74 if (term != NULL) {
75 int fulldirty = 0;
77 term->justSwapped = 0;
79 if (!forced && (xw.state&K8T_WIN_VISIBLE) == 0) {
80 //dlogf("invisible");
81 lastDrawTime = term->lastDrawTime = 1;
82 term->wantRedraw = 1;
83 return;
86 if (y1 == 0 && y2 == term->row) {
87 fulldirty = 1;
88 for (int y = 0; y < y2; ++y) if (!(term->dirty[y]&0x02)) { fulldirty = 0; break; }
91 if (term->topline < term->row) {
92 for (int y = y1; y < y2; ++y) k8t_DrawLine(term, x1, x2, y+term->topline, y, fulldirty);
94 if (term->topline > 0) {
95 int scry = K8T_MIN(term->topline, term->row), y = term->row;
97 fulldirty = 1;
98 if (term->topline >= term->row) y += term->topline-term->row;
99 while (--scry >= 0) {
100 k8t_DrawLine(term, 0, term->col, scry, y, 0);
101 ++y;
104 if (fulldirty) k8t_DrawCopy(term, 0, 0, term->col, term->row);
105 k8t_DrawCursor(term);
106 xdrawTabBar();
107 //XFlush(xw.dpy);
108 lastDrawTime = term->lastDrawTime = mclock_ticks();
109 term->wantRedraw = 0;
114 static void k8t_Draw (K8Term *term, int forced) {
115 if (term != NULL) {
116 //fprintf(stderr, "k8t_Draw(%d) (%d)\n", forced, mclock_ticks());
117 k8t_DrawRegion(term, 0, 0, term->col, term->row, forced);