From: Mike Lowis Date: Wed, 28 Sep 2016 19:25:15 +0000 (-0400) Subject: added screen.c for abstracting the display representation of the content X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=56527d8c1684a82423815040bf89dcde8929a493;p=projs%2Ftide.git added screen.c for abstracting the display representation of the content --- diff --git a/Makefile b/Makefile index 56f78e1..702fb2e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ LDFLAGS = -L/opt/X11/lib -lX11 -lXft CFLAGS = --std=c99 -Wall -Wextra -I. -I/opt/X11/include -I/opt/local/include/freetype2 -I/usr/include/freetype2 -SRCS = xedit.c buf.c +SRCS = xedit.c buf.c screen.c OBJS = $(SRCS:.c=.o) TESTSRCS = tests/tests.c tests/buf.c TESTOBJS = $(TESTSRCS:.c=.o) @@ -19,6 +19,6 @@ unittests: $(TESTOBJS) clean: $(RM) edit unittests $(OBJS) $(TESTOBJS) -$(OBJS): edit.h +$(OBJS): edit.h Makefile .PHONY: all test diff --git a/edit.h b/edit.h index 9a60ae9..8c587f4 100644 --- a/edit.h +++ b/edit.h @@ -55,19 +55,18 @@ unsigned buf_byline(Buf* buf, unsigned pos, int count); /* Screen management functions *****************************************************************************/ - typedef struct { - unsigned off; unsigned len; - Rune cols[100]; + Rune cols[]; } Row; -typedef struct { - unsigned off; - unsigned nrows; - unsigned ncols; - Row rows[73]; -} ScreenBuf; +void screen_setsize(unsigned nrows, unsigned ncols); +void screen_getsize(unsigned* nrows, unsigned* ncols); +void screen_clear(void); +Row* screen_getrow(unsigned row); +void screen_clearrow(unsigned row); +void screen_setcell(unsigned row, unsigned col, Rune r); +Rune screen_getcell(unsigned row, unsigned col); /* Miscellaneous Functions *****************************************************************************/ diff --git a/screen.c b/screen.c new file mode 100644 index 0000000..c7179b1 --- /dev/null +++ b/screen.c @@ -0,0 +1,57 @@ +#include "edit.h" + +static unsigned FileOffset = 0; +static unsigned NumRows = 0; +static unsigned NumCols = 0; +static Row** Rows; + +void screen_setsize(unsigned nrows, unsigned ncols) +{ + if (Rows) free(Rows); + Rows = calloc(nrows, sizeof(Row*)); + for (unsigned i = 0; i < nrows; i++) + Rows[i] = calloc(1, sizeof(Row) + (ncols * sizeof(Rune))); + NumRows = nrows; + NumCols = ncols; +} + +void screen_getsize(unsigned* nrows, unsigned* ncols) +{ + *nrows = NumRows, *ncols = NumCols; +} + +void screen_clear(void) +{ + for (unsigned i = 0; i < NumRows; i++) + screen_clearrow(i); +} + +Row* screen_getrow(unsigned row) +{ + return (row < NumRows ? Rows[row] : NULL); +} + +void screen_clearrow(unsigned row) +{ + Row* scrrow = screen_getrow(row); + if (!scrrow) return; + for (unsigned i = 0; i < NumCols; i++) + scrrow->cols[i] = (Rune)' '; + scrrow->len = 0; +} + +void screen_setcell(unsigned row, unsigned col, Rune r) +{ + if (row >= NumRows || col >= NumCols) return; + Row* scrrow = screen_getrow(row); + scrrow->cols[col] = r; + if (col+1 >= scrrow->len) + scrrow->len = col+1; +} + +Rune screen_getcell(unsigned row, unsigned col) +{ + if (row >= NumRows || col >= NumCols) return 0; + Row* scrrow = screen_getrow(row); + return scrrow->cols[col]; +} diff --git a/xedit.c b/xedit.c index 5572b09..b482f5a 100644 --- a/xedit.c +++ b/xedit.c @@ -25,12 +25,8 @@ struct { } X; Buf Buffer; bool InsertMode = false; -ScreenBuf ScreenBuffer; - unsigned StartRow = 0; -unsigned EndRow = 0; unsigned CursorPos = 0; -unsigned LastDrawnPos = 0; void die(char* m) { fprintf(stderr, "dying, %s\n", m); @@ -113,8 +109,6 @@ static void deinit(void) { XCloseDisplay(X.display); } -#define StartRow (ScreenBuffer.off) - static void handle_key(XEvent* e) { int len; char buf[8]; @@ -144,25 +138,11 @@ static void handle_key(XEvent* e) { case XK_Down: StartRow = buf_byline(&Buffer, StartRow, 1); - //CursorPos = buf_byline(&Buffer, CursorPos, 1); - //if (buf_bol(&Buffer, CursorPos) > EndRow) - // EndRow++, StartRow = buf_byline(&Buffer, StartRow, 1); break; case XK_Up: StartRow = buf_byline(&Buffer, StartRow, -1); - //CursorPos = buf_byline(&Buffer, CursorPos, -1); - //if (CursorPos < StartRow) - // EndRow--, StartRow = buf_byline(&Buffer, StartRow, -1); break; - - //default: - // if (len == 0) - // continue; - // if (buf[0] == '\r') - // buf[0] = '\n'; - // utf8_decode_rune(&gev->key, (unsigned char *)buf, 8); - // break; } } @@ -175,10 +155,10 @@ static void handle_mousebtn(XEvent* e) { case Button3: /* Right Button */ break; case Button4: /* Wheel Up */ - StartRow = buf_byline(&Buffer, StartRow, -2); + StartRow = buf_byline(&Buffer, StartRow, -4); break; case Button5: /* Wheel Down */ - StartRow = buf_byline(&Buffer, StartRow, 2); + StartRow = buf_byline(&Buffer, StartRow, 4); break; } } @@ -202,10 +182,9 @@ static void handle_event(XEvent* e) { if (e->xconfigure.width != X.width || e->xconfigure.height != X.height) { X.width = e->xconfigure.width; X.height = e->xconfigure.height; - X.rows = X.height / X.font->height; - X.cols = X.width / X.font->max_advance_width; X.pixmap = XCreatePixmap(X.display, X.window, X.width, X.height, X.depth); X.xft = XftDrawCreate(X.display, X.pixmap, X.visual, X.colormap); + screen_setsize(X.width / X.font->max_advance_width, X.height / X.font->height); } break; @@ -232,19 +211,18 @@ static void redraw(void) { /* Update the screen buffer */ tstart = time_ms(); - LastDrawnPos = StartRow; - int csrx = 0, csry = 0; - for (int y = 0; y < 73; y++) { - ScreenBuffer.rows[y].off = LastDrawnPos; - ScreenBuffer.rows[y].len = 0; - for (int x = 0; x < 100; x++) { - if (CursorPos == LastDrawnPos) + unsigned nrows, ncols, pos = StartRow; + unsigned csrx = 0, csry = 0; + screen_getsize(&nrows,&ncols); + for (unsigned y = 1; y < nrows; y++) { + screen_clearrow(y); + for (unsigned x = 0; x < ncols; x++) { + if (CursorPos == pos) csrx = x, csry = y; - Rune r = buf_get(&Buffer, LastDrawnPos++); + Rune r = buf_get(&Buffer, pos++); if (r == '\n') { break; } if (r == '\t') { x += 4; break; } - ScreenBuffer.rows[y].cols[x] = r; - ScreenBuffer.rows[y].len++; + screen_setcell(y,x,r); } } printf("\nT1: %lu\n", time_ms() - tstart); @@ -256,74 +234,23 @@ static void redraw(void) { /* flush the screen buffer */ tstart = time_ms(); - for (int y = 0; y < 73; y++) - if (ScreenBuffer.rows[y].len > 0) - XftDrawString32(X.xft, &txtclr, X.font, 0, (y+2) * fheight, (FcChar32*)(ScreenBuffer.rows[y].cols), (ScreenBuffer.rows[y].len)); + for (unsigned y = 0; y < nrows; y++) { + Row* row = screen_getrow(y); + if (row->len > 0) + XftDrawString32(X.xft, &txtclr, X.font, 0, (y+2) * fheight, (FcChar32*)(row->cols), (row->len)); + } printf("T2: %lu\n", time_ms() - tstart); /* Place cursor on screen */ + Rune csrrune = screen_getcell(csry,csrx); XftDrawRect(X.xft, &txtclr, csrx * fwidth, (csry+1) * fheight + 3, fwidth, fheight); - XftDrawString32(X.xft, &bkgclr, X.font, csrx * fwidth, (csry+2) * fheight, (FcChar32*)&(ScreenBuffer.rows[csry].cols[csrx]), 1); + XftDrawString32(X.xft, &bkgclr, X.font, csrx * fwidth, (csry+2) * fheight, (FcChar32*)&(csrrune), 1); /* flush pixels to the screen */ tstart = time_ms(); XCopyArea(X.display, X.pixmap, X.window, X.gc, 0, 0, X.width, X.height, 0, 0); XFlush(X.display); printf("T3: %lu\n", time_ms() - tstart); - - //uint64_t tstart; - //printf("rows: %d, cols: %d\n", X.rows, X.cols); - - //tstart = time_ms(); - //int fheight = X.font->height; - //int fwidth = X.font->max_advance_width; - ///* Allocate the colors */ - //XftColor bkgclr = xftcolor(CLR_BASE03); - //XftColor gtrclr = xftcolor(CLR_BASE02); - //XftColor csrclr = xftcolor(CLR_BASE3); - //XftColor txtclr = xftcolor(CLR_BASE0); - ///* draw the background color */ - //XftDrawRect(X.xft, &bkgclr, 0, 0, X.width, X.height); - ///* draw the status background */ - //XftDrawRect(X.xft, >rclr, 0, 0, X.width, fheight); - //printf("\nT1: %lu\n", time_ms() - tstart); - - ///* Draw document text */ - //tstart = time_ms(); - //int x = 0, y = 2; - //for (LastDrawnPos = StartRow; LastDrawnPos < buf_end(&Buffer); LastDrawnPos++) { - // if (x * fwidth >= X.width) - // y++, x = 0; - // if (y * fheight >= X.height) - // break; - // FcChar32 ch = (FcChar32)buf_get(&Buffer, LastDrawnPos); - // XftColor *bgclr = &bkgclr, *fgclr = &txtclr; - // /* Draw the cursor background */ - // if (LastDrawnPos == CursorPos) { - // bgclr = &csrclr, fgclr = &bkgclr; - // if (InsertMode) - // fgclr = &txtclr, XftDrawRect(X.xft, bgclr, x * fwidth, ((y-1) * fheight) + 4, 1, fheight); - // else - // XftDrawRect(X.xft, bgclr, x * fwidth, ((y-1) * fheight) + 4, fwidth, fheight); - // } - // /* Draw the actual character */ - // if (ch == '\n') { y++, x = 0; continue; } - // if (ch == '\t') { x += TabWidth; continue; } - // XftDrawString32(X.xft, fgclr, X.font, x * fwidth, y * fheight, (FcChar32 *)&ch, 1); - // x++; - //} - //EndRow = buf_bol(&Buffer, LastDrawnPos-2); - //printf("T2: %lu\n", time_ms() - tstart); - - - //tstart = time_ms(); - ///* flush the pixels to the screen */ - //XCopyArea(X.display, X.pixmap, X.window, X.gc, 0, 0, X.width, X.height, 0, 0); - //printf("T3: %lu\n", time_ms() - tstart); - - //tstart = time_ms(); - //XFlush(X.display); - //printf("T4: %lu\n", time_ms() - tstart); } int main(int argc, char** argv) {