From 04ec68f7327c01ae5984394a461443121073cfc4 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 24 May 2017 19:58:32 -0400 Subject: [PATCH] Removed junk files from syncthing --- inc/win.sync-conflict-20170524-185737.h | 69 --- inc/x11.sync-conflict-20170524-185739.h | 149 ------ lib/win.sync-conflict-20170524-185738.c | 349 ------------- lib/x11.sync-conflict-20170524-185739.c | 627 ------------------------ xedit.sync-conflict-20170524-185737.c | 526 -------------------- 5 files changed, 1720 deletions(-) delete mode 100644 inc/win.sync-conflict-20170524-185737.h delete mode 100644 inc/x11.sync-conflict-20170524-185739.h delete mode 100644 lib/win.sync-conflict-20170524-185738.c delete mode 100644 lib/x11.sync-conflict-20170524-185739.c delete mode 100644 xedit.sync-conflict-20170524-185737.c diff --git a/inc/win.sync-conflict-20170524-185737.h b/inc/win.sync-conflict-20170524-185737.h deleted file mode 100644 index 77b464a..0000000 --- a/inc/win.sync-conflict-20170524-185737.h +++ /dev/null @@ -1,69 +0,0 @@ -enum { - MouseLeft = 1, - MouseMiddle = 2, - MouseRight = 3, - MouseWheelUp = 4, - MouseWheelDn = 5 -}; - -typedef enum { - STATUS = 0, - TAGS = 1, - EDIT = 2, - SCROLL = 3, - NREGIONS = 4, - FOCUSED = 4 -} WinRegion; - -typedef struct { - int mods; - Rune key; - void (*action)(void); -} KeyBinding; - -typedef struct { - size_t x; - size_t y; - size_t height; - size_t width; - size_t csrx; - size_t csry; - bool warp_ptr; - View view; -} Region; - -typedef void (*MouseFunc)(WinRegion id, size_t count, size_t row, size_t col); - -typedef struct { - MouseFunc left; - MouseFunc middle; - MouseFunc right; -} MouseConfig; - -void win_window(char* name, void (*errfn)(char*)); -void win_dialog(char* name, void (*errfn)(char*)); -void win_loop(void); -void win_settext(WinRegion id, char* text); -void win_setruler(size_t ruler); -void win_setkeys(KeyBinding* bindings); -void win_setmouse(MouseConfig* mconfig); -void win_warpptr(WinRegion id); -View* win_view(WinRegion id); -Buf* win_buf(WinRegion id); -Sel* win_sel(WinRegion id); -bool win_btnpressed(int btn); -WinRegion win_getregion(void); -bool win_setregion(WinRegion id); -void win_setscroll(double offset, double visible); - -/* These functions must be implemented by any appliation that wishes - to use this module */ -void onshutdown(void); -void onfocus(bool focused); -void onupdate(void); -void onlayout(void); -void onscroll(double percent); -void onmouseleft(WinRegion id, bool pressed, size_t row, size_t col); -void onmousemiddle(WinRegion id, bool pressed, size_t row, size_t col); -void onmouseright(WinRegion id, bool pressed, size_t row, size_t col); - diff --git a/inc/x11.sync-conflict-20170524-185739.h b/inc/x11.sync-conflict-20170524-185739.h deleted file mode 100644 index a758842..0000000 --- a/inc/x11.sync-conflict-20170524-185739.h +++ /dev/null @@ -1,149 +0,0 @@ -typedef struct { - void (*redraw)(int width, int height); - void (*handle_key)(int mods, uint32_t rune); - void (*shutdown)(void); - void (*set_focus)(bool focus); - void (*mouse_drag)(int state, int x, int y); - void (*mouse_btn)(int state, bool pressed, int x, int y); - uint32_t palette[16]; -} XConfig; - -typedef void* XFont; - -typedef struct { - uint32_t attr; /* attributes applied to this cell */ - uint32_t rune; /* rune value for the cell */ -} XGlyph; - -typedef struct { - void* font; - uint32_t glyph; - short x; - short y; -} XGlyphSpec; - -/* key definitions */ -enum Keys { - /* Define some runes in the private use area of unicode to represent - * special keys */ - KEY_F1 = (0xE000+0), - KEY_F2 = (0xE000+1), - KEY_F3 = (0xE000+2), - KEY_F4 = (0xE000+3), - KEY_F5 = (0xE000+4), - KEY_F6 = (0xE000+5), - KEY_F7 = (0xE000+6), - KEY_F8 = (0xE000+7), - KEY_F9 = (0xE000+8), - KEY_F10 = (0xE000+9), - KEY_F11 = (0xE000+10), - KEY_F12 = (0xE000+11), - KEY_INSERT = (0xE000+12), - KEY_DELETE = (0xE000+13), - KEY_HOME = (0xE000+14), - KEY_END = (0xE000+15), - KEY_PGUP = (0xE000+16), - KEY_PGDN = (0xE000+17), - KEY_UP = (0xE000+18), - KEY_DOWN = (0xE000+19), - KEY_RIGHT = (0xE000+20), - KEY_LEFT = (0xE000+21), - - /* ASCII Control Characters */ - KEY_CTRL_TILDE = 0x00, - KEY_CTRL_2 = 0x00, - KEY_CTRL_A = 0x01, - KEY_CTRL_B = 0x02, - KEY_CTRL_C = 0x03, - KEY_CTRL_D = 0x04, - KEY_CTRL_E = 0x05, - KEY_CTRL_F = 0x06, - KEY_CTRL_G = 0x07, - KEY_BACKSPACE = 0x08, - KEY_CTRL_H = 0x08, - KEY_TAB = 0x09, - KEY_CTRL_I = 0x09, - KEY_CTRL_J = 0x0A, - KEY_CTRL_K = 0x0B, - KEY_CTRL_L = 0x0C, - KEY_ENTER = 0x0D, - KEY_CTRL_M = 0x0D, - KEY_CTRL_N = 0x0E, - KEY_CTRL_O = 0x0F, - KEY_CTRL_P = 0x10, - KEY_CTRL_Q = 0x11, - KEY_CTRL_R = 0x12, - KEY_CTRL_S = 0x13, - KEY_CTRL_T = 0x14, - KEY_CTRL_U = 0x15, - KEY_CTRL_V = 0x16, - KEY_CTRL_W = 0x17, - KEY_CTRL_X = 0x18, - KEY_CTRL_Y = 0x19, - KEY_CTRL_Z = 0x1A, - KEY_ESCAPE = 0x1B, - KEY_CTRL_LSQ_BRACKET = 0x1B, - KEY_CTRL_3 = 0x1B, - KEY_CTRL_4 = 0x1C, - KEY_CTRL_BACKSLASH = 0x1C, - KEY_CTRL_5 = 0x1D, - KEY_CTRL_RSQ_BRACKET = 0x1D, - KEY_CTRL_6 = 0x1E, - KEY_CTRL_7 = 0x1F, - KEY_CTRL_SLASH = 0x1F, - KEY_CTRL_UNDERSCORE = 0x1F, -}; - -/* Key modifier masks */ -enum { - ModNone = 0, - ModShift = (1 << 0), - ModCapsLock = (1 << 1), - ModCtrl = (1 << 2), - ModAlt = (1 << 3), - ModNumLock = (1 << 4), - ModScrollLock = (1 << 5), - ModWindows = (1 << 6), - ModAny = -1 -}; - -/* Selection identifiers */ -enum { - PRIMARY = 0, - CLIPBOARD = 1 -}; - -void x11_init(XConfig* cfg); -void x11_deinit(void); -int x11_keybtnstate(void); -bool x11_keymodsset(int mask); -void x11_window(char* name, int width, int height); -void x11_dialog(char* name, int height, int width); -void x11_show(void); -bool x11_running(void); -void x11_flip(void); -void x11_flush(void); -void x11_finish(void); - -int x11_events_queued(void); -bool x11_events_await(unsigned int ms); -void x11_events_take(void); - -void x11_mouse_get(int* x, int* y); -void x11_mouse_set(int x, int y); - -XFont x11_font_load(char* name); -size_t x11_font_height(XFont fnt); -size_t x11_font_width(XFont fnt); -size_t x11_font_descent(XFont fnt); -void x11_font_getglyph(XFont font, XGlyphSpec* spec, uint32_t rune); -size_t x11_font_getglyphs(XGlyphSpec* specs, const XGlyph* glyphs, int len, XFont font, int x, int y); - -void x11_draw_rect(int color, int x, int y, int width, int height); -void x11_draw_utf8(XFont font, int fg, int bg, int x, int y, char* str); -void x11_draw_glyphs(int fg, int bg, XGlyphSpec* glyphs, size_t nglyphs); -void x11_draw_utf8(XFont font, int fg, int bg, int x, int y, char* str); - -bool x11_sel_get(int selid, void(*cbfn)(char*)); -bool x11_sel_set(int selid, char* str); - diff --git a/lib/win.sync-conflict-20170524-185738.c b/lib/win.sync-conflict-20170524-185738.c deleted file mode 100644 index f6cfc62..0000000 --- a/lib/win.sync-conflict-20170524-185738.c +++ /dev/null @@ -1,349 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static void onredraw(int height, int width); -static void oninput(int mods, Rune key); -static void onmousedrag(int state, int x, int y); -static void onmousebtn(int btn, bool pressed, int x, int y); -static void onwheelup(WinRegion id, bool pressed, size_t row, size_t col); -static void onwheeldn(WinRegion id, bool pressed, size_t row, size_t col); -static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t rlen, size_t ncols); -static WinRegion getregion(size_t x, size_t y); - -static size_t Ruler = 0; -static double ScrollOffset = 0.0; -static double ScrollVisible = 1.0; -static XFont Font; -static XConfig Config = { - .redraw = onredraw, - .handle_key = oninput, - .shutdown = onshutdown, - .set_focus = onfocus, - .mouse_drag = onmousedrag, - .mouse_btn = onmousebtn, - .palette = COLOR_PALETTE -}; -static WinRegion Focused = EDIT; -static Region Regions[NREGIONS] = {0}; -KeyBinding* Keys = NULL; - -static void win_init(void (*errfn)(char*)) { - for (int i = 0; i < SCROLL; i++) - view_init(&(Regions[i].view), NULL, errfn); - x11_init(&Config); - Font = x11_font_load(FONTNAME); -} - -void win_window(char* name, void (*errfn)(char*)) { - win_init(errfn); - x11_window(name, Width, Height); -} - -void win_dialog(char* name, void (*errfn)(char*)) { - win_init(errfn); - x11_dialog(name, Width, Height); -} - -static bool update_focus(void) { - static int prev_x = 0, prev_y = 0; - int ptr_x, ptr_y; - bool changed = false; - /* dont change focus if any mouse buttons are pressed */ - if ((x11_keybtnstate() & 0x1f00) == 0) { - x11_mouse_get(&ptr_x, &ptr_y); - if (prev_x != ptr_x || prev_y != ptr_y) - changed = win_setregion(getregion(ptr_x, ptr_y)); - prev_x = ptr_x, prev_y = ptr_y; - } - return changed; -} - -void win_loop(void) { - x11_show(); - x11_flip(); - while (x11_running()) { - bool pending = x11_events_await(EventTimeout); - int nevents = x11_events_queued(); - if (update_focus() || pending || nevents) { - x11_events_take(); - if (x11_running()) - x11_flip(); - } - x11_flush(); - } - x11_finish(); -} - -void win_settext(WinRegion id, char* text) { - View* view = win_view(id); - view->buffer.gapstart = view->buffer.bufstart; - view->buffer.gapend = view->buffer.bufend; - view->selection = (Sel){0,0,0}; - view_putstr(view, text); - view_selprev(view); // clear the selection - buf_logclear(&(view->buffer)); -} - -void win_setruler(size_t ruler) { - Ruler = ruler; -} - -void win_setkeys(KeyBinding* bindings) { - Keys = bindings; -} - -bool win_btnpressed(int btn) { - int btnmask = (1 << (btn + 7)); - return ((x11_keybtnstate() & btnmask) == btnmask); -} - -WinRegion win_getregion(void) { - return Focused; -} - -bool win_setregion(WinRegion id) { - bool changed = true; - if (Focused != id && (id == TAGS || id == EDIT)) - changed = true, Focused = id; - return changed; -} - -void win_warpptr(WinRegion id) { - Regions[id].warp_ptr = true; -} - -View* win_view(WinRegion id) { - if (id == FOCUSED) id = Focused; - return &(Regions[id].view); -} - -Buf* win_buf(WinRegion id) { - if (id == FOCUSED) id = Focused; - return &(Regions[id].view.buffer); -} - -Sel* win_sel(WinRegion id) { - if (id == FOCUSED) id = Focused; - return &(Regions[id].view.selection); -} - -void win_setscroll(double offset, double visible) { - ScrollOffset = offset; - ScrollVisible = visible; -} - -static void layout(int width, int height) { - size_t fheight = x11_font_height(Font); - size_t fwidth = x11_font_width(Font); - View* statview = win_view(STATUS); - View* tagview = win_view(TAGS); - View* editview = win_view(EDIT); - - /* update the text views and region positions and sizes */ - for (int i = 0; i < SCROLL; i++) { - Regions[i].x = 2; - Regions[i].y = 2; - Regions[i].csrx = SIZE_MAX; - Regions[i].csry = SIZE_MAX; - Regions[i].width = (width - 4); - Regions[i].height = fheight; - } - - /* place the status region */ - view_resize(statview, 1, Regions[STATUS].width / fwidth); - - /* Place the tag region relative to status */ - Regions[TAGS].y = 5 + Regions[STATUS].y + Regions[STATUS].height; - size_t maxtagrows = ((height - Regions[TAGS].y - 5) / 4) / fheight; - size_t tagcols = Regions[TAGS].width / fwidth; - size_t tagrows = view_limitrows(tagview, maxtagrows, tagcols); - Regions[TAGS].height = tagrows * fheight; - view_resize(tagview, tagrows, tagcols); - - /* Place the scroll region relative to tags */ - Regions[SCROLL].x = 0; - Regions[SCROLL].y = 5 + Regions[TAGS].y + Regions[TAGS].height; - Regions[SCROLL].height = (height - Regions[EDIT].y - 5); - Regions[SCROLL].width = 5 + fwidth; - - /* Place the edit region relative to tags */ - Regions[EDIT].x = 3 + Regions[SCROLL].width; - Regions[EDIT].y = 5 + Regions[TAGS].y + Regions[TAGS].height; - Regions[EDIT].height = (height - Regions[EDIT].y - 5); - Regions[EDIT].width = width - Regions[SCROLL].width - 5; - view_resize(editview, Regions[EDIT].height / fheight, Regions[EDIT].width / fwidth); -} - -static void onredraw(int width, int height) { - size_t fheight = x11_font_height(Font); - size_t fwidth = x11_font_width(Font); - - layout(width, height); - onupdate(); // Let the user program update the status and other content - view_update(win_view(STATUS), &(Regions[STATUS].csrx), &(Regions[STATUS].csry)); - view_update(win_view(TAGS), &(Regions[TAGS].csrx), &(Regions[TAGS].csry)); - view_update(win_view(EDIT), &(Regions[EDIT].csrx), &(Regions[EDIT].csry)); - onlayout(); // Let the user program update the scroll bar - - for (int i = 0; i < SCROLL; i++) { - View* view = win_view(i); - x11_draw_rect((i == TAGS ? CLR_BASE02 : CLR_BASE03), - 0, Regions[i].y - 3, width, Regions[i].height + 8); - x11_draw_rect(CLR_BASE01, 0, Regions[i].y - 3, width, 1); - if ((i == EDIT) && (Ruler != 0)) - x11_draw_rect(CLR_BASE02, (Ruler+2) * fwidth, Regions[i].y-2, 1, Regions[i].height+7); - for (size_t y = 0; y < view->nrows; y++) { - Row* row = view_getrow(view, y); - draw_glyphs(Regions[i].x, Regions[i].y + ((y+1) * fheight), row->cols, row->rlen, row->len); - } - } - - /* draw the scroll region */ - size_t thumbreg = (Regions[SCROLL].height - Regions[SCROLL].y + 9); - size_t thumboff = (size_t)((thumbreg * ScrollOffset) + (Regions[SCROLL].y - 2)); - size_t thumbsz = (size_t)(thumbreg * ScrollVisible); - if (thumbsz < 5) thumbsz = 5; - x11_draw_rect(CLR_BASE01, Regions[SCROLL].width, Regions[SCROLL].y - 2, 1, Regions[SCROLL].height); - x11_draw_rect(CLR_BASE00, 0, Regions[SCROLL].y - 2, Regions[SCROLL].width, thumbreg); - x11_draw_rect(CLR_BASE03, 0, thumboff, Regions[SCROLL].width, thumbsz); - - /* place the cursor on screen */ - if (Regions[Focused].csrx != SIZE_MAX && Regions[Focused].csry != SIZE_MAX) { - x11_draw_rect(CLR_BASE3, - Regions[Focused].x + (Regions[Focused].csrx * fwidth), - Regions[Focused].y + (Regions[Focused].csry * fheight), - 1, fheight); - } - - /* adjust the mouse location */ - if (Regions[Focused].warp_ptr) { - Regions[Focused].warp_ptr = false; - size_t x = Regions[Focused].x + (Regions[Focused].csrx * fwidth) - (fwidth/2); - size_t y = Regions[Focused].y + (Regions[Focused].csry * fheight) + (fheight/2); - x11_mouse_set(x, y); - } -} - -static void oninput(int mods, Rune key) { - /* mask of modifiers we don't care about */ - mods = mods & (ModCtrl|ModAlt|ModShift); - /* handle the proper line endings */ - if (key == '\r') key = '\n'; - /* search for a key binding entry */ - uint32_t mkey = tolower(key); - for (KeyBinding* bind = Keys; bind && bind->key; bind++) { - if ((mkey == bind->key) && (bind->mods == ModAny || bind->mods == mods)) { - bind->action(); - return; - } - } - - /* fallback to just inserting the rune if it doesn't fall in the private use area. - * the private use area is used to encode special keys */ - if (key < 0xE000 || key > 0xF8FF) { - if (key == '\n' && win_view(FOCUSED)->buffer.crlf) - key = RUNE_CRLF; - view_insert(win_view(FOCUSED), true, key); - } -} - -static void scroll_actions(int btn, bool pressed, int x, int y) { - size_t row = (y-Regions[SCROLL].y) / x11_font_height(Font); - size_t col = (x-Regions[SCROLL].x) / x11_font_width(Font); - switch (btn) { - case MouseLeft: - if (pressed) - view_scroll(win_view(EDIT), -row); - break; - case MouseMiddle: - if (pressed) - onscroll((double)(y - Regions[SCROLL].y) / - (double)(Regions[SCROLL].height - Regions[SCROLL].y)); - break; - case MouseRight: - if (pressed) - view_scroll(win_view(EDIT), +row); - break; - case MouseWheelUp: - view_scroll(win_view(EDIT), -ScrollLines); - break; - case MouseWheelDn: - view_scroll(win_view(EDIT), +ScrollLines); - break; - } -} - -static void onmousedrag(int state, int x, int y) { - WinRegion id = getregion(x, y); - size_t row = (y-Regions[id].y) / x11_font_height(Font); - size_t col = (x-Regions[id].x) / x11_font_width(Font); - if (id == Focused && win_btnpressed(MouseLeft)) - view_selext(win_view(id), row, col); -} - -static void onmousebtn(int btn, bool pressed, int x, int y) { - WinRegion id = getregion(x, y); - size_t row = (y-Regions[id].y) / x11_font_height(Font); - size_t col = (x-Regions[id].x) / x11_font_width(Font); - - if (id == SCROLL) { - scroll_actions(btn, pressed, x, y); - } else { - switch(btn) { - case MouseLeft: onmouseleft(id, pressed, row, col); break; - case MouseMiddle: onmousemiddle(id, pressed, row, col); break; - case MouseRight: onmouseright(id, pressed, row, col); break; - case MouseWheelUp: onwheelup(id, pressed, row, col); break; - case MouseWheelDn: onwheeldn(id, pressed, row, col); break; - } - } -} - -static void onwheelup(WinRegion id, bool pressed, size_t row, size_t col) { - if (!pressed) return; - view_scroll(win_view(id), -ScrollLines); -} - -static void onwheeldn(WinRegion id, bool pressed, size_t row, size_t col) { - if (!pressed) return; - view_scroll(win_view(id), +ScrollLines); -} - -static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t rlen, size_t ncols) { - XGlyphSpec specs[rlen]; - size_t i = 0; - while (rlen && i < ncols) { - 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 WinRegion getregion(size_t x, size_t y) { - for (int i = 0; i < NREGIONS; i++) { - size_t startx = Regions[i].x, endx = startx + Regions[i].width; - size_t starty = Regions[i].y, endy = starty + Regions[i].height; - if ((startx <= x && x <= endx) && (starty <= y && y <= endy)) - return (WinRegion)i; - } - return NREGIONS; -} diff --git a/lib/x11.sync-conflict-20170524-185739.c b/lib/x11.sync-conflict-20170524-185739.c deleted file mode 100644 index 38d3dc1..0000000 --- a/lib/x11.sync-conflict-20170524-185739.c +++ /dev/null @@ -1,627 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct XSel* selfetch(Atom atom); -static void selclear(XEvent* evnt); -static void selnotify(XEvent* evnt); -static void selrequest(XEvent* evnt); - -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[FontCacheSize]; - int ncached; -}; - -static bool Running = true; -static struct { - Window root; - Display* display; - Visual* visual; - Colormap colormap; - unsigned depth; - int screen; - /* assume a single window for now. these are it's attributes */ - Window window; - XftDraw* xft; - Pixmap pixmap; - int width; - int height; - XIC xic; - XIM xim; - GC gc; -} X; -static XConfig* Config; -static int KeyBtnState; -static Atom SelTarget; -static struct XSel { - char* name; - Atom atom; - char* text; - void (*callback)(char*); -} Selections[] = { - { .name = "PRIMARY" }, - { .name = "CLIPBOARD" }, -}; - -static void xftcolor(XftColor* xc, uint32_t c) { - xc->color.alpha = 0xFF | ((c & 0xFF000000) >> 16); - xc->color.red = 0xFF | ((c & 0x00FF0000) >> 8); - xc->color.green = 0xFF | ((c & 0x0000FF00)); - xc->color.blue = 0xFF | ((c & 0x000000FF) << 8); - XftColorAllocValue(X.display, X.visual, X.colormap, &(xc->color), xc); -} - -void x11_deinit(void) { - Running = false; -} - -void x11_init(XConfig* cfg) { - atexit(x11_deinit); - signal(SIGPIPE, SIG_IGN); // Ignore the SIGPIPE signal - setlocale(LC_CTYPE, ""); - XSetLocaleModifiers(""); - /* open the X display and get basic attributes */ - Config = cfg; - if (!(X.display = XOpenDisplay(0))) - die("could not open display"); - X.root = DefaultRootWindow(X.display); - XWindowAttributes wa; - XGetWindowAttributes(X.display, X.root, &wa); - X.visual = wa.visual; - X.colormap = wa.colormap; - X.screen = DefaultScreen(X.display); - X.depth = DefaultDepth(X.display, X.screen); - /* initialize selection atoms */ - for (int i = 0; i < (sizeof(Selections) / sizeof(Selections[0])); i++) - Selections[i].atom = XInternAtom(X.display, Selections[i].name, 0); - SelTarget = XInternAtom(X.display, "UTF8_STRING", 0); - if (SelTarget == None) - SelTarget = XInternAtom(X.display, "STRING", 0); -} - -int x11_keybtnstate(void) { - return KeyBtnState; -} - -bool x11_keymodsset(int mask) { - return ((KeyBtnState & mask) == mask); -} - -void x11_window(char* name, int width, int height) { - /* create the main window */ - X.width = width ; - X.height = height; - XWindowAttributes wa; - XGetWindowAttributes(X.display, X.root, &wa); - X.window = XCreateSimpleWindow(X.display, X.root, - (wa.width - X.width) / 2, - (wa.height - X.height) /2, - X.width, - X.height, - 0, X.depth, - Config->palette[0]); - - /* register interest in the delete window message */ - Atom wmDeleteMessage = XInternAtom(X.display, "WM_DELETE_WINDOW", False); - XSetWMProtocols(X.display, X.window, &wmDeleteMessage, 1); - - /* setup window attributes and events */ - XSetWindowAttributes swa; - swa.backing_store = WhenMapped; - swa.bit_gravity = NorthWestGravity; - XChangeWindowAttributes(X.display, X.window, CWBackingStore|CWBitGravity, &swa); - XStoreName(X.display, X.window, name); - XSelectInput(X.display, X.window, - StructureNotifyMask - | ButtonPressMask - | ButtonReleaseMask - | ButtonMotionMask - | KeyPressMask - | FocusChangeMask - ); - - /* set input methods */ - if ((X.xim = XOpenIM(X.display, 0, 0, 0))) - X.xic = XCreateIC(X.xim, XNInputStyle, XIMPreeditNothing|XIMStatusNothing, XNClientWindow, X.window, XNFocusWindow, X.window, NULL); - - /* initialize pixmap and drawing context */ - X.pixmap = XCreatePixmap(X.display, X.window, width, height, X.depth); - X.xft = XftDrawCreate(X.display, X.pixmap, X.visual, X.colormap); - - /* initialize the graphics context */ - XGCValues gcv; - gcv.foreground = WhitePixel(X.display, X.screen); - gcv.graphics_exposures = False; - X.gc = XCreateGC(X.display, X.window, GCForeground|GCGraphicsExposures, &gcv); -} - -void x11_dialog(char* name, int height, int width) { - x11_window(name, height, width); - Atom WindowType = XInternAtom(X.display, "_NET_WM_WINDOW_TYPE", False); - Atom DialogType = XInternAtom(X.display, "_NET_WM_WINDOW_TYPE_DIALOG", False); - XChangeProperty(X.display, X.window, WindowType, XA_ATOM, 32, PropModeReplace, (unsigned char*)&DialogType, 1); -} - -void x11_show(void) { - /* simulate an initial resize and map the window */ - XConfigureEvent ce; - ce.type = ConfigureNotify; - ce.width = X.width; - ce.height = X.height; - XSendEvent(X.display, X.window, False, StructureNotifyMask, (XEvent *)&ce); - XMapWindow(X.display, X.window); -} - -bool x11_running(void) { - return Running; -} - -void x11_flip(void) { - Config->redraw(X.width, X.height); - XCopyArea(X.display, X.pixmap, X.window, X.gc, 0, 0, X.width, X.height, 0, 0); - x11_flush(); -} - -void x11_flush(void) { - XFlush(X.display); -} - -void x11_finish(void) { - XCloseDisplay(X.display); - /* we're exiting now. If we own the clipboard, make sure it persists */ - if (Selections[CLIPBOARD].text) - cmdwrite((char*[]){ "xcpd", NULL }, Selections[CLIPBOARD].text, NULL); -} - -/******************************************************************************/ - -static uint32_t special_keys(uint32_t key) { - switch (key) { - case XK_F1: return KEY_F1; - case XK_F2: return KEY_F2; - case XK_F3: return KEY_F3; - case XK_F4: return KEY_F4; - case XK_F5: return KEY_F5; - case XK_F6: return KEY_F6; - case XK_F7: return KEY_F7; - case XK_F8: return KEY_F8; - case XK_F9: return KEY_F9; - case XK_F10: return KEY_F10; - case XK_F11: return KEY_F11; - case XK_F12: return KEY_F12; - case XK_Insert: return KEY_INSERT; - case XK_Delete: return KEY_DELETE; - case XK_Home: return KEY_HOME; - case XK_End: return KEY_END; - case XK_Page_Up: return KEY_PGUP; - case XK_Page_Down: return KEY_PGDN; - case XK_Up: return KEY_UP; - case XK_Down: return KEY_DOWN; - case XK_Left: return KEY_LEFT; - case XK_Right: return KEY_RIGHT; - case XK_Escape: return KEY_ESCAPE; - case XK_BackSpace: return '\b'; - case XK_Tab: return '\t'; - case XK_Return: return '\r'; - case XK_Linefeed: return '\n'; - - /* modifiers should not trigger key presses */ - case XK_Scroll_Lock: - case XK_Shift_L: - case XK_Shift_R: - case XK_Control_L: - case XK_Control_R: - case XK_Caps_Lock: - case XK_Shift_Lock: - case XK_Meta_L: - case XK_Meta_R: - case XK_Alt_L: - case XK_Alt_R: - case XK_Super_L: - case XK_Super_R: - case XK_Hyper_L: - case XK_Hyper_R: - return RUNE_ERR; - - /* if it ain't special, don't touch it */ - default: - return key; - } -} - -static uint32_t getkey(XEvent* e) { - uint32_t rune = RUNE_ERR; - size_t len = 0; - char buf[8]; - KeySym key; - Status status; - /* Read the key string */ - if (X.xic) - len = Xutf8LookupString(X.xic, &(e->xkey), buf, sizeof(buf), &key, &status); - else - len = XLookupString(&(e->xkey), buf, sizeof(buf), &key, 0); - /* if it's ascii, just return it */ - if (key >= 0x20 && key <= 0x7F) - return (uint32_t)key; - /* decode it */ - if (len > 0) { - len = 0; - for (int i = 0; i < 8 && !utf8decode(&rune, &len, buf[i]); i++); - } - /* translate special key codes into unicode codepoints */ - rune = special_keys(key); - return rune; -} - -static void handle_key(XEvent* event) { - uint32_t key = getkey(event); - KeyBtnState = event->xkey.state; - if (key == RUNE_ERR) return; - Config->handle_key(KeyBtnState, key); -} - -static void handle_mouse(XEvent* e) { - KeyBtnState = e->xbutton.state; - int x = e->xbutton.x; - int y = e->xbutton.y; - - if (e->type == MotionNotify) { - Config->mouse_drag(KeyBtnState, x, y); - } else { - if (e->type == ButtonRelease) - KeyBtnState &= ~(1 << (e->xbutton.button + 7)); - else - KeyBtnState |= (1 << (e->xbutton.button + 7)); - Config->mouse_btn(e->xbutton.button, (e->type == ButtonPress), x, y); - } -} - -static void set_focus(bool focused) { - if (focused) { - if (X.xic) XSetICFocus(X.xic); - } else { - if (X.xic) XUnsetICFocus(X.xic); - } - Config->set_focus(focused); -} - -void x11_handle_event(XEvent* e) { - Atom wmDeleteMessage = XInternAtom(X.display, "WM_DELETE_WINDOW", False); - switch (e->type) { - case FocusIn: set_focus(true); break; - case FocusOut: set_focus(false); break; - case KeyPress: handle_key(e); break; - case ButtonRelease: handle_mouse(e); break; - case ButtonPress: handle_mouse(e); break; - case MotionNotify: handle_mouse(e); break; - case SelectionClear: selclear(e); break; - case SelectionNotify: selnotify(e); break; - case SelectionRequest: selrequest(e); break; - case ClientMessage: - if (e->xclient.data.l[0] == wmDeleteMessage) - Config->shutdown(); - break; - case ConfigureNotify: // Resize the window - if (e->xconfigure.width != X.width || e->xconfigure.height != X.height) { - X.width = e->xconfigure.width; - X.height = e->xconfigure.height; - X.pixmap = XCreatePixmap(X.display, X.window, X.width, X.height, X.depth); - X.xft = XftDrawCreate(X.display, X.pixmap, X.visual, X.colormap); - } - break; - } -} - -int x11_events_queued(void) { - return XEventsQueued(X.display, QueuedAfterFlush); -} - -bool x11_events_await(unsigned int ms) { - fd_set fds; - int xfd = ConnectionNumber(X.display), redraw = 1; - /* configure for 100ms timeout */ - struct timeval tv = { .tv_usec = ms * 1000 }; - FD_ZERO(&fds); - FD_SET(xfd, &fds); - return (select(xfd+1, &fds, NULL, NULL, &tv) > 0); -} - -void x11_events_take(void) { - XEvent e; - int nevents; - XGetMotionEvents(X.display, X.window, CurrentTime, CurrentTime, &nevents); - while (XPending(X.display)) { - XNextEvent(X.display, &e); - if (!XFilterEvent(&e, None)) - x11_handle_event(&e); - } -} - -void x11_mouse_set(int x, int y) { - XWarpPointer(X.display, X.window, X.window, 0, 0, X.width, X.height, x, y); -} - -void x11_mouse_get(int* ptrx, int* ptry) { - Window xw; int x; unsigned int ux; - XQueryPointer(X.display, X.window, &xw, &xw, &x, &x, ptrx, ptry, &ux); -} - -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"); - FcPattern* pattern = FcNameParse((FcChar8 *)name); - if (!pattern) - die("can't open font %s\n", name); - - /* load the base font */ - FcResult result; - FcPattern* match = XftFontMatch(X.display, X.screen, pattern, &result); - if (!match || !(font->base.match = XftFontOpenPattern(X.display, match))) - die("could not load default font: %s", name); - - /* get base font extents */ - XGlyphInfo extents; - const FcChar8 ascii[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; - XftTextExtentsUtf8(X.display, font->base.match, ascii, sizeof(ascii), &extents); - font->base.set = NULL; - font->base.pattern = FcPatternDuplicate(pattern); - font->base.ascent = font->base.match->ascent; - font->base.descent = font->base.match->descent; - 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 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) { - spec->font = font->base.match; - spec->glyph = glyphidx; - return; - } - /* Otherwise check the cache */ - for (int f = 0; f < font->ncached; f++) { - glyphidx = XftCharIndex(X.display, font->cache[f].font, rune); - /* Fond a suitable font or found a default font */ - if (glyphidx || (!glyphidx && font->cache[f].unicodep == rune)) { - spec->font = font->cache[f].font; - spec->glyph = glyphidx; - return; - } - } - /* if all other options fail, ask fontconfig for a suitable font */ - FcResult fcres; - if (!font->base.set) - font->base.set = FcFontSort(0, font->base.pattern, 1, 0, &fcres); - FcFontSet* fcsets[] = { font->base.set }; - FcPattern* fcpattern = FcPatternDuplicate(font->base.pattern); - FcCharSet* fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, rune); - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); - FcConfigSubstitute(0, fcpattern, FcMatchPattern); - FcDefaultSubstitute(fcpattern); - FcPattern* fontmatch = FcFontSetMatch(0, fcsets, 1, fcpattern, &fcres); - /* add the font to the cache and use it */ - if (font->ncached >= FontCacheSize) { - font->ncached = FontCacheSize - 1; - XftFontClose(X.display, font->cache[font->ncached].font); - } - font->cache[font->ncached].font = XftFontOpenPattern(X.display, fontmatch); - font->cache[font->ncached].unicodep = rune; - spec->glyph = XftCharIndex(X.display, font->cache[font->ncached].font, rune); - spec->font = font->cache[font->ncached].font; - font->ncached++; - FcPatternDestroy(fcpattern); - FcCharSetDestroy(fccharset); -} - -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, winy = y; - size_t numspecs = 0; - for (int i = 0, xp = winx, yp = winy + font->base.ascent; i < len;) { - x11_font_getglyph(font, &(specs[numspecs]), glyphs[i].rune); - specs[numspecs].x = xp; - specs[numspecs].y = yp; - xp += font->base.width; - numspecs++; - i++; - /* skip over null chars which mark multi column runes */ - for (; i < len && !glyphs[i].rune; i++) - xp += font->base.width; - } - return numspecs; -} - -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) + LineSpacing; - xftcolor(&bgc, Config->palette[bg]); - size_t width = specs[nspecs-1].x - specs[0].x + w; - x11_draw_rect(bg, specs[0].x, specs[0].y - h, width, font->height + LineSpacing); - XftColorFree(X.display, X.visual, X.colormap, &bgc); - } - xftcolor(&fgc, Config->palette[fg]); - XftDrawGlyphFontSpec(X.xft, &fgc, (XftGlyphFontSpec*)specs, nspecs); - XftColorFree(X.display, X.visual, X.colormap, &fgc); -} - -void x11_draw_utf8(XFont fnt, int fg, int bg, int x, int y, char* str) { - struct XFont* font = fnt; - static XftGlyphFontSpec specs[256]; - size_t nspecs = 0; - while (*str && nspecs < 256) { - x11_font_getglyph(font, (XGlyphSpec*)&(specs[nspecs]), *str); - specs[nspecs].x = x; - specs[nspecs].y = y; - x += font->base.width; - nspecs++; - str++; - } - x11_draw_glyphs(fg, bg, (XGlyphSpec*)specs, nspecs); -} - -/* Selection Handling - *****************************************************************************/ - -static char* readprop(Display* disp, Window win, Atom prop) { - Atom type; - int format; - unsigned long nitems, nleft; - unsigned char* ret = NULL; - int nread = 1024; - - // Read the property in progressively larger chunks until the entire - // property has been read (nleft == 0) - do { - if (ret) XFree(ret); - XGetWindowProperty(disp, win, prop, 0, nread, False, AnyPropertyType, - &type, &format, &nitems, &nleft, - &ret); - nread *= 2; - } while (nleft != 0); - - return (char*)ret; -} - -static struct XSel* selfetch(Atom atom) { - for (int i = 0; i < (sizeof(Selections) / sizeof(Selections[0])); i++) - if (atom == Selections[i].atom) - return &Selections[i]; - return NULL; -} - -static void selclear(XEvent* evnt) { - struct XSel* sel = selfetch(evnt->xselectionrequest.selection); - if (!sel) return; - free(sel->text); - sel->text = NULL; -} - -static void selnotify(XEvent* evnt) { - /* bail if the selection cannot be converted */ - if (evnt->xselection.property == None) - return; - struct XSel* sel = selfetch( evnt->xselection.selection ); - char* propdata = readprop(X.display, X.window, sel->atom); - if (evnt->xselection.target == SelTarget) { - void(*cbfn)(char*) = sel->callback; - sel->callback = NULL; - cbfn(propdata); - } - /* cleanup */ - if (propdata) XFree(propdata); -} - -static void selrequest(XEvent* evnt) { - XEvent s; - struct XSel* sel = selfetch( evnt->xselectionrequest.selection ); - s.xselection.type = SelectionNotify; - s.xselection.property = evnt->xselectionrequest.property; - s.xselection.requestor = evnt->xselectionrequest.requestor; - s.xselection.selection = evnt->xselectionrequest.selection; - s.xselection.target = evnt->xselectionrequest.target; - s.xselection.time = evnt->xselectionrequest.time; - - Atom target = evnt->xselectionrequest.target; - Atom xatargets = XInternAtom(X.display, "TARGETS", 0); - Atom xastring = XInternAtom(X.display, "STRING", 0); - if (target == xatargets) { - /* respond with the supported type */ - XChangeProperty( - X.display, - s.xselection.requestor, - s.xselection.property, - XA_ATOM, 32, PropModeReplace, - (unsigned char*)&SelTarget, 1); - } else if (target == SelTarget || target == xastring) { - XChangeProperty( - X.display, - s.xselection.requestor, - s.xselection.property, - SelTarget, 8, PropModeReplace, - (unsigned char*)sel->text, strlen(sel->text)); - } - XSendEvent(X.display, s.xselection.requestor, True, 0, &s); -} - -bool x11_sel_get(int selid, void(*cbfn)(char*)) { - struct XSel* sel = &(Selections[selid]); - if (sel->callback) return false; - Window owner = XGetSelectionOwner(X.display, sel->atom); - if (owner == X.window) { - cbfn(sel->text); - } else if (owner != None){ - sel->callback = cbfn; - XConvertSelection(X.display, sel->atom, SelTarget, sel->atom, X.window, CurrentTime); - } - return true; -} - -bool x11_sel_set(int selid, char* str) { - struct XSel* sel = &(Selections[selid]); - if (!sel || !str || !*str) { - free(str); - return false; - } else { - sel->text = str; - XSetSelectionOwner(X.display, sel->atom, X.window, CurrentTime); - return true; - } -} diff --git a/xedit.sync-conflict-20170524-185737.c b/xedit.sync-conflict-20170524-185737.c deleted file mode 100644 index 0897ea9..0000000 --- a/xedit.sync-conflict-20170524-185737.c +++ /dev/null @@ -1,526 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -typedef struct { - char* tag; - union { - void (*noarg)(void); - void (*arg)(char* arg); - } action; -} Tag; - -/* The shell: Filled in with $SHELL. Used to execute commands */ -static char* ShellCmd[] = { NULL, "-c", NULL, NULL }; -static char* SedCmd[] = { "sed", "-e", NULL, NULL }; -static char* PickFileCmd[] = { "xfilepick", ".", NULL }; -static char* PickTagCmd[] = { "xtagpick", NULL, "tags", NULL, NULL }; -static char* OpenCmd[] = { "xedit", NULL, NULL }; -static Tag Builtins[]; -static int SearchDir = DOWN; -static char* SearchTerm = NULL; - -/* Tag/Cmd Execution - ******************************************************************************/ -static Tag* tag_lookup(char* cmd) { - size_t len = 0; - Tag* tags = Builtins; - for (char* tag = cmd; *tag && !isspace(*tag); tag++, len++); - while (tags->tag) { - if (!strncmp(tags->tag, cmd, len)) - return tags; - tags++; - } - return NULL; -} - -static void tag_exec(Tag* tag, char* arg) { - /* if we didnt get an arg, find one in the selection */ - if (!arg) arg = view_getstr(win_view(TAGS), NULL); - if (!arg) arg = view_getstr(win_view(EDIT), NULL); - /* execute the tag handler */ - tag->action.arg(arg); - free(arg); -} - -static void cmd_exec(char* cmd) { - char op = '\0'; - if (*cmd == ':' || *cmd == '!' || *cmd == '<' || *cmd == '|' || *cmd == '>') - op = *cmd, cmd++; - ShellCmd[2] = cmd; - /* execute the command */ - char *input = NULL, *output = NULL, *error = NULL; - WinRegion dest = EDIT; - if (op && op != '<' && op != '!' && 0 == view_selsize(win_view(EDIT))) - win_view(EDIT)->selection = (Sel){ .beg = 0, .end = buf_end(win_buf(EDIT)) }; - input = view_getstr(win_view(EDIT), NULL); - - if (op == '!') { - cmdrun(ShellCmd, NULL); - } else if (op == '>') { - dest = TAGS; - output = cmdwriteread(ShellCmd, input, &error); - } else if (op == '|') { - output = cmdwriteread(ShellCmd, input, &error); - } else if (op == ':') { - SedCmd[2] = cmd; - output = cmdwriteread(SedCmd, input, &error); - } else { - if (op != '<') dest = win_getregion(); - output = cmdread(ShellCmd, &error); - } - - if (error) - view_append(win_view(TAGS), chomp(error)); - - if (output) { - if (op == '>') - view_append(win_view(dest), chomp(output)); - else - view_putstr(win_view(dest), output); - win_setregion(dest); - } - /* cleanup */ - free(input); - free(output); - free(error); -} - -static void exec(char* cmd) { - /* skip leading space */ - for (; *cmd && isspace(*cmd); cmd++); - if (!*cmd) return; - /* see if it matches a builtin tag */ - Tag* tag = tag_lookup(cmd); - if (tag) { - while (*cmd && !isspace(*cmd++)); - tag_exec(tag, (*cmd ? stringdup(cmd) : NULL)); - } else { - cmd_exec(cmd); - } -} - -/* Action Callbacks - ******************************************************************************/ -static void onerror(char* msg) { - view_append(win_view(TAGS), msg); -} - -static void trim_whitespace(void) { - Buf* buf = win_buf(EDIT); - if (TrimOnSave && buf_end(buf) > 0) { - View* view = win_view(EDIT); - unsigned off = 0, prev = 1; - /* loop through the buffer till we hit the end or we stop advancing */ - while (off < buf_end(buf) && prev != off) { - off = buf_eol(buf, off); - Rune r = buf_get(buf, off-1); - for (; (r == ' ' || r == '\t'); r = buf_get(buf, off-1)) { - if (off <= view->selection.beg) { - view->selection.end--; - view->selection.beg--; - } - off = buf_delete(buf, off-1, off); - } - /* make sure we keep advancing */ - prev = off; - off = buf_byline(buf, off, +1); - } - } -} - -static void quit(void) { - static uint64_t before = 0; - uint64_t now = getmillis(); - if (!win_buf(EDIT)->modified || (now-before) <= 250) { - #ifndef TEST - x11_deinit(); - #else - exit(0); - #endif - } else { - view_append(win_view(TAGS), - "File is modified. Repeat action twice in < 250ms to quit."); - } - before = now; -} - -static bool changed_externally(Buf* buf) { - bool modified = (buf->modtime != modtime(buf->path)); - if (modified) { - view_append(win_view(TAGS), - "File modified externally: Reload, Overwrite, or {SaveAs }"); - } - return modified; -} - -static void overwrite(void) { - trim_whitespace(); - buf_save(win_buf(EDIT)); -} - -static void save(void) { - if (!changed_externally(win_buf(EDIT))) - overwrite(); -} - -static void reload(void) { - view_reload(win_view(EDIT)); -} - -/* Mouse Handling - ******************************************************************************/ -void onmouseleft(WinRegion id, bool pressed, size_t row, size_t col) { - static int count = 0; - static uint64_t before = 0; - if (!pressed) return; - uint64_t now = getmillis(); - count = ((now-before) <= 250 ? count+1 : 1); - before = now; - - if (count == 1) { - if (x11_keymodsset(ModShift)) - view_selext(win_view(id), row, col); - else - view_setcursor(win_view(id), row, col); - } else if (count == 2) { - view_select(win_view(id), row, col); - } else if (count == 3) { - view_selword(win_view(id), row, col); - } -} - -void onmousemiddle(WinRegion id, bool pressed, size_t row, size_t col) { - if (pressed) return; - if (win_btnpressed(MouseLeft)) { - cut(); - } else { - char* str = view_fetch(win_view(id), row, col); - if (str) exec(str); - free(str); - } -} - -void onmouseright(WinRegion id, bool pressed, size_t row, size_t col) { - if (pressed) return; - if (win_btnpressed(MouseLeft)) { - paste(); - } else { - SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1); - free(SearchTerm); - SearchTerm = view_fetch(win_view(id), row, col); - if (view_findstr(win_view(EDIT), SearchDir, SearchTerm)) { - win_setregion(EDIT); - win_warpptr(EDIT); - } - } -} - -/* Keyboard Handling - ******************************************************************************/ -static void saveas(char* arg) { - if (arg) { - char* path = win_buf(EDIT)->path; - win_buf(EDIT)->path = stringdup(arg); - buf_save(win_buf(EDIT)); - free(path); - } -} - -static void tag_undo(void) { - view_undo(win_view(EDIT)); -} - -static void tag_redo(void) { - view_redo(win_view(EDIT)); -} - -static void search(void) { - char* str; - SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1); - if (x11_keymodsset(ModAlt) && SearchTerm) - str = stringdup(SearchTerm); - else - str = view_getctx(win_view(FOCUSED)); - view_findstr(win_view(EDIT), SearchDir, str); - free(SearchTerm); - SearchTerm = str; - if (view_selsize(win_view(EDIT))) { - win_setregion(EDIT); - win_warpptr(EDIT); - } -} - -static void execute(void) { - char* str = view_getcmd(win_view(FOCUSED)); - if (str) exec(str); - free(str); -} - -static void find(char* arg) { - SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1); - view_findstr(win_view(EDIT), SearchDir, arg); -} - -static void open_file(void) { - char* file = cmdread(PickFileCmd, NULL); - if (file) { - file = chomp(file); - if (!win_buf(EDIT)->path && !win_buf(EDIT)->modified) { - buf_load(win_buf(EDIT), file); - } else { - OpenCmd[1] = file; - cmdrun(OpenCmd, NULL); - } - } - free(file); -} - -static void pick_symbol(char* symbol) { - PickTagCmd[1] = "fetch"; - PickTagCmd[3] = symbol; - char* pick = cmdread(PickTagCmd, NULL); - if (pick) { - Buf* buf = win_buf(EDIT); - if (buf->path && 0 == strncmp(buf->path, pick, strlen(buf->path))) { - view_setln(win_view(EDIT), strtoul(strrchr(pick, ':')+1, NULL, 0)); - win_setregion(EDIT); - } else { - if (!buf->path && !buf->modified) { - view_init(win_view(EDIT), pick, onerror); - } else { - OpenCmd[1] = chomp(pick); - cmdrun(OpenCmd, NULL); - } - } - } -} - -static void pick_ctag(void) { - pick_symbol(NULL); -} - -static void complete(void) { - View* view = win_view(FOCUSED); - buf_getword(&(view->buffer), risword, &(view->selection)); - view->selection.end = buf_byrune(&(view->buffer), view->selection.end, RIGHT); - PickTagCmd[1] = "print"; - PickTagCmd[3] = view_getstr(view, NULL); - char* pick = cmdread(PickTagCmd, NULL); - if (pick) - view_putstr(view, chomp(pick)); - free(PickTagCmd[3]); -} - -static void jump_to(char* arg) { - if (arg) { - size_t line = strtoul(arg, NULL, 0); - if (line) { - view_setln(win_view(EDIT), line); - win_setregion(EDIT); - } else { - pick_symbol(arg); - } - } -} - -static void goto_ctag(void) { - char* str = view_getctx(win_view(FOCUSED)); - jump_to(str); - free(str); -} - -static void tabs(void) { - bool enabled = !(win_buf(EDIT)->expand_tabs); - win_buf(EDIT)->expand_tabs = enabled; - win_buf(TAGS)->expand_tabs = enabled; -} - -static void indent(void) { - bool enabled = !(win_buf(EDIT)->copy_indent); - win_buf(EDIT)->copy_indent = enabled; - win_buf(TAGS)->copy_indent = enabled; -} - -static void del_indent(void) { - view_indent(win_view(FOCUSED), LEFT); -} - -static void add_indent(void) { - view_indent(win_view(FOCUSED), RIGHT); -} - -static void eol_mode(void) { - int crlf = win_buf(EDIT)->crlf; - win_buf(EDIT)->crlf = !crlf; - win_buf(TAGS)->crlf = !crlf; - exec(crlf ? "|dos2unix" : "|unix2dos"); -} - -static void new_win(void) { - cmd_exec("!edit"); -} - -static void newline(void) { - View* view = win_view(FOCUSED); - if (x11_keymodsset(ModShift)) { - view_byline(view, UP, false); - view_bol(view, false); - if (view->selection.end == 0) { - view_insert(view, true, '\n'); - view->selection = (Sel){0,0,0}; - return; - } - } - view_eol(view, false); - view_insert(view, true, '\n'); -} - -void highlight(void) { - view_selctx(win_view(FOCUSED)); -} - -/* Main Routine - ******************************************************************************/ -static Tag Builtins[] = { - { .tag = "Cut", .action.noarg = cut }, - { .tag = "Copy", .action.noarg = copy }, - { .tag = "Eol", .action.noarg = eol_mode }, - { .tag = "Find", .action.arg = find }, - { .tag = "GoTo", .action.arg = jump_to }, - { .tag = "Indent", .action.noarg = indent }, - { .tag = "Overwrite", .action.noarg = overwrite }, - { .tag = "Paste", .action.noarg = paste }, - { .tag = "Quit", .action.noarg = quit }, - { .tag = "Redo", .action.noarg = tag_redo }, - { .tag = "Reload", .action.noarg = reload }, - { .tag = "Save", .action.noarg = save }, - { .tag = "SaveAs", .action.arg = saveas }, - { .tag = "Tabs", .action.noarg = tabs }, - { .tag = "Undo", .action.noarg = tag_undo }, - { .tag = NULL, .action.noarg = NULL } -}; - -static KeyBinding Bindings[] = { - /* Cursor Movements */ - { ModAny, KEY_HOME, cursor_home }, - { ModAny, KEY_END, cursor_end }, - { ModAny, KEY_UP, cursor_up }, - { ModAny, KEY_DOWN, cursor_dn }, - { ModAny, KEY_LEFT, cursor_left }, - { ModAny, KEY_RIGHT, cursor_right }, - - /* Standard Unix Shortcuts */ - { ModCtrl, 'u', del_to_bol }, - { ModCtrl, 'k', del_to_eol }, - { ModCtrl, 'w', del_to_bow }, - { ModCtrl, 'a', cursor_bol }, - { ModCtrl, 'e', cursor_eol }, - - /* Standard Text Editing Shortcuts */ - { ModCtrl, 's', save }, - { ModCtrl, 'z', undo }, - { ModCtrl, 'y', redo }, - { ModCtrl, 'x', cut }, - { ModCtrl, 'c', copy }, - { ModCtrl, 'v', paste }, - { ModCtrl, 'j', join_lines }, - { ModCtrl, 'l', select_line }, - - /* Block Indent */ - { ModCtrl, '[', del_indent }, - { ModCtrl, ']', add_indent }, - - /* Common Special Keys */ - { ModNone, KEY_PGUP, page_up }, - { ModNone, KEY_PGDN, page_dn }, - { ModAny, KEY_DELETE, delete }, - { ModAny, KEY_BACKSPACE, backspace }, - - /* Implementation Specific */ - { ModNone, KEY_ESCAPE, select_prev }, - { ModCtrl, 't', change_focus }, - { ModCtrl, 'q', quit }, - { ModCtrl, 'h', highlight }, - { ModCtrl, 'f', search }, - { ModCtrl|ModShift, 'f', search }, - { ModCtrl|ModAlt, 'f', search }, - { ModCtrl|ModAlt|ModShift, 'f', search }, - { ModCtrl, 'd', execute }, - { ModCtrl, 'o', open_file }, - { ModCtrl, 'p', pick_ctag }, - { ModCtrl, 'g', goto_ctag }, - { ModCtrl, 'n', new_win }, - { ModCtrl, '\n', newline }, - { ModCtrl|ModShift, '\n', newline }, - { ModCtrl, ' ', complete }, - { 0, 0, 0 } -}; - -void onscroll(double percent) { - size_t bend = buf_end(win_buf(EDIT)); - size_t off = (size_t)((double)bend * percent); - view_scrollto(win_view(EDIT), (off >= bend ? bend : off)); -} - -void onfocus(bool focused) { - /* notify the user if the file has changed externally */ - (void)changed_externally(win_buf(EDIT)); -} - -void onupdate(void) { - static char status_bytes[256]; - memset(status_bytes, 0, sizeof(status_bytes)); - char* status = status_bytes; - Buf* buf = win_buf(EDIT); - *(status++) = (buf->charset == BINARY ? 'B' : 'U'); - *(status++) = (buf->crlf ? 'C' : 'N'); - *(status++) = (buf->expand_tabs ? 'S' : 'T'); - *(status++) = (buf->copy_indent ? 'I' : 'i'); - *(status++) = (SearchDir < 0 ? '<' : '>'); - *(status++) = (buf->modified ? '*' : ' '); - *(status++) = ' '; - char* path = (buf->path ? buf->path : "*scratch*"); - size_t remlen = sizeof(status_bytes) - strlen(status_bytes) - 1; - strncat(status, path, remlen); - win_settext(STATUS, status_bytes); - win_view(STATUS)->selection = (Sel){0,0,0}; -} - -void onlayout(void) { - /* calculate and update scroll region */ - View* view = win_view(EDIT); - size_t bend = buf_end(win_buf(EDIT)); - if (bend == 0) bend = 1; - if (!view->rows) return; - size_t vbeg = view->rows[0]->off; - size_t vend = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen; - double scroll_vis = (double)(vend - vbeg) / (double)bend; - double scroll_off = ((double)vbeg / (double)bend); - win_setscroll(scroll_off, scroll_vis); -} - -void onshutdown(void) { - quit(); -} - -#ifndef TEST -int main(int argc, char** argv) { - /* setup the shell */ - ShellCmd[0] = getenv("SHELL"); - if (!ShellCmd[0]) ShellCmd[0] = "/bin/sh"; - /* Create the window and enter the event loop */ - win_window("edit", onerror); - char* tags = getenv("EDITTAGS"); - win_settext(TAGS, (tags ? tags : DEFAULT_TAGS)); - win_setruler(80); - view_init(win_view(EDIT), (argc > 1 ? argv[1] : NULL), onerror); - win_setkeys(Bindings); - win_loop(); - return 0; -} -#endif -- 2.54.0