]> git.mdlowis.com Git - projs/tide.git/commitdiff
Added back in pointer warping logic for search
authorMichael D. Lowis <mike@mdlowis.com>
Sat, 25 Feb 2017 22:18:42 +0000 (17:18 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Sat, 25 Feb 2017 22:18:42 +0000 (17:18 -0500)
TODO.md
inc/win.h
lib/win.c
xedit.c

diff --git a/TODO.md b/TODO.md
index a631aa6035b000e2df425dbbad9a85a15d11d630..c12b6e4534a54ea742bed129d4d6ec4e739f483d 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -16,7 +16,7 @@ Tomorrow-ish:
 * off by one error on scrolling up with wrapped lines
 * add a distinct state for pointer move versus drag
 * Add a SaveAs tag that takes an argument for the filename to save as
-* Add a GoTo tag for ctags lookup and line number jump (or right click magic?)
+* Add a GoTo tag for ctags lookup and line number jump (or right click magic?) 
 * Add a ctrl+space shortcut to autocomplete ctag
 * 100% coverage with unit and unit-integration tests
 
index 5139d77068e5836158d84cd9fefff517fd71cead..0bdf419f4679a23a7a3e3e1ffc368b37bfa8caed 100644 (file)
--- a/inc/win.h
+++ b/inc/win.h
@@ -37,6 +37,7 @@ void win_loop(void);
 void win_settext(WinRegion id, char* text);\r
 void win_setkeys(KeyBinding* bindings);\r
 void win_setmouse(MouseConfig* mconfig);\r
+void win_warpptr(WinRegion id);\r
 View* win_view(WinRegion id);\r
 Buf* win_buf(WinRegion id);\r
 Sel* win_sel(WinRegion id);\r
index a3d642fbd2e96a2b2135b105eaf8473afe50b15d..7588d104806f405cb8574fa118df5de78d5e2c0a 100644 (file)
--- a/lib/win.c
+++ b/lib/win.c
-#include <stdc.h>\r
-#include <utf.h>\r
-#include <edit.h>\r
-#include <x11.h>\r
-#include <win.h>\r
-#include <ctype.h>\r
-\r
-typedef struct {\r
-    uint64_t time;\r
-    uint8_t count;\r
-    bool pressed;\r
-    int region;\r
-} ButtonState;\r
-\r
-static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t rlen, size_t ncols);\r
-static WinRegion getregion(size_t x, size_t y);\r
-static void onredraw(int height, int width);\r
-static void oninput(int mods, Rune key);\r
-static void onmouse(MouseAct act, MouseBtn btn, int x, int y);\r
-static void onshutdown(void);\r
-static void mouse_wheelup(WinRegion id, size_t count, size_t row, size_t col);\r
-static void mouse_wheeldn(WinRegion id, size_t count, size_t row, size_t col);\r
-\r
-static XFont Font;\r
-static XConfig Config = {\r
-    .redraw       = onredraw,\r
-    .handle_key   = oninput,\r
-    .handle_mouse = onmouse,\r
-    .shutdown     = onshutdown,\r
-    .palette      = COLOR_PALETTE\r
-};\r
-\r
-void (*MouseActs[MOUSE_BTN_COUNT])(WinRegion id, size_t count, size_t row, size_t col) = {\r
-    [MOUSE_BTN_LEFT]      = mouse_left,\r
-    [MOUSE_BTN_MIDDLE]    = mouse_middle,\r
-    [MOUSE_BTN_RIGHT]     = mouse_right,\r
-    [MOUSE_BTN_WHEELUP]   = mouse_wheelup,\r
-    [MOUSE_BTN_WHEELDOWN] = mouse_wheeldn,\r
-};\r
-\r
-static WinRegion Focused = EDIT;\r
-static Region Regions[NREGIONS] = {0};\r
-static ButtonState MouseBtns[MOUSE_BTN_COUNT] = {0};\r
-KeyBinding* Keys = NULL;\r
-\r
-void win_init(char* name) {\r
-    for (int i = 0; i < SCROLL; i++)\r
-        view_init(&(Regions[i].view), NULL);\r
-    x11_init(&Config);\r
-    Font = x11_font_load(FONTNAME);\r
-    x11_window(name, Width, Height);\r
-}\r
-\r
-void win_loop(void) {\r
-    x11_show();\r
-    x11_loop();\r
-}\r
-\r
-void win_settext(WinRegion id, char* text) {\r
-    View* view = win_view(id);\r
-    view->buffer.gapstart = view->buffer.bufstart;\r
-    view->buffer.gapend   = view->buffer.bufend;\r
-    view->selection = (Sel){0,0,0};\r
-    view_putstr(view, text);\r
-    view_selprev(view); // clear the selection\r
-    buf_logclear(&(view->buffer));\r
-}\r
-\r
-void win_setkeys(KeyBinding* bindings) {\r
-    Keys = bindings;\r
-}\r
-\r
-bool win_btnpressed(MouseBtn btn) {\r
-    return MouseBtns[btn].pressed;\r
-}\r
-\r
-WinRegion win_getregion(void) {\r
-    return Focused;\r
-}\r
-\r
-void win_setregion(WinRegion id) {\r
-    Focused = id;\r
-}\r
-\r
-View* win_view(WinRegion id) {\r
-    if (id == FOCUSED) id = Focused;\r
-    return &(Regions[id].view);\r
-}\r
-\r
-Buf* win_buf(WinRegion id) {\r
-    if (id == FOCUSED) id = Focused;\r
-    return &(Regions[id].view.buffer);\r
-}\r
-\r
-Sel* win_sel(WinRegion id) {\r
-    if (id == FOCUSED) id = Focused;\r
-    return &(Regions[id].view.selection);\r
-}\r
-\r
-static void layout(int width, int height) {\r
-    size_t fheight = x11_font_height(Font);\r
-    size_t fwidth  = x11_font_width(Font);\r
-    View* statview = win_view(STATUS);\r
-    View* tagview  = win_view(TAGS);\r
-    View* editview = win_view(EDIT);\r
-    \r
-    /* update the text views and region positions and sizes */\r
-    for (int i = 0; i < SCROLL; i++) {\r
-        Regions[i].x      = 2;\r
-        Regions[i].y      = 2;\r
-        Regions[i].csrx   = SIZE_MAX;\r
-        Regions[i].csry   = SIZE_MAX;\r
-        Regions[i].width  = (width - 4);\r
-        Regions[i].height = fheight;\r
-    }\r
-    \r
-    /* place the status region */\r
-    view_resize(statview, 1, Regions[STATUS].width / fwidth);\r
-    view_update(statview, &(Regions[STATUS].csrx), &(Regions[STATUS].csry));\r
-    \r
-    /* Place the tag region relative to status */\r
-    Regions[TAGS].y = 5 + Regions[STATUS].y + Regions[STATUS].height;\r
-    size_t maxtagrows = ((height - Regions[TAGS].y - 5) / 4) / fheight;\r
-    size_t tagcols    = Regions[TAGS].width / fwidth;\r
-    size_t tagrows    = view_limitrows(tagview, maxtagrows, tagcols);\r
-    Regions[TAGS].height = tagrows * fheight;\r
-    view_resize(tagview, tagrows, tagcols);\r
-    view_update(tagview, &(Regions[TAGS].csrx), &(Regions[TAGS].csry));\r
-    \r
-    /* Place the edit region relative to status */\r
-    Regions[EDIT].y      = 5 + Regions[TAGS].y + Regions[TAGS].height;\r
-    Regions[EDIT].height = (height - Regions[EDIT].y - 5);\r
-    view_resize(editview, Regions[EDIT].height / fheight, Regions[EDIT].width / fwidth);\r
-    view_update(editview, &(Regions[EDIT].csrx), &(Regions[EDIT].csry));\r
-}\r
-\r
-static void onredraw(int width, int height) {\r
-    size_t fheight = x11_font_height(Font);\r
-    size_t fwidth  = x11_font_width(Font);\r
-    onupdate(); // Let the user program update the status and such\r
-    /* layout and draw the three text regions */\r
-    layout(width, height);\r
-    for (int i = 0; i < SCROLL; i++) {\r
-        View* view = win_view(i);\r
-        x11_draw_rect((i == TAGS ? CLR_BASE02 : CLR_BASE03), \r
-            0, Regions[i].y - 3, width, Regions[i].height + 8);\r
-        x11_draw_rect(CLR_BASE01, 0, Regions[i].y - 3, Regions[i].width + 4, 1);\r
-        for (size_t y = 0; y < view->nrows; y++) {\r
-            Row* row = view_getrow(view, y);\r
-            draw_glyphs(Regions[i].x, Regions[i].y + ((y+1) * fheight), row->cols, row->rlen, row->len);\r
-        }\r
-    }\r
-    \r
-    /* draw the scroll region */\r
-    \r
-    /* place the cursor on screen */\r
-    x11_draw_rect(CLR_BASE3, \r
-        Regions[Focused].x + (Regions[Focused].csrx * fwidth), \r
-        Regions[Focused].y + (Regions[Focused].csry * fheight), \r
-        1, fheight);\r
-    \r
-    /* adjust the mouse location */\r
-    if (Regions[Focused].warp_ptr) {\r
-        Regions[Focused].warp_ptr = false;\r
-        size_t x = Regions[Focused].x + (Regions[Focused].csrx * fwidth)  - (fwidth/2);\r
-        size_t y = Regions[Focused].y + (Regions[Focused].csry * fheight) + (fheight/2);\r
-        x11_warp_mouse(x,y);\r
-    }\r
-}\r
-\r
-static void oninput(int mods, Rune key) {\r
-    /* handle the proper line endings */\r
-    if (key == '\r') key = '\n';\r
-    if (key == '\n' && win_view(FOCUSED)->buffer.crlf) key = RUNE_CRLF;\r
-    /* search for a key binding entry */\r
-    uint32_t mkey = tolower(key);\r
-    for (KeyBinding* bind = Keys; bind && bind->key; bind++) {\r
-        if ((mkey == bind->key) && (bind->mods == ModAny || bind->mods == mods)) {\r
-            bind->action();\r
-            return;\r
-        }\r
-    }\r
-    \r
-    /* fallback to just inserting the rune if it doesn't fall in the private use area.\r
-     * the private use area is used to encode special keys */\r
-    if (key < 0xE000 || key > 0xF8FF)\r
-        view_insert(win_view(FOCUSED), true, key);\r
-}\r
-\r
-static void onmouse(MouseAct act, MouseBtn btn, int x, int y) {\r
-    WinRegion id = getregion(x, y);\r
-    size_t row = (y-Regions[id].y) / x11_font_height(Font);\r
-    size_t col = (x-Regions[id].x) / x11_font_width(Font);\r
-    if (act == MOUSE_ACT_MOVE) {\r
-        if (MouseBtns[MOUSE_BTN_LEFT].pressed) {\r
-            WinRegion selid = MouseBtns[MOUSE_BTN_LEFT].region;\r
-            if (MouseBtns[MOUSE_BTN_LEFT].count == 1) {\r
-                view_setcursor(win_view(selid), row, col);\r
-                MouseBtns[MOUSE_BTN_LEFT].count = 0;\r
-            } else {\r
-                view_selext(win_view(selid), row, col);\r
-            }\r
-        } else if (id == TAGS || id == EDIT) {\r
-            Focused = id;\r
-        }\r
-    } else {\r
-        MouseBtns[btn].pressed = (act == MOUSE_ACT_DOWN);\r
-        if (MouseBtns[btn].pressed) {\r
-            /* update the number of clicks and click time */\r
-            uint32_t now = getmillis();\r
-            uint32_t elapsed = now - MouseBtns[btn].time;\r
-            MouseBtns[btn].time = now;\r
-            MouseBtns[btn].region = id;\r
-            if (elapsed <= 250)\r
-                MouseBtns[btn].count++;\r
-            else\r
-                MouseBtns[btn].count = 1;\r
-        } else if (MouseBtns[btn].count > 0) {\r
-            /* execute the action on button release */\r
-            if (MouseActs[btn])\r
-                MouseActs[btn](MouseBtns[btn].region, MouseBtns[btn].count, row, col);\r
-        }\r
-    }\r
-}\r
-\r
-static void onshutdown(void) {\r
-    x11_deinit();\r
-}\r
-\r
-static void mouse_wheelup(WinRegion id, size_t count, size_t row, size_t col) {\r
-    view_scroll(win_view(id), -ScrollLines);\r
-}\r
-\r
-static void mouse_wheeldn(WinRegion id, size_t count, size_t row, size_t col) {\r
-    view_scroll(win_view(id), +ScrollLines);\r
-}\r
-\r
-/*****************************************************************************/\r
-\r
-static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t rlen, size_t ncols) {\r
-    XGlyphSpec specs[rlen];\r
-    size_t i = 0;\r
-    while (rlen && i < ncols) {\r
-        int numspecs = 0;\r
-        uint32_t attr = glyphs[i].attr;\r
-        while (i < ncols && glyphs[i].attr == attr) {\r
-            x11_font_getglyph(Font, &(specs[numspecs]), glyphs[i].rune);\r
-            specs[numspecs].x = x;\r
-            specs[numspecs].y = y - x11_font_descent(Font);\r
-            x += x11_font_width(Font);\r
-            numspecs++;\r
-            i++;\r
-            /* skip over null chars which mark multi column runes */\r
-            for (; i < ncols && !glyphs[i].rune; i++)\r
-                x += x11_font_width(Font);\r
-        }\r
-        /* Draw the glyphs with the proper colors */\r
-        uint8_t bg = attr >> 8;\r
-        uint8_t fg = attr & 0xFF;\r
-        x11_draw_glyphs(fg, bg, specs, numspecs);\r
-        rlen -= numspecs;\r
-    }\r
-}\r
-\r
-static WinRegion getregion(size_t x, size_t y) {\r
-    for (int i = 0; i < NREGIONS; i++) {\r
-        size_t startx = Regions[i].x, endx = startx + Regions[i].width;\r
-        size_t starty = Regions[i].y, endy = starty + Regions[i].height;\r
-        if ((startx <= x && x <= endx) && (starty <= y && y <= endy))\r
-            return (WinRegion)i;\r
-    }\r
-    return NREGIONS;\r
-}\r
-\r
+#include <stdc.h>
+#include <utf.h>
+#include <edit.h>
+#include <x11.h>
+#include <win.h>
+#include <ctype.h>
+
+typedef struct {
+    uint64_t time;
+    uint8_t count;
+    bool pressed;
+    int region;
+} ButtonState;
+
+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 void onredraw(int height, int width);
+static void oninput(int mods, Rune key);
+static void onmouse(MouseAct act, MouseBtn btn, int x, int y);
+static void onshutdown(void);
+static void mouse_wheelup(WinRegion id, size_t count, size_t row, size_t col);
+static void mouse_wheeldn(WinRegion id, size_t count, size_t row, size_t col);
+
+static XFont Font;
+static XConfig Config = {
+    .redraw       = onredraw,
+    .handle_key   = oninput,
+    .handle_mouse = onmouse,
+    .shutdown     = onshutdown,
+    .palette      = COLOR_PALETTE
+};
+
+void (*MouseActs[MOUSE_BTN_COUNT])(WinRegion id, size_t count, size_t row, size_t col) = {
+    [MOUSE_BTN_LEFT]      = mouse_left,
+    [MOUSE_BTN_MIDDLE]    = mouse_middle,
+    [MOUSE_BTN_RIGHT]     = mouse_right,
+    [MOUSE_BTN_WHEELUP]   = mouse_wheelup,
+    [MOUSE_BTN_WHEELDOWN] = mouse_wheeldn,
+};
+
+static WinRegion Focused = EDIT;
+static Region Regions[NREGIONS] = {0};
+static ButtonState MouseBtns[MOUSE_BTN_COUNT] = {0};
+KeyBinding* Keys = NULL;
+
+void win_init(char* name) {
+    for (int i = 0; i < SCROLL; i++)
+        view_init(&(Regions[i].view), NULL);
+    x11_init(&Config);
+    Font = x11_font_load(FONTNAME);
+    x11_window(name, Width, Height);
+}
+
+void win_loop(void) {
+    x11_show();
+    x11_loop();
+}
+
+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_setkeys(KeyBinding* bindings) {
+    Keys = bindings;
+}
+
+bool win_btnpressed(MouseBtn btn) {
+    return MouseBtns[btn].pressed;
+}
+
+WinRegion win_getregion(void) {
+    return Focused;
+}
+
+void win_setregion(WinRegion id) {
+    Focused = id;
+}
+
+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);
+}
+
+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);
+    view_update(statview, &(Regions[STATUS].csrx), &(Regions[STATUS].csry));
+    
+    /* 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);
+    view_update(tagview, &(Regions[TAGS].csrx), &(Regions[TAGS].csry));
+    
+    /* 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);
+    view_update(editview, &(Regions[EDIT].csrx), &(Regions[EDIT].csry));
+}
+
+static void onredraw(int width, int height) {
+    size_t fheight = x11_font_height(Font);
+    size_t fwidth  = x11_font_width(Font);
+    onupdate(); // Let the user program update the status and such
+    /* layout and draw the three text regions */
+    layout(width, height);
+    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);
+        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 */
+    x11_draw_rect(CLR_BASE01, Regions[SCROLL].width, Regions[SCROLL].y-2, 1, Regions[SCROLL].height);
+    
+    /* 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_warp_mouse(x,y);
+    }
+}
+
+static void oninput(int mods, Rune key) {
+    /* handle the proper line endings */
+    if (key == '\r') key = '\n';
+    if (key == '\n' && win_view(FOCUSED)->buffer.crlf) key = RUNE_CRLF;
+    /* 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)
+        view_insert(win_view(FOCUSED), true, key);
+}
+
+static void onmouse(MouseAct act, MouseBtn btn, 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 (act == MOUSE_ACT_MOVE) {
+        if (MouseBtns[MOUSE_BTN_LEFT].pressed) {
+            WinRegion selid = MouseBtns[MOUSE_BTN_LEFT].region;
+            if (MouseBtns[MOUSE_BTN_LEFT].count == 1) {
+                view_setcursor(win_view(selid), row, col);
+                MouseBtns[MOUSE_BTN_LEFT].count = 0;
+            } else {
+                view_selext(win_view(selid), row, col);
+            }
+        } else if (id == TAGS || id == EDIT) {
+            Focused = id;
+        }
+    } else {
+        MouseBtns[btn].pressed = (act == MOUSE_ACT_DOWN);
+        if (MouseBtns[btn].pressed) {
+            /* update the number of clicks and click time */
+            uint32_t now = getmillis();
+            uint32_t elapsed = now - MouseBtns[btn].time;
+            MouseBtns[btn].time = now;
+            MouseBtns[btn].region = id;
+            if (elapsed <= 250)
+                MouseBtns[btn].count++;
+            else
+                MouseBtns[btn].count = 1;
+        } else if (MouseBtns[btn].count > 0) {
+            /* execute the action on button release */
+            if (MouseActs[btn])
+                MouseActs[btn](MouseBtns[btn].region, MouseBtns[btn].count, row, col);
+        }
+    }
+}
+
+static void onshutdown(void) {
+    x11_deinit();
+}
+
+static void mouse_wheelup(WinRegion id, size_t count, size_t row, size_t col) {
+    if (id == SCROLL) id = EDIT;
+    view_scroll(win_view(id), -ScrollLines);
+}
+
+static void mouse_wheeldn(WinRegion id, size_t count, size_t row, size_t col) {
+    if (id == SCROLL) id = EDIT;
+    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/xedit.c b/xedit.c
index 9e4adfb10b19b2013b376959cfabf73573f2bb27..774de5928e2123f57ab222a6f88c4d3cff3bc092 100644 (file)
--- a/xedit.c
+++ b/xedit.c
@@ -179,7 +179,7 @@ void mouse_right(WinRegion id, size_t count, size_t row, size_t col) {
     } else {
         SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1);
         view_find(win_view(id), SearchDir, row, col);
-        //Regions[id].warp_ptr = true;
+        win_warpptr(id);
     }
 }
 
@@ -294,7 +294,8 @@ static void search(void) {
     char* str = view_getctx(win_view(FOCUSED));
     view_findstr(win_view(EDIT), SearchDir, str);
     free(str);
-    //Regions[EDIT].warp_ptr = true;
+    win_setregion(EDIT);
+    win_warpptr(EDIT);
 }
 
 static void execute(void) {