--- /dev/null
+#include <stdc.h>
+#include <utf.h>
+#include <edit.h>
+
+#define ATTR_NORMAL (CLR_BASE03 << 8 | CLR_BASE0)
+#define ATTR_SELECTED (CLR_BASE0 << 8 | CLR_BASE03)
+
+static void clearrow(View* view, size_t row) {
+ Row* scrrow = view_getrow(view, row);
+ if (!scrrow) return;
+ for (size_t i = 0; i < view->ncols; i++)
+ scrrow->cols[i].rune = (Rune)' ';
+ scrrow->rlen = 0;
+ scrrow->len = 0;
+}
+
+static size_t setcell(View* view, size_t row, size_t col, uint32_t attr, Rune r) {
+ if (row >= view->nrows || col >= view->ncols) return 0;
+ Row* scrrow = view_getrow(view, row);
+ int ncols = runewidth(col, r);
+ /* write the rune to the screen buf */
+ scrrow->cols[col].attr = attr;
+ if (r == '\t' || r == '\n' || r == RUNE_CRLF)
+ scrrow->cols[col].rune = ' ';
+ else
+ scrrow->cols[col].rune = r;
+ /* Update lengths */
+ scrrow->rlen += 1;
+ for (int i = 1; i < ncols; i++) {
+ scrrow->cols[col].attr = attr;
+ scrrow->cols[col+i].rune = '\0';
+ }
+ if ((col + ncols) > scrrow->len)
+ scrrow->len = col + ncols;
+ return ncols;
+}
+
+static bool selected(View* view, size_t pos) {
+ Sel sel = view->selection;
+ if (sel.end < sel.beg) {
+ size_t temp = sel.beg;
+ sel.beg = sel.end;
+ sel.end = temp;
+ }
+ return (sel.beg <= pos && pos < sel.end);
+}
+
+static size_t fill_row(View* view, unsigned row, size_t pos) {
+ view_getrow(view, row)->off = pos;
+ clearrow(view, row);
+ for (size_t x = 0; x < view->ncols;) {
+ uint32_t attr = (selected(view, pos) ? ATTR_SELECTED : ATTR_NORMAL);
+ Rune r = buf_get(&(view->buffer), pos++);
+ x += setcell(view, row, x, attr, r);
+ if (buf_iseol(&(view->buffer), pos-1)) break;
+ }
+ return pos;
+}
+
+static void reflow(View* view) {
+ size_t pos = view->rows[0]->off;
+ for (size_t y = 0; y < view->nrows; y++)
+ pos = fill_row(view, y, pos);
+}
+
+void view_init(View* view, char* file) {
+ memset(view, 0, sizeof(View));
+ buf_init(&(view->buffer));
+ if (file)
+ buf_load(&(view->buffer), file);
+}
+
+void view_resize(View* view, size_t nrows, size_t ncols) {
+ if (view->nrows == nrows && view->ncols == ncols) return;
+ /* free the old row data */
+ if (view->nrows) {
+ for (unsigned i = 0; i < view->nrows; i++)
+ free(view->rows[i]);
+ free(view->rows);
+ }
+ /* create the new row data */
+ view->rows = calloc(nrows, sizeof(Row*));
+ for (unsigned i = 0; i < nrows; i++)
+ view->rows[i] = calloc(1, sizeof(Row) + (ncols * sizeof(UGlyph)));
+ /* update dimensions */
+ view->nrows = nrows;
+ view->ncols = ncols;
+ /* populate the screen buffer */
+ reflow(view);
+}
+
+void view_update(View* view, size_t* csrx, size_t* csry) {
+ size_t csr = view->selection.beg;
+ /* scroll the view and reflow the screen lines */
+ //sync_view(buf, csr);
+ reflow(view);
+ /* find the cursor on the new screen */
+ for (size_t y = 0; y < view->nrows; y++) {
+ size_t start = view->rows[y]->off;
+ size_t end = view->rows[y]->off + view->rows[y]->rlen - 1;
+ if (start <= csr && csr <= end) {
+ size_t pos = start;
+ for (size_t x = 0; x < view->ncols;) {
+ if (pos == csr) {
+ *csry = y, *csrx = x;
+ break;
+ }
+ x += runewidth(x, buf_get(&(view->buffer),pos++));
+ }
+ break;
+ }
+ }
+}
+
+Row* view_getrow(View* view, size_t row) {
+ return (row < view->nrows ? view->rows[row] : NULL);
+}
+
+void view_byrune(View* view, int move) {
+ Sel sel = view->selection;
+ sel.beg = sel.end = buf_byrune(&(view->buffer), sel.end, move);
+ sel.col = buf_getcol(&(view->buffer), sel.end);
+ view->selection = sel;
+}
+
+void view_byline(View* view, int move) {
+ Sel sel = view->selection;
+ sel.beg = sel.end = buf_byline(&(view->buffer), sel.end, move);
+ sel.beg = sel.end = buf_setcol(&(view->buffer), sel.end, sel.col);
+ view->selection = sel;
+}
+
+
+//void view_update(View* view, size_t crsr, size_t* csrx, size_t* csry) {
+//
+//}
+//
+//size_t view_getoff(View* view, size_t pos, size_t row, size_t col) {
+// return 0;
+//}
+//
+//void view_setsize(View* view, size_t nrows, size_t ncols) {
+//
+//}
+//
+//void view_getsize(View* view, size_t* nrows, size_t* ncols) {
+//
+//}
+//
+//void view_clearrow(View* view, size_t row) {
+//
+//}
+//
+//size_t view_setcell(View* view, size_t row, size_t col, uint32_t attr, Rune r) {
+// return 0;
+//}
+//
+//UGlyph* view_getglyph(View* view, size_t row, size_t col, size_t* scrwidth) {
+// return NULL;
+//}
-#include <stdc.h>
-#include <X.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
+#include <X11/Xft/Xft.h>
+#include <x11.h>
+#include <stdc.h>
#include <utf.h>
#include <locale.h>
+#ifndef MAXFONTS
+#define MAXFONTS 16
+#endif
+
+struct XFont {
+ struct {
+ int height;
+ int width;
+ int ascent;
+ int descent;
+ XftFont* match;
+ FcFontSet* set;
+ FcPattern* pattern;
+ } base;
+ struct {
+ XftFont* font;
+ uint32_t unicodep;
+ } cache[MAXFONTS];
+ int ncached;
+};
+
static bool Running = true;
static struct {
Window root;
XCloseDisplay(X.display);
}
-void x11_draw_rect(int color, int x, int y, int width, int height) {
- XftColor clr;
- xftcolor(&clr, Config->palette[color]);
- XftDrawRect(X.xft, &clr, x, y, width, height);
- XftColorFree(X.display, X.visual, X.colormap, &clr);
-}
-
-void x11_getsize(int* width, int* height) {
- *width = X.width;
- *height = X.height;
-}
-
-void x11_font_load(XFont* font, char* name) {
+XFont x11_font_load(char* name) {
+ struct XFont* font = calloc(1, sizeof(struct XFont));
/* init the library and the base font pattern */
if (!FcInit())
die("Could not init fontconfig.\n");
font->base.height = font->base.ascent + font->base.descent;
font->base.width = ((extents.xOff + (sizeof(ascii) - 1)) / sizeof(ascii));
FcPatternDestroy(pattern);
+ return font;
+}
+
+size_t x11_font_height(XFont fnt) {
+ struct XFont* font = fnt;
+ return font->base.height;
+}
+
+size_t x11_font_width(XFont fnt) {
+ struct XFont* font = fnt;
+ return font->base.width;
+}
+
+size_t x11_font_descent(XFont fnt) {
+ struct XFont* font = fnt;
+ return font->base.descent;
+}
+
+void x11_draw_rect(int color, int x, int y, int width, int height) {
+ XftColor clr;
+ xftcolor(&clr, Config->palette[color]);
+ XftDrawRect(X.xft, &clr, x, y, width, height);
+ XftColorFree(X.display, X.visual, X.colormap, &clr);
}
-void x11_font_getglyph(XFont* font, XftGlyphFontSpec* spec, uint32_t rune) {
+void x11_font_getglyph(XFont fnt, XGlyphSpec* spec, uint32_t rune) {
+ struct XFont* font = fnt;
/* if the rune is in the base font, set it and return */
FT_UInt glyphidx = XftCharIndex(X.display, font->base.match, rune);
if (glyphidx) {
FcCharSetDestroy(fccharset);
}
-void x11_draw_glyphs(int fg, int bg, XftGlyphFontSpec* specs, size_t nspecs) {
- if (!nspecs) return;
- XftFont* font = specs[0].font;
- XftColor fgc, bgc;
- if (bg > 0) {
- XGlyphInfo extent;
- XftTextExtentsUtf8(X.display, font, (const FcChar8*)"0", 1, &extent);
- int w = extent.xOff;
- int h = (font->height - font->descent);
- xftcolor(&bgc, Config->palette[bg]);
- x11_draw_rect(bg, specs[0].x, specs[0].y - h, nspecs * w, font->height);
- XftColorFree(X.display, X.visual, X.colormap, &bgc);
- }
- xftcolor(&fgc, Config->palette[fg]);
- XftDrawGlyphFontSpec(X.xft, &fgc, specs, nspecs);
- XftColorFree(X.display, X.visual, X.colormap, &fgc);
-}
-
-size_t x11_font_getglyphs(XftGlyphFontSpec* specs, const XGlyph* glyphs, int len, XFont* font, int x, int y) {
+size_t x11_font_getglyphs(XGlyphSpec* specs, const XGlyph* glyphs, int len, XFont fnt, int x, int y) {
+ struct XFont* font = fnt;
int winx = x * font->base.width, winy = y * font->base.ascent;
size_t numspecs = 0;
for (int i = 0, xp = winx, yp = winy + font->base.ascent; i < len;) {
return numspecs;
}
-void x11_draw_utf8(XFont* font, int fg, int bg, int x, int y, char* str) {
- static XftGlyphFontSpec specs[256];
- size_t nspecs = 0;
- while (*str && nspecs < 256) {
- x11_font_getglyph(font, &(specs[nspecs]), *str);
- specs[nspecs].x = x;
- specs[nspecs].y = y;
- x += font->base.width;
- nspecs++;
- str++;
+void x11_draw_glyphs(int fg, int bg, XGlyphSpec* specs, size_t nspecs) {
+ if (!nspecs) return;
+ XftFont* font = specs[0].font;
+ XftColor fgc, bgc;
+ if (bg > 0) {
+ XGlyphInfo extent;
+ XftTextExtentsUtf8(X.display, font, (const FcChar8*)"0", 1, &extent);
+ int w = extent.xOff;
+ int h = (font->height - font->descent);
+ xftcolor(&bgc, Config->palette[bg]);
+ x11_draw_rect(bg, specs[0].x, specs[0].y - h, nspecs * w, font->height);
+ XftColorFree(X.display, X.visual, X.colormap, &bgc);
}
- x11_draw_glyphs(fg, bg, specs, nspecs);
+ xftcolor(&fgc, Config->palette[fg]);
+ XftDrawGlyphFontSpec(X.xft, &fgc, (XftGlyphFontSpec*)specs, nspecs);
+ XftColorFree(X.display, X.visual, X.colormap, &fgc);
}
-void x11_warp_mouse(int x, int y) {
- XWarpPointer(X.display, X.window, X.window, 0, 0, X.width, X.height, x, y);
-}
+//void x11_draw_utf8(XFont* font, int fg, int bg, int x, int y, char* str) {
+// static XftGlyphFontSpec specs[256];
+// size_t nspecs = 0;
+// while (*str && nspecs < 256) {
+// x11_font_getglyph(font, &(specs[nspecs]), *str);
+// specs[nspecs].x = x;
+// specs[nspecs].y = y;
+// x += font->base.width;
+// nspecs++;
+// str++;
+// }
+// x11_draw_glyphs(fg, bg, specs, nspecs);
+//}
+//
+//void x11_warp_mouse(int x, int y) {
+// XWarpPointer(X.display, X.window, X.window, 0, 0, X.width, X.height, x, y);
+//}
#include <stdc.h>
-#include <X.h>
+#include <x11.h>
#include <utf.h>
#include <edit.h>
#include <ctype.h>
/* Global Data
*****************************************************************************/
-Buf Buffer;
-Buf TagBuffer;
-unsigned TargetCol = 0;
-unsigned SelBeg = 0;
-unsigned SelEnd = 0;
-static unsigned ScrRows = 0;
-static unsigned ScrCols = 0;
+//Buf Buffer;
+//Buf TagBuffer;
+//unsigned TargetCol = 0;
+//unsigned SelBeg = 0;
+//unsigned SelEnd = 0;
+//static unsigned ScrRows = 0;
+//static unsigned ScrCols = 0;
+//static XFont Fonts;
+
static bool TagWinExpanded = false;
-static XFont Fonts;
+static View TagView;
+static View BufView;
+static View* Focused = &BufView;
+static XFont Font;
static XConfig Config = {
.redraw = redraw,
.handle_key = key_handler,
.palette = COLOR_PALETTE
};
-/* new view globals */
-static View TagView;
-static View EditView;
-static View* Active = &EditView;
+/* UI Callbacks
+ *****************************************************************************/
+static void cursor_up(void) {
+ view_byline(Focused, -1);
+}
+
+static void cursor_dn(void) {
+ view_byline(Focused, +1);
+}
+
+static void cursor_left(void) {
+ view_byrune(Focused, -1);
+}
+
+static void cursor_right(void) {
+ view_byrune(Focused, +1);
+}
+
+/* UI Callbacks
+ *****************************************************************************/
+static void mouse_handler(MouseAct act, MouseBtn btn, int x, int y) {
+
+}
+
+/* Keyboard Bindings
+ *****************************************************************************/
+typedef struct {
+ Rune key;
+ void (*action)(void);
+} KeyBinding_T;
+
+static KeyBinding_T Insert[] = {
+ { KEY_UP, cursor_up },
+ { KEY_DOWN, cursor_dn },
+ { KEY_LEFT, cursor_left },
+ { KEY_RIGHT, cursor_right },
+ //{ KEY_CTRL_Q, quit },
+ //{ KEY_CTRL_S, write },
+ //{ KEY_CTRL_T, tagwin },
+ //{ KEY_CTRL_Z, undo },
+ //{ KEY_CTRL_Y, redo },
+ //{ KEY_CTRL_X, cut },
+ //{ KEY_CTRL_C, copy },
+ //{ KEY_CTRL_V, paste },
+ //{ KEY_HOME, cursor_bol },
+ //{ KEY_END, cursor_eol },
+ //{ KEY_DELETE, delete },
+ //{ KEY_BACKSPACE, backspace },
+ { 0, NULL }
+};
+
+static void process_table(KeyBinding_T* bindings, Rune key) {
+ while (bindings->key) {
+ if (key == bindings->key) {
+ bindings->action();
+ return;
+ }
+ bindings++;
+ }
+ /* skip control and nonprintable characters */
+ if ((!isspace(key) && key < 0x20) ||
+ (key >= 0xE000 && key <= 0xF8FF))
+ return;
+ /* fallback to just inserting the rune */
+ //buf_ins(&Buffer, SelEnd++, key);
+ //SelBeg = SelEnd;
+ //TargetCol = buf_getcol(&Buffer, SelEnd);
+}
+
+static void key_handler(Rune key) {
+ /* ignore invalid keys */
+ if (key == RUNE_ERR) return;
+ /* handle the proper line endings */
+ if (key == '\r') key = '\n';
+ if (key == '\n' && Focused->buffer.crlf) key = RUNE_CRLF;
+ /* handle the key */
+ process_table(Insert, key);
+}
+
+/* Redisplay Functions
+ *****************************************************************************/
+static void draw_runes(unsigned x, unsigned y, int fg, int bg, UGlyph* glyphs, size_t rlen) {
+ XGlyphSpec specs[rlen];
+ while (rlen) {
+ size_t nspecs = x11_font_getglyphs(specs, (XGlyph*)glyphs, rlen, Font, x, y);
+ x11_draw_glyphs(fg, bg, specs, nspecs);
+ rlen -= nspecs;
+ }
+}
+
+static void draw_glyphs(unsigned x, unsigned y, UGlyph* glyphs, size_t rlen, size_t ncols) {
+ XGlyphSpec specs[rlen];
+ size_t i = 0;
+ while (rlen) {
+ int numspecs = 0;
+ uint32_t attr = glyphs[i].attr;
+ while (i < ncols && glyphs[i].attr == attr) {
+ x11_font_getglyph(Font, &(specs[numspecs]), glyphs[i].rune);
+ specs[numspecs].x = x;
+ specs[numspecs].y = y - x11_font_descent(Font);
+ x += x11_font_width(Font);
+ numspecs++;
+ i++;
+ /* skip over null chars which mark multi column runes */
+ for (; i < ncols && !glyphs[i].rune; i++)
+ x += x11_font_width(Font);
+ }
+ /* Draw the glyphs with the proper colors */
+ uint8_t bg = attr >> 8;
+ uint8_t fg = attr & 0xFF;
+ x11_draw_glyphs(fg, bg, specs, numspecs);
+ rlen -= numspecs;
+ }
+}
+
+static void draw_status(int fg, unsigned ncols) {
+ UGlyph glyphs[ncols], *status = glyphs;
+ (status++)->rune = (BufView.buffer.charset == BINARY ? 'B' : 'U');
+ (status++)->rune = (BufView.buffer.crlf ? 'C' : 'N');
+ (status++)->rune = (BufView.buffer.modified ? '*' : ' ');
+ (status++)->rune = ' ';
+ char* path = (BufView.buffer.path ? BufView.buffer.path : "*scratch*");
+ size_t len = strlen(path);
+ if (len > ncols-4) {
+ (status++)->rune = '.';
+ (status++)->rune = '.';
+ (status++)->rune = '.';
+ path += (len - ncols) + 6;
+ }
+ while(*path)
+ (status++)->rune = *path++;
+ draw_runes(0, 0, fg, 0, glyphs, status - glyphs);
+}
+
+static size_t stackvert(size_t off, size_t rows) {
+ return (off + 4 + (rows * x11_font_height(Font)));
+}
+
+static size_t draw_view(size_t off, View* view, size_t rows, size_t width) {
+ size_t fheight = x11_font_height(Font);
+ size_t fwidth = x11_font_width(Font);
+ size_t cols = (width - 4) / fwidth;
+ view_resize(view, rows, cols);
+ /* update the screen buffer and retrieve cursor coordinates */
+ size_t csrx, csry;
+ view_update(view, &csrx, &csry);
+ /* flush the screen buffer */
+ for (size_t y = 0; y < rows; y++) {
+ Row* row = view_getrow(view, y);
+ draw_glyphs(2, off + ((y+1) * fheight), row->cols, row->rlen, row->len);
+ }
+ /* Place cursor on screen */
+ x11_draw_rect(CLR_BASE3, 2 + csrx * fwidth, off + (csry * fheight), 1, fheight);
+ return (off + 4 + (rows * x11_font_height(Font)));
+}
+
+static void redraw(int width, int height) {
+ size_t vmargin = 2;
+ size_t hmargin = 2;
+ size_t fheight = x11_font_height(Font);
+ size_t fwidth = x11_font_width(Font);
+ /* clear background and draw status */
+ size_t vpos = 0;
+ x11_draw_rect(CLR_BASE03, 0, vpos, width, height);
+ draw_status(CLR_BASE3, width / fwidth);
+ /* draw the tag buffer */
+ vpos = stackvert(vpos, 1);
+ x11_draw_rect(CLR_BASE01, 0, vpos++, width, 1);
+ size_t totrows = (height - vpos - 9) / fheight;
+ size_t tagrows = (TagWinExpanded ? (totrows / 4) : 1);
+ size_t bufrows = totrows - tagrows;
+ vpos = draw_view(3+vpos, &TagView, tagrows, width);
+ /* draw thee dit buffer */
+ x11_draw_rect(CLR_BASE01, 0, ++vpos, width, 1);
+ vpos = draw_view(3+vpos, &BufView, bufrows, width);
+}
+
+/* Main Routine
+ *****************************************************************************/
+int main(int argc, char** argv) {
+ /* load the buffer views */
+ view_init(&TagView, NULL);
+ view_init(&BufView, (argc > 1 ? argv[1] : NULL));
+ buf_putstr(&(TagView.buffer), 0, 0, DEFAULT_TAGS);
+ /* initialize the display engine */
+ x11_init(&Config);
+ x11_window("edit", Width, Height);
+ x11_show();
+ Font = x11_font_load(FONTNAME);
+ x11_loop();
+ return 0;
+}
+
+#if 0
+#if 0
+/* External Commands
+ *****************************************************************************/
+#ifdef __MACH__
+static char* CopyCmd[] = { "pbcopy", NULL };
+static char* PasteCmd[] = { "pbpaste", NULL };
+#else
+static char* CopyCmd[] = { "xsel", "-bi", NULL };
+static char* PasteCmd[] = { "xsel", "-bo", NULL };
+#endif
/* Keyboard Actions
*****************************************************************************/
static void cut(void) {
char* str = buf_getstr(&Buffer, SelBeg, SelEnd);
- clipcopy(str);
+ cmdwrite(CopyCmd, str);
free(str);
delete();
}
static void copy(void) {
char* str = buf_getstr(&Buffer, SelBeg, SelEnd);
- clipcopy(str);
+ cmdwrite(CopyCmd, str);
free(str);
}
static void paste(void) {
- char* str = clippaste();
+ char* str = cmdread(PasteCmd);
buf_putstr(&Buffer, SelBeg, SelEnd, str);
free(str);
}
-static void cursor_up(void) {
- SelBeg = SelEnd = buf_byline(&Buffer, SelEnd, -1);
- SelBeg = SelEnd = buf_setcol(&Buffer, SelEnd, TargetCol);
-}
-
-static void cursor_dn(void) {
- SelBeg = SelEnd = buf_byline(&Buffer, SelEnd, 1);
- SelBeg = SelEnd = buf_setcol(&Buffer, SelEnd, TargetCol);
-}
-
-static void cursor_left(void) {
- SelBeg = SelEnd = buf_byrune(&Buffer, SelEnd, -1);
- TargetCol = buf_getcol(&Buffer, SelEnd);
-}
-
-static void cursor_right(void) {
- SelBeg = SelEnd = buf_byrune(&Buffer, SelEnd, 1);
- TargetCol = buf_getcol(&Buffer, SelEnd);
-}
-
static void cursor_bol(void) {
SelBeg = SelEnd = buf_bol(&Buffer, SelEnd);
TargetCol = 0;
TagWinExpanded = !TagWinExpanded;
}
-/* Keyboard Bindings
- *****************************************************************************/
-typedef struct {
- Rune key;
- void (*action)(void);
-} KeyBinding_T;
-
-static KeyBinding_T Insert[] = {
- { KEY_CTRL_Q, quit },
- { KEY_CTRL_S, write },
- { KEY_CTRL_T, tagwin },
- { KEY_CTRL_Z, undo },
- { KEY_CTRL_Y, redo },
- { KEY_CTRL_X, cut },
- { KEY_CTRL_C, copy },
- { KEY_CTRL_V, paste },
- { KEY_UP, cursor_up },
- { KEY_DOWN, cursor_dn },
- { KEY_LEFT, cursor_left },
- { KEY_RIGHT, cursor_right },
- { KEY_HOME, cursor_bol },
- { KEY_END, cursor_eol },
- { KEY_DELETE, delete },
- { KEY_BACKSPACE, backspace },
- { 0, NULL }
-};
-
-static void process_table(KeyBinding_T* bindings, Rune key) {
- while (bindings->key) {
- if (key == bindings->key) {
- bindings->action();
- return;
- }
- bindings++;
- }
- /* skip control and nonprintable characters */
- if ((!isspace(key) && key < 0x20) ||
- (key >= 0xE000 && key <= 0xF8FF))
- return;
- /* fallback to just inserting the rune */
- buf_ins(&Buffer, SelEnd++, key);
- SelBeg = SelEnd;
- TargetCol = buf_getcol(&Buffer, SelEnd);
-}
-
-static void key_handler(Rune key) {
- /* ignore invalid keys */
- if (key == RUNE_ERR) return;
- /* handle the proper line endings */
- if (key == '\r') key = '\n';
- if (key == '\n' && Buffer.crlf) key = RUNE_CRLF;
- /* handle the key */
- process_table(Insert, key);
-}
+#endif
/* Mouse Actions
*****************************************************************************/
+#if 0
void unused(int x, int y) {
}
void move_cursor(int x, int y) {
if (y == 0) return;
- SelBeg = SelEnd = screen_getoff(&Buffer, SelEnd, y-1, x);
+ //SelBeg = SelEnd = screen_getoff(&Buffer, SelEnd, y-1, x);
TargetCol = buf_getcol(&Buffer, SelEnd);
}
}
void search(int x, int y) {
- unsigned clickpos = screen_getoff(&Buffer, SelEnd, y-1, x);
- if (clickpos < SelBeg || clickpos > SelEnd) {
- move_cursor(x,y);
- selection(x,y);
- } else {
- buf_find(&Buffer, &SelBeg, &SelEnd);
- }
- unsigned c, r;
- screen_update(&Buffer, SelEnd, &c, &r);
- extern void move_pointer(unsigned c, unsigned r);
- move_pointer(c, r);
-
+ //unsigned clickpos = screen_getoff(&Buffer, SelEnd, y-1, x);
+ //if (clickpos < SelBeg || clickpos > SelEnd) {
+ // move_cursor(x,y);
+ // selection(x,y);
+ //} else {
+ // buf_find(&Buffer, &SelBeg, &SelEnd);
+ //}
+ //unsigned c, r;
+ //screen_update(&Buffer, SelEnd, &c, &r);
+ //extern void move_pointer(unsigned c, unsigned r);
+ //move_pointer(c, r);
}
void scrollup(int x, int y) {
void scrolldn(int x, int y) {
SelBeg = SelEnd = buf_byline(&Buffer, SelEnd, ScrollLines);
}
-
+#endif
/* Mouse Input Handler
*****************************************************************************/
struct {
uint32_t count;
} Buttons[5] = { 0 };
-void (*Actions[5][3])(int x, int y) = {
+void (*Actions[5][3])(int x, int y) = { 0
/* Single Double Triple */
- [MOUSE_BTN_LEFT] = { move_cursor, selection, bigword, },
- [MOUSE_BTN_MIDDLE] = { unused, unused, unused, },
- [MOUSE_BTN_RIGHT] = { search, search, search, },
- [MOUSE_BTN_WHEELUP] = { scrollup, scrollup, scrollup, },
- [MOUSE_BTN_WHEELDOWN] = { scrolldn, scrolldn, scrolldn, },
+ //[MOUSE_BTN_LEFT] = { move_cursor, selection, bigword, },
+ //[MOUSE_BTN_MIDDLE] = { unused, unused, unused, },
+ //[MOUSE_BTN_RIGHT] = { search, search, search, },
+ //[MOUSE_BTN_WHEELUP] = { scrollup, scrollup, scrollup, },
+ //[MOUSE_BTN_WHEELDOWN] = { scrolldn, scrolldn, scrolldn, },
};
static void mouse_handler(MouseAct act, MouseBtn btn, int x, int y) {
- unsigned row = y / Fonts.base.height;
- unsigned col = x / Fonts.base.width;
- unsigned twsz = (TagWinExpanded ? ((ScrRows - 1) / 4) : 1);
-
- //if (row == 0) {
- // puts("status");
- //} else if (row >= 1 && row <= twsz) {
- // puts("tagwin");
- //} else {
- // puts("editwin");
+ //unsigned row = y / Fonts.base.height;
+ //unsigned col = x / Fonts.base.width;
+ //unsigned twsz = (TagWinExpanded ? ((ScrRows - 1) / 4) : 1);
+
+ ////if (row == 0) {
+ //// puts("status");
+ ////} else if (row >= 1 && row <= twsz) {
+ //// puts("tagwin");
+ ////} else {
+ //// puts("editwin");
+ ////}
+
+ //if (act == MOUSE_ACT_DOWN) {
+ // //if (mevnt->button >= 5) return;
+ // ///* update the number of clicks */
+ // //uint32_t now = getmillis();
+ // //uint32_t elapsed = now - Buttons[mevnt->button].time;
+ // //if (elapsed <= 250)
+ // // Buttons[mevnt->button].count++;
+ // //else
+ // // Buttons[mevnt->button].count = 1;
+ // //Buttons[mevnt->button].time = now;
+ // ///* execute the click action */
+ // //uint32_t nclicks = Buttons[mevnt->button].count;
+ // //nclicks = (nclicks > 3 ? 1 : nclicks);
+ // //Actions[mevnt->button][nclicks-1](mevnt);
+ //} else if (act == MOUSE_ACT_MOVE) {
+ // puts("move");
+ // //if (mevnt->y == 0 || mevnt->button != MOUSE_LEFT) return;
+ // //SelEnd = screen_getoff(&Buffer, SelEnd, mevnt->y-1, mevnt->x);
+ // //TargetCol = buf_getcol(&Buffer, SelEnd);
//}
-
- if (act == MOUSE_ACT_DOWN) {
- //if (mevnt->button >= 5) return;
- ///* update the number of clicks */
- //uint32_t now = getmillis();
- //uint32_t elapsed = now - Buttons[mevnt->button].time;
- //if (elapsed <= 250)
- // Buttons[mevnt->button].count++;
- //else
- // Buttons[mevnt->button].count = 1;
- //Buttons[mevnt->button].time = now;
- ///* execute the click action */
- //uint32_t nclicks = Buttons[mevnt->button].count;
- //nclicks = (nclicks > 3 ? 1 : nclicks);
- //Actions[mevnt->button][nclicks-1](mevnt);
- } else if (act == MOUSE_ACT_MOVE) {
- //if (mevnt->y == 0 || mevnt->button != MOUSE_LEFT) return;
- //SelEnd = screen_getoff(&Buffer, SelEnd, mevnt->y-1, mevnt->x);
- //TargetCol = buf_getcol(&Buffer, SelEnd);
- }
}
-
/* Screen Redraw
*****************************************************************************/
-static void draw_runes(unsigned x, unsigned y, int fg, int bg, UGlyph* glyphs, size_t rlen) {
- XftGlyphFontSpec specs[rlen];
- while (rlen) {
- size_t nspecs = x11_font_getglyphs(specs, (XGlyph*)glyphs, rlen, &Fonts, x, y);
- x11_draw_glyphs(fg, bg, specs, nspecs);
- rlen -= nspecs;
- }
-}
-
-static void draw_glyphs(unsigned x, unsigned y, UGlyph* glyphs, size_t rlen, size_t ncols) {
- XftGlyphFontSpec specs[rlen];
- size_t i = 0;
- while (rlen) {
- int numspecs = 0;
- uint32_t attr = glyphs[i].attr;
- while (i < ncols && glyphs[i].attr == attr) {
- x11_font_getglyph(&Fonts, &(specs[numspecs]), glyphs[i].rune);
- specs[numspecs].x = x;
- specs[numspecs].y = y - Fonts.base.descent;
- x += Fonts.base.width;
- numspecs++;
- i++;
- /* skip over null chars which mark multi column runes */
- for (; i < ncols && !glyphs[i].rune; i++)
- x += Fonts.base.width;
- }
- /* Draw the glyphs with the proper colors */
- uint8_t bg = attr >> 8;
- uint8_t fg = attr & 0xFF;
- x11_draw_glyphs(fg, bg, specs, numspecs);
- rlen -= numspecs;
- }
-}
-
-static void draw_status(int fg, unsigned ncols) {
- UGlyph glyphs[ncols], *status = glyphs;
- (status++)->rune = (Buffer.charset == BINARY ? 'B' : 'U');
- (status++)->rune = (Buffer.crlf ? 'C' : 'N');
- (status++)->rune = (Buffer.modified ? '*' : ' ');
- (status++)->rune = ' ';
- char* path = (Buffer.path ? Buffer.path : "*scratch*");
- size_t len = strlen(path);
- if (len > ncols-4) {
- (status++)->rune = '.';
- (status++)->rune = '.';
- (status++)->rune = '.';
- path += (len - ncols) + 6;
- }
- while(*path)
- (status++)->rune = *path++;
- draw_runes(0, 0, fg, 0, glyphs, status - glyphs);
-}
-
static void draw_tagwin(unsigned off, unsigned rows, unsigned cols) {
//screen_setsize(&TagBuffer, rows, cols);
}
static void draw_bufwin(unsigned off, unsigned rows, unsigned cols) {
- screen_setsize(&Buffer, rows, cols);
- /* update the screen buffer and retrieve cursor coordinates */
- unsigned csrx, csry;
- screen_update(&Buffer, SelEnd, &csrx, &csry);
- /* flush the screen buffer */
- unsigned nrows, ncols;
- screen_getsize(&nrows, &ncols);
- draw_status(CLR_BASE2, ncols);
- for (unsigned y = 0; y < nrows; y++) {
- Row* row = screen_getrow(y);
- draw_glyphs(0, off + ((y+1) * Fonts.base.height), row->cols, row->rlen, row->len);
- }
- /* Place cursor on screen */
- x11_draw_rect(CLR_BASE3, csrx * Fonts.base.width, off + (csry * Fonts.base.height), 1, Fonts.base.height);
+ //screen_setsize(&Buffer, rows, cols);
+ ///* update the screen buffer and retrieve cursor coordinates */
+ //unsigned csrx, csry;
+ //screen_update(&Buffer, SelEnd, &csrx, &csry);
+ ///* flush the screen buffer */
+ //unsigned nrows, ncols;
+ //screen_getsize(&nrows, &ncols);
+ //draw_status(CLR_BASE2, ncols);
+ //for (unsigned y = 0; y < nrows; y++) {
+ // Row* row = screen_getrow(y);
+ // draw_glyphs(0, off + ((y+1) * Fonts.base.height), row->cols, row->rlen, row->len);
+ //}
+ ///* Place cursor on screen */
+ //x11_draw_rect(CLR_BASE3, csrx * Fonts.base.width, off + (csry * Fonts.base.height), 1, Fonts.base.height);
}
static void redraw(int width, int height) {
- unsigned fheight = Fonts.base.height;
- unsigned fwidth = Fonts.base.width;
- ScrRows = height / Fonts.base.height;
- ScrCols = width / Fonts.base.width;
- /* clear background and draw status */
- x11_draw_rect(CLR_BASE03, 0, 0, width, height);
- draw_status(CLR_BASE2, ScrCols);
- /* draw the tag window */
- unsigned twsz = (TagWinExpanded ? ((ScrRows - 1) / 4) : 1);
- x11_draw_rect(CLR_BASE02, 0, fheight, width, twsz * fheight);
- x11_draw_rect(CLR_BASE01, 0, fheight, width, 1);
- draw_tagwin(fheight, twsz, ScrCols);
- /* draw the file window */
- x11_draw_rect(CLR_BASE01, 0, (twsz+1) * fheight, width, 1);
- draw_bufwin((twsz+1) * fheight, ScrRows - (twsz), ScrCols);
+ //unsigned fheight = Fonts.base.height;
+ //unsigned fwidth = Fonts.base.width;
+ //ScrRows = height / Fonts.base.height;
+ //ScrCols = width / Fonts.base.width;
+ ///* clear background and draw status */
+ //x11_draw_rect(CLR_BASE03, 0, 0, width, height);
+ //draw_status(CLR_BASE2, ScrCols);
+ ///* draw the tag window */
+ //unsigned twsz = (TagWinExpanded ? ((ScrRows - 1) / 4) : 1);
+ //x11_draw_rect(CLR_BASE02, 0, fheight, width, twsz * fheight);
+ //x11_draw_rect(CLR_BASE01, 0, fheight, width, 1);
+ //draw_tagwin(fheight, twsz, ScrCols);
+ ///* draw the file window */
+ //x11_draw_rect(CLR_BASE01, 0, (twsz+1) * fheight, width, 1);
+ //draw_bufwin((twsz+1) * fheight, ScrRows - (twsz), ScrCols);
}
int main(int argc, char** argv) {
- /* load the buffer */
- buf_init(&Buffer);
- if (argc > 1)
- buf_load(&Buffer, argv[1]);
+ /* load the buffer views */
+ view_init(&TagView, NULL);
+ view_init(&BufView, (argc > 1 ? argv[1] : NULL));
/* initialize the display engine */
x11_init(&Config);
x11_window("edit", Width, Height);
y = ((y+1) * Fonts.base.height) + (Fonts.base.height / 2);
x11_warp_mouse(x,y);
}
+#endif