Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Commit

Permalink
Merge commit '5cdb5bb582a81ab1bf39bf8c88bf8243e37878e7' of https://gi…
Browse files Browse the repository at this point in the history
  • Loading branch information
paolo-sz committed Apr 21, 2017
2 parents 37487a2 + 5cdb5bb commit 4955e5d
Show file tree
Hide file tree
Showing 16 changed files with 762 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/Makefile
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SRC := charset.c child.c config.c ctrls.c minibidi.c std.c term.c termclip.c \
termline.c termmouse.c termout.c winclip.c winctrls.c windialog.c wininput.c \
winmain.c winprint.c wintext.c wintip.c xcwidth.c \
winmain.c winprint.c wintext.c wintip.c xcwidth.c winsearch.c \
childxx.cc winxx.cc \
res.rc
BIN ?= fatty.exe
Expand Down
10 changes: 10 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const config default_cfg = {
.tab_bg_colour = 0x000000,
.tab_active_bg_colour = 0x323232,
.tab_attention_bg_colour = 0x003200,
.search_fg_colour = 0x000000,
.search_bg_colour = 0x00DDDD,
.search_current_colour = 0x0099DD,
.cursor_colour = 0xBFBFBF,
.transparency = 0,
.opaque_when_focused = false,
Expand All @@ -47,6 +50,7 @@ const config default_cfg = {
.window_shortcuts = true,
.switch_shortcuts = true,
.zoom_shortcuts = true,
.zoom_font_with_window = true,
.alt_fn_shortcuts = true,
.ctrl_shift_shortcuts = false,
.break_string = "",
Expand All @@ -68,6 +72,7 @@ const config default_cfg = {
.scrollback_lines = 10000,
.scroll_mod = MDK_SHIFT,
.pgupdn_scroll = false,
.search_bar = "",
// Terminal
.term = "xterm",
.answerback = "",
Expand Down Expand Up @@ -139,6 +144,9 @@ options[] = {
// Looks
{"ForegroundColour", OPT_COLOUR, offcfg(fg_colour)},
{"BackgroundColour", OPT_COLOUR, offcfg(bg_colour)},
{"SearchForegroundColour", OPT_COLOUR, offcfg(search_fg_colour)},
{"SearchBackgroundColour", OPT_COLOUR, offcfg(search_bg_colour)},
{"SearchCurrentColour", OPT_COLOUR, offcfg(search_current_colour)},
{"CursorColour", OPT_COLOUR, offcfg(cursor_colour)},
{"Transparency", OPT_TRANS, offcfg(transparency)},
{"OpaqueWhenFocused", OPT_BOOL, offcfg(opaque_when_focused)},
Expand Down Expand Up @@ -169,6 +177,7 @@ options[] = {
{"WindowShortcuts", OPT_BOOL, offcfg(window_shortcuts)},
{"SwitchShortcuts", OPT_BOOL, offcfg(switch_shortcuts)},
{"ZoomShortcuts", OPT_BOOL, offcfg(zoom_shortcuts)},
{"ZoomFontWithWindow", OPT_BOOL, offcfg(zoom_font_with_window)},
{"AltFnShortcuts", OPT_BOOL, offcfg(alt_fn_shortcuts)},
{"CtrlShiftShortcuts", OPT_BOOL, offcfg(ctrl_shift_shortcuts)},
{"Break", OPT_STRING, offcfg(break_string)},
Expand All @@ -192,6 +201,7 @@ options[] = {
{"Scrollbar", OPT_SCROLLBAR, offcfg(scrollbar)},
{"ScrollMod", OPT_MOD, offcfg(scroll_mod)},
{"PgUpDnScroll", OPT_BOOL, offcfg(pgupdn_scroll)},
{"SearchBar", OPT_STRING, offcfg(search_bar)},

// Terminal
{"Term", OPT_STRING, offcfg(term)},
Expand Down
3 changes: 3 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ typedef struct {
// Looks
colour fg_colour, bg_colour, cursor_colour;
colour tab_fg_colour, tab_bg_colour, tab_attention_bg_colour, tab_active_bg_colour;
colour search_fg_colour, search_bg_colour, search_current_colour;
char transparency;
bool opaque_when_focused;
char cursor_type;
Expand All @@ -64,6 +65,7 @@ typedef struct {
bool window_shortcuts;
bool switch_shortcuts;
bool zoom_shortcuts;
bool zoom_font_with_window;
bool alt_fn_shortcuts;
bool ctrl_shift_shortcuts;
string break_string;
Expand All @@ -84,6 +86,7 @@ typedef struct {
char scrollbar;
char scroll_mod;
bool pgupdn_scroll;
string search_bar;
// Terminal
string term;
string answerback;
Expand Down
258 changes: 258 additions & 0 deletions src/term.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
// Adapted from code from PuTTY-0.60 by Simon Tatham and team.
// Licensed under the terms of the GNU General Public License v3 or later.

#include <windows.h>
#include <CommCtrl.h>

#include "termpriv.h"

#include "win.h"
#include "charset.h"
#include "child.h"
#include "winsearch.h"

const cattr CATTR_DEFAULT =
{.attr = ATTR_DEFAULT, .truefg = 0, .truebg = 0};
Expand Down Expand Up @@ -163,6 +167,9 @@ term_reset(struct term* term)
term_clear_scrollback(term);

win_reset_colours();

term->searched = false;
term->search_window_visible = false;
}

static void freelines(termlines* lines, int rows) {
Expand Down Expand Up @@ -255,6 +262,247 @@ term_reconfig(struct term* term)
term->vt220_keys = strstr(new_cfg.term, "vt220");
}

bool in_result(struct term* term, pos abspos, pos respos) {
return
(abspos.x + abspos.y * term->cols >= respos.x + respos.y * term->cols) &&
(abspos.x + abspos.y * term->cols < respos.x + respos.y * term->cols + term->results.query_length);
}

bool
in_results_recurse(struct term* term, pos abspos, int lo, int hi) {
if (hi - lo == 0) {
return false;
}
int mid = (lo + hi) / 2;
pos respos = term->results.results[mid];
if (respos.x + respos.y * term->cols > abspos.x + abspos.y * term->cols) {
return in_results_recurse(term, abspos, lo, mid);
} else if (respos.x + respos.y * term->cols + term->results.query_length <= abspos.x + abspos.y * term->cols) {
return in_results_recurse(term, abspos, mid + 1, hi);
}
return true;
}

int
in_results(struct term* term, pos scrpos)
{
if (term->results.length == 0) {
return 0;
}

pos abspos = {
.x = scrpos.x,
.y = scrpos.y + term->sblines
};

int match = in_results_recurse(term, abspos, 0, term->results.length);
match += in_result(term, abspos, term->results.results[term->results.current]);
return match;
}

void
results_add(struct term* term, pos abspos)
{
assert(term->results.capacity > 0);
if (term->results.length == term->results.capacity) {
term->results.capacity *= 2;
term->results.results = renewn(term->results.results, term->results.capacity);
}

term->results.results[term->results.length] = abspos;
++term->results.length;
}

void
results_partial_clear(struct term* term, int pos)
{
int i = term->results.length;
while (i > 0 && term->results.results[i - 1].y >= pos) {
--i;
}
term->results.length = i;
}

void
term_set_search(struct term* term, wchar * needle)
{
free(term->results.query);
term->results.query = needle;

term->results.update_type = FULL_UPDATE;
term->results.query_length = wcslen(needle);
}

void
circbuf_init(circbuf * cb, int sz)
{
cb->capacity = sz;
cb->length = 0;
cb->start = 0;
cb->buf = newn(termline*, sz);
}

void
circbuf_destroy(circbuf * cb)
{
cb->capacity = 0;
cb->length = 0;
cb->start = 0;

// Free any termlines we have left.
for (int i = 0; i < cb->capacity; ++i) {
if (cb->buf[i] == NULL)
continue;
release_line(cb->buf[i]);
}
free(cb->buf);
cb->buf = NULL;
}

void
circbuf_push(circbuf * cb, termline * tl)
{
int pos = (cb->start + cb->length) % cb->capacity;

if (cb->length < cb->capacity) {
++cb->length;
} else {
++cb->start;
release_line(cb->buf[pos]);
}
cb->buf[pos] = tl;
}

termline *
circbuf_get(circbuf * cb, int i)
{
assert(i < cb->length);
return cb->buf[(cb->start + i) % cb->capacity];
}

void
term_update_search(struct term* term)
{
if (term->results.update_type == DISABLE_UPDATE)
return;
if (term->results.update_type == NO_UPDATE)
return;

int update_type = term->results.update_type;
term->results.update_type = NO_UPDATE;

if (term->results.query_length == 0)
return;

circbuf cb;
// Allocate room for the circular buffer of termlines.
int lcurr = 0;
if (update_type == PARTIAL_UPDATE) {
// How much of the backscroll we need to update on a partial update?
// Do a ceil: (x + y - 1) / y
// On query_length - 1
int pstart = -((term->results.query_length + term->cols - 2) / term->cols) + term->sblines;
lcurr = lcurr > pstart ? lcurr:pstart;
results_partial_clear(term, lcurr);
} else {
term_clear_results(term);
}
int llen = term->results.query_length / term->cols + 1;
if (llen < 2)
llen = 2;

circbuf_init(&cb, llen);

// Fill in our starting set of termlines.
for (int i = lcurr; i < term->rows + term->sblines && cb.length < cb.capacity; ++i) {
circbuf_push(&cb, fetch_line(term, i - term->sblines));
}

int cpos = term->cols * lcurr;
int npos = 0;
int end = term->cols * (term->rows + term->sblines);

// Loop over every character and search for query.
while (cpos < end) {
// Determine the current position.
int x = (cpos % term->cols);
int y = (cpos / term->cols);

// If our current position isn't in the buffer, add it in.
if (y - lcurr >= llen) {
circbuf_push(&cb, fetch_line(term, lcurr + llen - term->sblines));
++lcurr;
}
termline * lll = circbuf_get(&cb, y - lcurr);
termchar * chr = lll->chars + x;

if (npos == 0 && cpos + term->results.query_length >= end)
break;

if (chr->chr != term->results.query[npos]) {
// Skip the second cell of any wide characters
if (chr->chr == UCSWIDE) {
++cpos; continue;
}
cpos -= npos - 1;
npos = 0;
continue;
}

++npos;

if (term->results.query_length == npos) {
int start = cpos - npos + 1;
pos respos = {
.x = start % term->cols,
.y = start / term->cols,
};
results_add(term, respos);
npos = 0;
}

++cpos;
}

circbuf_destroy(&cb);
}

void
term_schedule_search_update(struct term* term)
{
if (term->results.update_type != DISABLE_UPDATE)
term->results.update_type = FULL_UPDATE;
}

void
term_schedule_search_partial_update(struct term* term)
{
if (term->results.update_type != DISABLE_UPDATE) {
if (term->results.update_type == NO_UPDATE) {
term->results.update_type = PARTIAL_UPDATE;
}
}
}

void
term_clear_results(struct term* term)
{
term->results.results = renewn(term->results.results, 16);
term->results.current = 0;
term->results.length = 0;
term->results.capacity = 16;
}

void
term_clear_search(struct term* term)
{
term_clear_results(term);
term->results.update_type = NO_UPDATE;
free(term->results.query);
term->results.query = NULL;
term->results.query_length = 0;
}

static void
scrollback_push(struct term* term, uchar *line)
{
Expand Down Expand Up @@ -717,6 +965,16 @@ term_paint(struct term* term)
if (term->in_vbell || selected)
tattr.attr ^= ATTR_REVERSE;

int match = in_results(term, scrpos);
if (match > 0) {
tattr.attr |= TATTR_RESULT;
if (match > 1) {
tattr.attr |= TATTR_CURRESULT;
}
} else {
tattr.attr &= ~TATTR_RESULT;
}

/* 'Real' blinking ? */
if (term->blink_is_real && (tattr.attr & ATTR_BLINK)) {
if (term->has_focus && term->tblinker)
Expand Down
Loading

0 comments on commit 4955e5d

Please sign in to comment.