blob: 9db0f60972ae0d03ba7d3ef179cb94442de05871 [file] [log] [blame] [raw]
Nicholas Marriott35876ea2009-06-01 22:58:49 +00001/* $OpenBSD$ */
2
3/*
nicm995af0e2016-01-19 15:59:12 +00004 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
Nicholas Marriott35876ea2009-06-01 22:58:49 +00005 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20
Nicholas Marriottd42fb432009-06-04 18:48:24 +000021#include <stdlib.h>
Nicholas Marriott35876ea2009-06-01 22:58:49 +000022#include <string.h>
Nicholas Marriottac9daf92010-04-06 21:35:44 +000023#include <unistd.h>
nicm8149bc32017-06-04 09:02:36 +000024#include <vis.h>
Nicholas Marriott35876ea2009-06-01 22:58:49 +000025
26#include "tmux.h"
27
nicm82776c42018-07-31 11:49:26 +000028/* Selected area in screen. */
29struct screen_sel {
30 int hidden;
31 int rectangle;
32 int modekeys;
33
34 u_int sx;
35 u_int sy;
36
37 u_int ex;
38 u_int ey;
39
40 struct grid_cell cell;
41};
42
43/* Entry on title stack. */
nicm88517ce2017-10-05 13:29:18 +000044struct screen_title_entry {
45 char *text;
46
47 TAILQ_ENTRY(screen_title_entry) entry;
48};
49TAILQ_HEAD(screen_titles, screen_title_entry);
50
nicmc426e482016-10-10 21:29:23 +000051static void screen_resize_y(struct screen *, u_int);
Nicholas Marriott35876ea2009-06-01 22:58:49 +000052
nicme4540182016-10-11 13:21:59 +000053static void screen_reflow(struct screen *, u_int);
nicm88517ce2017-10-05 13:29:18 +000054
55/* Free titles stack. */
56static void
57screen_free_titles(struct screen *s)
58{
59 struct screen_title_entry *title_entry;
60
61 if (s->titles == NULL)
62 return;
63
64 while ((title_entry = TAILQ_FIRST(s->titles)) != NULL) {
65 TAILQ_REMOVE(s->titles, title_entry, entry);
66 free(title_entry->text);
67 free(title_entry);
68 }
69
70 free(s->titles);
71 s->titles = NULL;
72}
nicme4540182016-10-11 13:21:59 +000073
Nicholas Marriott35876ea2009-06-01 22:58:49 +000074/* Create a new screen. */
75void
76screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
77{
78 s->grid = grid_create(sx, sy, hlimit);
nicmd9b31332015-08-28 17:11:12 +000079 s->title = xstrdup("");
nicm88517ce2017-10-05 13:29:18 +000080 s->titles = NULL;
Nicholas Marriott35876ea2009-06-01 22:58:49 +000081
Nicholas Marriott3ea5e062011-05-20 19:17:39 +000082 s->cstyle = 0;
Nicholas Marriott944b5e62011-05-20 19:03:58 +000083 s->ccolour = xstrdup("");
Nicholas Marriottd42fb432009-06-04 18:48:24 +000084 s->tabs = NULL;
nicm82776c42018-07-31 11:49:26 +000085 s->sel = NULL;
Nicholas Marriottd42fb432009-06-04 18:48:24 +000086
Nicholas Marriott35876ea2009-06-01 22:58:49 +000087 screen_reinit(s);
88}
89
90/* Reinitialise screen. */
91void
92screen_reinit(struct screen *s)
93{
94 s->cx = 0;
95 s->cy = 0;
96
97 s->rupper = 0;
98 s->rlower = screen_size_y(s) - 1;
99
Nicholas Marriottac9daf92010-04-06 21:35:44 +0000100 s->mode = MODE_CURSOR | MODE_WRAP;
Nicholas Marriott15a64b82009-12-03 22:50:09 +0000101
Nicholas Marriottd42fb432009-06-04 18:48:24 +0000102 screen_reset_tabs(s);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000103
nicm4179b422016-10-13 20:27:27 +0000104 grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy, 8);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000105
106 screen_clear_selection(s);
nicm88517ce2017-10-05 13:29:18 +0000107 screen_free_titles(s);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000108}
109
110/* Destroy a screen. */
111void
112screen_free(struct screen *s)
113{
nicm82776c42018-07-31 11:49:26 +0000114 free(s->sel);
Nicholas Marriottdf912e32012-07-10 11:53:01 +0000115 free(s->tabs);
116 free(s->title);
117 free(s->ccolour);
nicm88517ce2017-10-05 13:29:18 +0000118
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000119 grid_destroy(s->grid);
nicm88517ce2017-10-05 13:29:18 +0000120
121 screen_free_titles(s);
Nicholas Marriottd42fb432009-06-04 18:48:24 +0000122}
123
124/* Reset tabs to default, eight spaces apart. */
125void
126screen_reset_tabs(struct screen *s)
127{
128 u_int i;
129
Nicholas Marriottdf912e32012-07-10 11:53:01 +0000130 free(s->tabs);
Nicholas Marriottd42fb432009-06-04 18:48:24 +0000131
132 if ((s->tabs = bit_alloc(screen_size_x(s))) == NULL)
133 fatal("bit_alloc failed");
134 for (i = 8; i < screen_size_x(s); i += 8)
135 bit_set(s->tabs, i);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000136}
137
Nicholas Marriott3ea5e062011-05-20 19:17:39 +0000138/* Set screen cursor style. */
139void
140screen_set_cursor_style(struct screen *s, u_int style)
141{
Nicholas Marriott87d092d2012-03-17 21:37:36 +0000142 if (style <= 6)
Nicholas Marriott3ea5e062011-05-20 19:17:39 +0000143 s->cstyle = style;
144}
145
Nicholas Marriott944b5e62011-05-20 19:03:58 +0000146/* Set screen cursor colour. */
147void
nicm2a1f27e2015-12-28 14:02:52 +0000148screen_set_cursor_colour(struct screen *s, const char *colour)
Nicholas Marriott944b5e62011-05-20 19:03:58 +0000149{
Nicholas Marriottdf912e32012-07-10 11:53:01 +0000150 free(s->ccolour);
nicm2a1f27e2015-12-28 14:02:52 +0000151 s->ccolour = xstrdup(colour);
Nicholas Marriott944b5e62011-05-20 19:03:58 +0000152}
153
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000154/* Set screen title. */
155void
156screen_set_title(struct screen *s, const char *title)
157{
Nicholas Marriottdf912e32012-07-10 11:53:01 +0000158 free(s->title);
nicm8149bc32017-06-04 09:02:36 +0000159 utf8_stravis(&s->title, title, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000160}
161
nicmf3dc38d2019-11-15 11:16:53 +0000162/* Set screen path. */
163void
164screen_set_path(struct screen *s, const char *path)
165{
166 free(s->path);
167 utf8_stravis(&s->path, path, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
168}
169
nicm88517ce2017-10-05 13:29:18 +0000170/* Push the current title onto the stack. */
171void
172screen_push_title(struct screen *s)
173{
174 struct screen_title_entry *title_entry;
175
176 if (s->titles == NULL) {
177 s->titles = xmalloc(sizeof *s->titles);
178 TAILQ_INIT(s->titles);
179 }
180 title_entry = xmalloc(sizeof *title_entry);
181 title_entry->text = xstrdup(s->title);
182 TAILQ_INSERT_HEAD(s->titles, title_entry, entry);
183}
184
185/*
186 * Pop a title from the stack and set it as the screen title. If the stack is
187 * empty, do nothing.
188 */
189void
190screen_pop_title(struct screen *s)
191{
192 struct screen_title_entry *title_entry;
193
194 if (s->titles == NULL)
195 return;
196
197 title_entry = TAILQ_FIRST(s->titles);
198 if (title_entry != NULL) {
199 screen_set_title(s, title_entry->text);
200
201 TAILQ_REMOVE(s->titles, title_entry, entry);
202 free(title_entry->text);
203 free(title_entry);
204 }
205}
206
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000207/* Resize screen. */
208void
Nicholas Marriott8903c1f2013-02-05 11:08:59 +0000209screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000210{
211 if (sx < 1)
212 sx = 1;
213 if (sy < 1)
214 sy = 1;
215
Nicholas Marriottd42fb432009-06-04 18:48:24 +0000216 if (sx != screen_size_x(s)) {
nicm9ee1a8f2019-03-20 19:19:11 +0000217 s->grid->sx = sx;
Nicholas Marriottd42fb432009-06-04 18:48:24 +0000218 screen_reset_tabs(s);
nicm3887d952017-11-02 18:26:38 +0000219 } else
220 reflow = 0;
Nicholas Marriottd42fb432009-06-04 18:48:24 +0000221
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000222 if (sy != screen_size_y(s))
223 screen_resize_y(s, sy);
Nicholas Marriott8903c1f2013-02-05 11:08:59 +0000224
225 if (reflow)
226 screen_reflow(s, sx);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000227}
228
nicmc426e482016-10-10 21:29:23 +0000229static void
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000230screen_resize_y(struct screen *s, u_int sy)
231{
232 struct grid *gd = s->grid;
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000233 u_int needed, available, oldy, i;
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000234
235 if (sy == 0)
236 fatalx("zero size");
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000237 oldy = screen_size_y(s);
238
Nicholas Marriott15a64b82009-12-03 22:50:09 +0000239 /*
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000240 * When resizing:
241 *
242 * If the height is decreasing, delete lines from the bottom until
243 * hitting the cursor, then push lines from the top into the history.
Nicholas Marriott15a64b82009-12-03 22:50:09 +0000244 *
nicm2627ab32016-09-02 20:57:20 +0000245 * When increasing, pull as many lines as possible from scrolled
246 * history (not explicitly cleared from view) to the top, then fill the
247 * remaining with blanks at the bottom.
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000248 */
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000249
250 /* Size decreasing. */
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000251 if (sy < oldy) {
252 needed = oldy - sy;
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000253
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000254 /* Delete as many lines as possible from the bottom. */
255 available = oldy - 1 - s->cy;
256 if (available > 0) {
257 if (available > needed)
258 available = needed;
nicm4179b422016-10-13 20:27:27 +0000259 grid_view_delete_lines(gd, oldy - available, available,
260 8);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000261 }
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000262 needed -= available;
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000263
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000264 /*
Nicholas Marriott35928592009-07-13 10:43:52 +0000265 * Now just increase the history size, if possible, to take
266 * over the lines which are left. If history is off, delete
267 * lines from the top.
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000268 */
Nicholas Marriott35928592009-07-13 10:43:52 +0000269 available = s->cy;
nicm2627ab32016-09-02 20:57:20 +0000270 if (gd->flags & GRID_HISTORY) {
271 gd->hscrolled += needed;
Nicholas Marriott35928592009-07-13 10:43:52 +0000272 gd->hsize += needed;
nicm2627ab32016-09-02 20:57:20 +0000273 } else if (needed > 0 && available > 0) {
Nicholas Marriott35928592009-07-13 10:43:52 +0000274 if (available > needed)
275 available = needed;
nicm4179b422016-10-13 20:27:27 +0000276 grid_view_delete_lines(gd, 0, available, 8);
Nicholas Marriott35928592009-07-13 10:43:52 +0000277 }
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000278 s->cy -= needed;
Nicholas Marriott15a64b82009-12-03 22:50:09 +0000279 }
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000280
nicm2fae6a52018-07-04 09:44:07 +0000281 /* Resize line array. */
282 grid_adjust_lines(gd, gd->hsize + sy);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000283
284 /* Size increasing. */
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000285 if (sy > oldy) {
286 needed = sy - oldy;
287
Nicholas Marriott35928592009-07-13 10:43:52 +0000288 /*
nicmc426e482016-10-10 21:29:23 +0000289 * Try to pull as much as possible out of scrolled history, if
290 * is is enabled.
Nicholas Marriott35928592009-07-13 10:43:52 +0000291 */
nicm2627ab32016-09-02 20:57:20 +0000292 available = gd->hscrolled;
Nicholas Marriott35928592009-07-13 10:43:52 +0000293 if (gd->flags & GRID_HISTORY && available > 0) {
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000294 if (available > needed)
295 available = needed;
nicm2627ab32016-09-02 20:57:20 +0000296 gd->hscrolled -= available;
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000297 gd->hsize -= available;
298 s->cy += available;
Nicholas Marriott35928592009-07-13 10:43:52 +0000299 } else
300 available = 0;
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000301 needed -= available;
302
303 /* Then fill the rest in with blanks. */
Nicholas Marriott5e01b6d2009-08-08 13:29:27 +0000304 for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++)
nicm2fae6a52018-07-04 09:44:07 +0000305 memset(grid_get_line(gd, i), 0, sizeof(struct grid_line));
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000306 }
307
Nicholas Marriottf4b8f002009-06-24 19:12:44 +0000308 /* Set the new size, and reset the scroll region. */
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000309 gd->sy = sy;
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000310 s->rupper = 0;
311 s->rlower = screen_size_y(s) - 1;
312}
313
314/* Set selection. */
315void
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000316screen_set_selection(struct screen *s, u_int sx, u_int sy,
nicm82776c42018-07-31 11:49:26 +0000317 u_int ex, u_int ey, u_int rectangle, int modekeys, struct grid_cell *gc)
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000318{
nicm82776c42018-07-31 11:49:26 +0000319 if (s->sel == NULL)
320 s->sel = xcalloc(1, sizeof *s->sel);
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000321
nicm82776c42018-07-31 11:49:26 +0000322 memcpy(&s->sel->cell, gc, sizeof s->sel->cell);
323 s->sel->hidden = 0;
324 s->sel->rectangle = rectangle;
325 s->sel->modekeys = modekeys;
nicm7e6c2cb2016-11-24 13:38:44 +0000326
nicm82776c42018-07-31 11:49:26 +0000327 s->sel->sx = sx;
328 s->sel->sy = sy;
329 s->sel->ex = ex;
330 s->sel->ey = ey;
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000331}
332
333/* Clear selection. */
334void
335screen_clear_selection(struct screen *s)
336{
nicm82776c42018-07-31 11:49:26 +0000337 free(s->sel);
338 s->sel = NULL;
nicm7e6c2cb2016-11-24 13:38:44 +0000339}
340
341/* Hide selection. */
342void
343screen_hide_selection(struct screen *s)
344{
nicm82776c42018-07-31 11:49:26 +0000345 if (s->sel != NULL)
346 s->sel->hidden = 1;
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000347}
348
349/* Check if cell in selection. */
350int
351screen_check_selection(struct screen *s, u_int px, u_int py)
352{
nicm82776c42018-07-31 11:49:26 +0000353 struct screen_sel *sel = s->sel;
nicm29d20a52014-08-11 22:18:16 +0000354 u_int xx;
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000355
nicm82776c42018-07-31 11:49:26 +0000356 if (sel == NULL || sel->hidden)
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000357 return (0);
358
nicm82776c42018-07-31 11:49:26 +0000359 if (sel->rectangle) {
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000360 if (sel->sy < sel->ey) {
361 /* start line < end line -- downward selection. */
362 if (py < sel->sy || py > sel->ey)
363 return (0);
364 } else if (sel->sy > sel->ey) {
365 /* start line > end line -- upward selection. */
366 if (py > sel->sy || py < sel->ey)
367 return (0);
368 } else {
369 /* starting line == ending line. */
370 if (py != sel->sy)
371 return (0);
372 }
373
374 /*
375 * Need to include the selection start row, but not the cursor
376 * row, which means the selection changes depending on which
377 * one is on the left.
378 */
379 if (sel->ex < sel->sx) {
380 /* Cursor (ex) is on the left. */
Nicholas Marriott20ed20e2010-12-11 17:56:01 +0000381 if (px < sel->ex)
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000382 return (0);
383
384 if (px > sel->sx)
385 return (0);
386 } else {
387 /* Selection start (sx) is on the left. */
388 if (px < sel->sx)
389 return (0);
390
Nicholas Marriott20ed20e2010-12-11 17:56:01 +0000391 if (px > sel->ex)
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000392 return (0);
393 }
394 } else {
395 /*
396 * Like emacs, keep the top-left-most character, and drop the
397 * bottom-right-most, regardless of copy direction.
398 */
399 if (sel->sy < sel->ey) {
400 /* starting line < ending line -- downward selection. */
401 if (py < sel->sy || py > sel->ey)
402 return (0);
403
nicm29d20a52014-08-11 22:18:16 +0000404 if (py == sel->sy && px < sel->sx)
nicm4e956d52014-09-01 21:50:18 +0000405 return (0);
nicm29d20a52014-08-11 22:18:16 +0000406
nicm34c08072019-01-15 09:56:31 +0000407 if (sel->modekeys == MODEKEY_EMACS)
408 xx = (sel->ex == 0 ? 0 : sel->ex - 1);
409 else
410 xx = sel->ex;
411 if (py == sel->ey && px > xx)
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000412 return (0);
413 } else if (sel->sy > sel->ey) {
414 /* starting line > ending line -- upward selection. */
415 if (py > sel->sy || py < sel->ey)
416 return (0);
417
nicm29d20a52014-08-11 22:18:16 +0000418 if (py == sel->ey && px < sel->ex)
419 return (0);
420
421 if (sel->modekeys == MODEKEY_EMACS)
422 xx = sel->sx - 1;
423 else
424 xx = sel->sx;
nicm13a0b6b2017-02-08 16:45:18 +0000425 if (py == sel->sy && (sel->sx == 0 || px > xx))
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000426 return (0);
427 } else {
428 /* starting line == ending line. */
429 if (py != sel->sy)
430 return (0);
431
432 if (sel->ex < sel->sx) {
433 /* cursor (ex) is on the left */
nicm29d20a52014-08-11 22:18:16 +0000434 if (sel->modekeys == MODEKEY_EMACS)
435 xx = sel->sx - 1;
436 else
437 xx = sel->sx;
438 if (px > xx || px < sel->ex)
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000439 return (0);
440 } else {
441 /* selection start (sx) is on the left */
nicm34c08072019-01-15 09:56:31 +0000442 if (sel->modekeys == MODEKEY_EMACS)
443 xx = (sel->ex == 0 ? 0 : sel->ex - 1);
444 else
445 xx = sel->ex;
446 if (px < sel->sx || px > xx)
Nicholas Marriott3ef38022010-02-06 17:35:01 +0000447 return (0);
448 }
449 }
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000450 }
451
Nicholas Marriott35876ea2009-06-01 22:58:49 +0000452 return (1);
453}
Nicholas Marriott8903c1f2013-02-05 11:08:59 +0000454
nicm4160df42016-10-12 13:24:07 +0000455/* Get selected grid cell. */
456void
457screen_select_cell(struct screen *s, struct grid_cell *dst,
458 const struct grid_cell *src)
459{
nicm82776c42018-07-31 11:49:26 +0000460 if (s->sel == NULL || s->sel->hidden)
nicm4160df42016-10-12 13:24:07 +0000461 return;
462
nicm82776c42018-07-31 11:49:26 +0000463 memcpy(dst, &s->sel->cell, sizeof *dst);
nicm4160df42016-10-12 13:24:07 +0000464
465 utf8_copy(&dst->data, &src->data);
466 dst->attr = dst->attr & ~GRID_ATTR_CHARSET;
467 dst->attr |= src->attr & GRID_ATTR_CHARSET;
468 dst->flags = src->flags;
469}
470
Nicholas Marriott8903c1f2013-02-05 11:08:59 +0000471/* Reflow wrapped lines. */
nicme4540182016-10-11 13:21:59 +0000472static void
Nicholas Marriott9b7e18f2013-03-21 16:12:10 +0000473screen_reflow(struct screen *s, u_int new_x)
Nicholas Marriott8903c1f2013-02-05 11:08:59 +0000474{
nicmffa4d482019-04-02 08:45:32 +0000475 u_int cx = s->cx, cy = s->grid->hsize + s->cy, wx, wy;
nicm9ee1a8f2019-03-20 19:19:11 +0000476 struct timeval start, tv;
477
478 gettimeofday(&start, NULL);
479
nicmffa4d482019-04-02 08:45:32 +0000480 grid_wrap_position(s->grid, cx, cy, &wx, &wy);
481 log_debug("%s: cursor %u,%u is %u,%u", __func__, cx, cy, wx, wy);
nicm9ee1a8f2019-03-20 19:19:11 +0000482
483 grid_reflow(s->grid, new_x);
484
nicmffa4d482019-04-02 08:45:32 +0000485 grid_unwrap_position(s->grid, &cx, &cy, wx, wy);
nicm9ee1a8f2019-03-20 19:19:11 +0000486 log_debug("%s: new cursor is %u,%u", __func__, cx, cy);
487
488 if (cy >= s->grid->hsize) {
489 s->cx = cx;
490 s->cy = cy - s->grid->hsize;
491 } else {
492 s->cx = 0;
493 s->cy = 0;
494 }
495
496 gettimeofday(&tv, NULL);
497 timersub(&tv, &start, &tv);
498
499 log_debug("%s: reflow took %llu.%06u seconds", __func__,
500 (unsigned long long)tv.tv_sec, (u_int)tv.tv_usec);
Nicholas Marriott8903c1f2013-02-05 11:08:59 +0000501}