commit f6d2f18
uint
·
2026-05-13 22:46:16 +0000 UTC
parent 86883e9
add window resizing resizing windows also updates the pty viewarea
3 files changed,
+188,
-37
+126,
-37
1@@ -19,23 +19,21 @@
2 #include "term.h"
3 #include "utils.h"
4
5-#define WIDTH 800
6-#define HEIGHT 600
7-
8-#define COLS 80
9-#define ROWS 24
10+#define START_COLS 80
11+#define START_ROWS 24
12
13 static Fontface font;
14 static Caret car;
15 static RGFW_window* win = NULL;
16 static RGFW_surface* surf = NULL;
17 static uint32_t* pixels = NULL;
18+static int winw;
19+static int winh;
20
21-static Rune runes[COLS*ROWS]; /* TODO: dynamic */
22 static Term term = {
23- .runes = runes,
24- .cols = COLS,
25- .rows = ROWS,
26+ .runes = NULL,
27+ .cols = 0,
28+ .rows = 0,
29 .ptyfd = -1,
30 .ptypid = -1,
31 .fg = 0xffffffff,
32@@ -47,6 +45,9 @@ static void handle_key(RGFW_event ev);
33 static void init(void);
34 static void ptyread(void);
35 static void ptywrite(const char* s, size_t n);
36+static void resize_pty(void);
37+static int resize_surface(int w, int h);
38+static void resize_terminal(int w, int h);
39 static void run(void);
40
41 /**
42@@ -54,6 +55,7 @@ static void run(void);
43 */
44 static void cleanup(void)
45 {
46+ free(term.runes);
47 font_free(&font);
48
49 if (surf)
50@@ -104,12 +106,38 @@ static void handle_key(RGFW_event ev)
51 */
52 static void init(void)
53 {
54+ /* font */
55+ /* TODO: paths */
56+ if (font_load(&font, "./Xanh.ttf", 24.0) < 0)
57+ die(1, "failed to load font");
58+ font.aa = true;
59+
60+ winw = START_COLS*font.cellw;
61+ winh = START_ROWS*font.cellh;
62+
63+ if (term_resize(&term, &car, START_COLS, START_ROWS) < 0)
64+ die(1, "failed to resize terminal");
65+
66+ /* window */
67+ if (!(win = RGFW_createWindow("cterm", 0, 0, winw, winh, 0)))
68+ die(1, "failed to create window");
69+
70+ pixels = calloc(winw*winh, sizeof(*pixels));
71+ if (!pixels)
72+ die(1, "failed to alloc pixel buffer");
73+
74+ surf = RGFW_window_createSurface(
75+ win, (u8*)pixels, winw, winh, RGFW_formatRGBA8
76+ );
77+ if (!surf)
78+ die(1, "failed to create window surface");
79+
80 /* pty */
81 struct winsize ws = {
82- .ws_col = COLS,
83- .ws_row = ROWS,
84- .ws_xpixel = WIDTH,
85- .ws_ypixel = HEIGHT
86+ .ws_col = term.cols,
87+ .ws_row = term.rows,
88+ .ws_xpixel = winw,
89+ .ws_ypixel = winh
90 };
91 term.ptypid = forkpty(&term.ptyfd, NULL, NULL, &ws);
92 if (term.ptypid < 0)
93@@ -125,25 +153,6 @@ static void init(void)
94 if (flags >= 0) /* append to existing flags */
95 fcntl(term.ptyfd, F_SETFL, flags|O_NONBLOCK);
96
97- /* window */
98- if (!(win = RGFW_createWindow("cterm", 0, 0, 800, 600, 0)))
99- die(1, "failed to create window");
100-
101- pixels = calloc(WIDTH*HEIGHT, sizeof(*pixels));
102- if (!pixels)
103- die(1, "failed to alloc pixel buffer");
104-
105- surf = RGFW_window_createSurface(
106- win, (u8*)pixels, WIDTH, HEIGHT, RGFW_formatRGBA8
107- );
108- if (!surf)
109- die(1, "failed to create window surface");
110-
111- /* font */
112- /* TODO: paths */
113- if (font_load(&font, "./Xanh.ttf", 24.0) < 0)
114- die(1, "failed to load font");
115- font.aa = true;
116 term_clear(&term, &car);
117 }
118
119@@ -192,6 +201,78 @@ static void ptywrite(const char* s, size_t n)
120 }
121 }
122
123+/** TODO
124+ */
125+static void resize_pty(void)
126+{
127+ struct winsize ws = {
128+ .ws_col = term.cols,
129+ .ws_row = term.rows,
130+ .ws_xpixel = winw,
131+ .ws_ypixel = winh,
132+ };
133+
134+ if (term.ptyfd >= 0)
135+ ioctl(term.ptyfd, TIOCSWINSZ, &ws);
136+}
137+
138+/** TODO
139+ */
140+static int resize_surface(int w, int h)
141+{
142+ uint32_t* npixels;
143+ RGFW_surface* nsurf;
144+
145+ if (w < 1)
146+ w = 1;
147+ if (h < 1)
148+ h = 1;
149+
150+ npixels = calloc(w*h, sizeof(*npixels));
151+ if (!npixels)
152+ return -1;
153+
154+ nsurf = RGFW_window_createSurface(
155+ win, (u8*)npixels, w, h, RGFW_formatRGBA8
156+ );
157+ if (!nsurf) {
158+ free(npixels);
159+ return -1;
160+ }
161+
162+ if (surf)
163+ RGFW_surface_free(surf);
164+ free(pixels);
165+
166+ pixels = npixels;
167+ surf = nsurf;
168+ winw = w;
169+ winh = h;
170+
171+ return 0;
172+}
173+
174+/** TODO
175+ */
176+static void resize_terminal(int w, int h)
177+{
178+ int cols = w / font.cellw;
179+ int rows = h / font.cellh;
180+
181+ if (cols < 1)
182+ cols = 1;
183+ if (rows < 1)
184+ rows = 1;
185+
186+ if (cols == term.cols && rows == term.rows)
187+ return;
188+
189+ if (term_resize(&term, &car, cols, rows) < 0)
190+ die(1, "failed to resize terminal");
191+
192+ resize_pty();
193+}
194+
195 /**
196 * @brief program event loop (TODO)
197 */
198@@ -200,25 +281,33 @@ static void run(void)
199 RGFW_event ev;
200
201 while (!RGFW_window_shouldClose(win)) {
202- while (RGFW_window_checkEvent(win, &ev))
203+ while (RGFW_window_checkEvent(win, &ev)) {
204+ if (ev.type == RGFW_windowResized) {
205+ if (resize_surface(ev.update.w, ev.update.h) < 0)
206+ die(EXIT_FAILURE, "failed to resize surface");
207+ resize_terminal(ev.update.w, ev.update.h);
208+ continue;
209+ }
210+
211 handle_key(ev);
212+ }
213
214 ptyread();
215
216 /* drawing */
217- draw_clear(pixels, WIDTH, HEIGHT, rgba(0, 0, 0, 255));
218+ draw_clear(pixels, winw, winh, rgba(0, 0, 0, 255));
219 for (int y = 0; y < term.rows; y++) {
220 for (int x = 0; x < term.cols; x++) {
221 Rune* rune = &RUNE(&term, x, y);
222
223 draw_rune(
224- pixels, WIDTH, HEIGHT, x, y,
225+ pixels, winw, winh, x, y,
226 font.cellw, font.cellh, rune->bg
227 );
228
229 if (rune->cp != ' ') {
230 draw_codepoint(
231- &font, pixels, WIDTH, HEIGHT,
232+ &font, pixels, winw, winh,
233 x * font.cellw,
234 y * font.cellh + (int)font.asc,
235 rune->cp, rune->fg
236@@ -228,7 +317,7 @@ static void run(void)
237 }
238
239 draw_caret(
240- pixels, WIDTH, HEIGHT,
241+ pixels, winw, winh,
242 car.x, car.y,
243 font.cellw, font.cellh,
244 rgba(255, 255, 255, 255)
+4,
-0
1@@ -61,6 +61,10 @@ void term_clear(Term* t, Caret* c);
2 */
3 void term_putc(Term* t, Caret* c, uint32_t cp);
4
5+/** TODO
6+ */
7+int term_resize(Term* t, Caret* c, int cols, int rows);
8+
9 /**
10 * @brief scroll viewport up by one
11 *
+58,
-0
1@@ -1,4 +1,5 @@
2 #include <stdbool.h>
3+#include <stdlib.h>
4 #include <string.h>
5
6 #include <grapheme.h>
7@@ -251,6 +252,63 @@ void term_putc(Term* t, Caret* c, uint32_t cp)
8 }
9 }
10
11+int term_resize(Term* t, Caret* c, int cols, int rows)
12+{
13+ /* old */
14+ Rune* or = t->runes;
15+ int ocols = t->cols;
16+ int orows = t->rows;
17+
18+ if (cols < 1)
19+ cols = 1;
20+ if (rows < 1)
21+ rows = 1;
22+
23+ /* new */
24+ Rune* nr = calloc(cols*rows, sizeof(*nr));
25+ if (!nr)
26+ return -1;
27+
28+ for (int y = 0; y < rows; y++) {
29+ for (int x = 0; x < cols; x++) {
30+ Rune* r = &nr[y * cols + x];
31+ r->cp = ' ';
32+ r->fg = t->fg;
33+ r->bg = t->bg;
34+ r->dmg = true;
35+ }
36+ }
37+
38+ if (or) {
39+ int copyrows = orows < rows ? orows : rows;
40+ int copycols = ocols < cols ? ocols : cols;
41+
42+ for (int y = 0; y < copyrows; y++) {
43+ memcpy(
44+ &nr[y * cols], &or[y * ocols],
45+ sizeof(Rune) * copycols
46+ );
47+ }
48+ }
49+
50+ free(or);
51+
52+ t->runes = nr;
53+ t->cols = cols;
54+ t->rows = rows;
55+
56+ if (c->x >= cols)
57+ c->x = cols - 1;
58+ if (c->y >= rows)
59+ c->y = rows - 1;
60+ if (c->x < 0)
61+ c->x = 0;
62+ if (c->y < 0)
63+ c->y = 0;
64+
65+ return 0;
66+}
67+
68 void term_scroll(Term* t)
69 {
70 Rune* runes = t->runes;