diff options
Diffstat (limited to 'swt.c')
| -rw-r--r-- | swt.c | 193 |
1 files changed, 111 insertions, 82 deletions
@@ -1,4 +1,5 @@ #include <bits/time.h> +#include <linux/input-event-codes.h> #include <sys/mman.h> #include <sys/timerfd.h> #include <unistd.h> @@ -28,6 +29,7 @@ char *argv0; #define TRUEBLUE(x) (((x) & 0xff)) #define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) #define FONTMODE(mode) (mode & ATTR_ITALIC ? (mode & ATTR_BOLD ? FONT_BOLD_ITALIC : FONT_ITALIC) : (mode & ATTR_BOLD ? FONT_BOLD : FONT_NORMAL)) +#define wintotty(scale, type) (scale < 2 * borderpx ? 0 : (scale - 2 * borderpx) / win.fontcache->box.type) #define match_then_bind(obj, inter, ver) \ if (strcmp(interface, inter.name) == 0) { \ obj = wl_registry_bind(registry, name, &inter, ver); @@ -62,6 +64,7 @@ static int matchmod(uint32_t mask, uint32_t mod); static char *kmap(); static void buffer_release(void *data, struct wl_buffer *buffer); static void draw_frame(); +static void draw_glyph(Glyph g, int x, int y); static void commit_surface(); static void surface_configure(void *data, struct xdg_surface *surface, uint32_t serial); static void toplevel_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height, struct wl_array *clients); @@ -160,24 +163,66 @@ void wclipcopy() { } -void wdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { +void +draw_glyph(Glyph g, int x, int y) +{ + uint32_t bg; + uint32_t fg; + + if (selected(x, y)) { + g.mode ^= ATTR_REVERSE; + } + + bg = (g.mode & ATTR_REVERSE) ? colors[g.fg] : colors[g.bg]; + fg = (g.mode & ATTR_REVERSE) ? colors[g.bg] : colors[g.fg]; + + win.fontcache->fonttype = FONTMODE(g.mode); draw_rect( win.canvas, - borderpx + ox * win.fontcache->box.width, - borderpx + oy * win.fontcache->box.height, + borderpx + x * win.fontcache->box.width, + borderpx + y * win.fontcache->box.height, win.fontcache->box.width, win.fontcache->box.height, - colors[og.bg] - ); - win.fontcache->fonttype = FONTMODE(og.mode); + bg + ); + + if (g.mode & ATTR_UNDERLINE) { + draw_rect( + win.canvas, + borderpx + x * win.fontcache->box.width, + borderpx + (y + 1) * win.fontcache->box.height - 1, + win.fontcache->box.width, + 1, + fg + ); + } + draw_char( win.canvas, win.fontcache, - og.u, + g.u, + borderpx + x * win.fontcache->box.width, + borderpx + y * win.fontcache->box.height + win.fontcache->fontsize, + fg + ); +} + + +void +wdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { + draw_rect( + win.canvas, borderpx + ox * win.fontcache->box.width, - borderpx + oy * win.fontcache->box.height + win.fontcache->fontsize, - colors[og.fg] + borderpx + oy * win.fontcache->box.height, + win.fontcache->box.width, + win.fontcache->box.height, + colors[og.bg] ); + draw_glyph(og, ox, oy); + + g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; + g.bg = defaultfg; + g.fg = defaultbg; switch(win.cursor) { case 0: @@ -191,15 +236,7 @@ void wdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { win.fontcache->box.height, colors[defaultcursorcolor] ); - win.fontcache->fonttype = FONTMODE(g.mode); - draw_char( - win.canvas, - win.fontcache, - g.u, - borderpx + cx * win.fontcache->box.width, - borderpx + cy * win.fontcache->box.height + win.fontcache->fontsize, - colors[g.bg] - ); + draw_glyph(g, cx, cy); break; case 3: case 4: @@ -211,15 +248,7 @@ void wdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { cursorthickness, colors[defaultcursorcolor] ); - win.fontcache->fonttype = FONTMODE(g.mode); - draw_char( - win.canvas, - win.fontcache, - g.u, - borderpx + cx * win.fontcache->box.width, - borderpx + cy * win.fontcache->box.height + win.fontcache->fontsize, - colors[g.fg] - ); + draw_glyph(g, cx, cy); break; case 5: case 6: @@ -231,15 +260,7 @@ void wdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { win.fontcache->box.height, colors[defaultcursorcolor] ); - win.fontcache->fonttype = FONTMODE(g.mode); - draw_char( - win.canvas, - win.fontcache, - g.u, - borderpx + cx * win.fontcache->box.width, - borderpx + cy * win.fontcache->box.height + win.fontcache->fontsize, - colors[g.fg] - ); + draw_glyph(g, cx, cy); break; } } @@ -248,46 +269,8 @@ void wdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { void wdrawline(Line line, int x1, int y1, int x2) { int x; - draw_rect( - win.canvas, - borderpx + x1 * win.fontcache->box.width, - borderpx + y1 * win.fontcache->box.height, - x2 * win.fontcache->box.width, - win.fontcache->box.height, - colors[defaultbg] - ); - for (x = x1; x < x2; x++) { - win.fontcache->fonttype = FONTMODE(line[x].mode); - draw_rect( - win.canvas, - borderpx + x * win.fontcache->box.width, - borderpx + y1 * win.fontcache->box.height, - win.fontcache->box.width, - win.fontcache->box.height, - colors[line[x].bg] - ); - - if (line[x].mode & ATTR_UNDERLINE) { - fprintf(stderr, "DRAWING %c\n", line[x].u); - draw_rect( - win.canvas, - borderpx + x * win.fontcache->box.width, - borderpx + (y1 + 1) * win.fontcache->box.height - 1, - win.fontcache->box.width - 2, - 1, - colors[line[x].fg] - ); - } - - draw_char( - win.canvas, - win.fontcache, - line[x].u, - borderpx + x * win.fontcache->box.width, - borderpx + y1 * win.fontcache->box.height + win.fontcache->fontsize, - colors[line[x].fg] - ); + draw_glyph(line[x], x, y1); } } @@ -450,7 +433,6 @@ toplevel_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int tresize(ttywidth, ttyheight); ttyresize(ttywidth, ttyheight); } - } @@ -665,13 +647,54 @@ pointer_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl void pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y) { - wl_surface_commit(client.pointer.surface); + client.pointer.position.x = wl_fixed_to_int(x); + client.pointer.position.y = wl_fixed_to_int(y); + + if (client.pointer.buttons.button & BTN_LEFT) { + selextend( + wintotty(client.pointer.position.x, width), + wintotty(client.pointer.position.y, height), + SEL_REGULAR, + 0 + ); + draw(); + } } void pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { + int snap; + + if (button == BTN_LEFT && state) { + client.pointer.buttons.button |= BTN_LEFT; + + if (client.pointer.buttons.click_combo == 1 && time - client.pointer.buttons.tclick <= doubleclicktimeout) { + snap = SNAP_WORD; + fprintf(stderr, "double\n"); + } else if (client.pointer.buttons.click_combo >= 2 && time - client.pointer.buttons.tclick <= tripleclicktimeout) { + fprintf(stderr, "tripple\n"); + snap = SNAP_LINE; + } else { + client.pointer.buttons.click_combo = 0; + snap = 0; + } + + client.pointer.buttons.tclick = time; + ++client.pointer.buttons.click_combo; + + selstart(wintotty(client.pointer.position.x, width), wintotty(client.pointer.position.y, height), snap); + draw(); + fprintf(stderr, "redraw: %i\n", snap); + } else if (button == BTN_LEFT && !state) { + selextend( + wintotty(client.pointer.position.x, width), + wintotty(client.pointer.position.y, height), + SEL_REGULAR, + 1 + ); + } } @@ -686,6 +709,7 @@ setup() { win.mode = MODE_VISIBLE; win.fontcache = create_font_cache(fonts, sizeof(fonts) / sizeof(FontPath), fontsize); + selinit(); wloadcols(); client.kb.repeat.timer = timerfd_create(CLOCK_MONOTONIC, 0); client.kb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); @@ -715,6 +739,10 @@ setup() client.pointer.surface = wl_compositor_create_surface(client.compositor); wl_surface_attach(client.pointer.surface, client.pointer.buffer, 0, 0); wl_surface_commit(client.pointer.surface); + + + wl_display_roundtrip(client.display); + draw(); } @@ -723,7 +751,7 @@ run() { struct itimerspec spec = { 0 }; struct pollfd fds[3]; - int redraw = 0; + int req_redraw = 0; fds[0].fd = wl_display_get_fd(client.display); fds[0].events = POLLIN; @@ -733,7 +761,7 @@ run() fds[2].events = POLLIN; while (running) { - redraw = 0; + req_redraw = 0; if (wl_display_flush(client.display) < 0) { if (errno == EAGAIN) @@ -750,7 +778,7 @@ run() /* handle ttyfd at first so we have the real current screen */ if (fds[2].revents & POLLIN) { ttyread(); - redraw = 1; + req_redraw = 1; } if (fds[0].revents & POLLIN) { @@ -764,11 +792,12 @@ run() spec.it_value.tv_sec = client.kb.repeat.period / 1000; spec.it_value.tv_nsec = (client.kb.repeat.period % 1000) * 1000000; timerfd_settime(client.kb.repeat.timer, 0, &spec, 0); - redraw = 1; + req_redraw = 1; } - if (redraw) { + if (req_redraw) { draw(); + fprintf(stderr, "redraw\n"); } } } |