aboutsummaryrefslogtreecommitdiff
path: root/screen.c
diff options
context:
space:
mode:
authorTiago Cunha <tcunha@gmx.com>2010-02-08 18:13:17 +0000
committerTiago Cunha <tcunha@gmx.com>2010-02-08 18:13:17 +0000
commit3c37b0927269819945c0520a8eeb79a2a67ec1c5 (patch)
tree795d3b529320fee37e83d192f9ef58c4ac61bf9e /screen.c
parenta32d095c97177eaa7ba7d2a3c723df1b878e9922 (diff)
downloadrtmux-3c37b0927269819945c0520a8eeb79a2a67ec1c5.tar.gz
rtmux-3c37b0927269819945c0520a8eeb79a2a67ec1c5.tar.bz2
rtmux-3c37b0927269819945c0520a8eeb79a2a67ec1c5.zip
Sync OpenBSD patchset 636:
Rectangle copy support, from Robin Lee Powell.
Diffstat (limited to 'screen.c')
-rw-r--r--screen.c115
1 files changed, 78 insertions, 37 deletions
diff --git a/screen.c b/screen.c
index 338c00c5..122b24e8 100644
--- a/screen.c
+++ b/screen.c
@@ -1,4 +1,4 @@
-/* $Id: screen.c,v 1.98 2010-01-05 23:54:53 tcunha Exp $ */
+/* $Id: screen.c,v 1.99 2010-02-08 18:13:17 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -227,41 +227,17 @@ screen_resize_y(struct screen *s, u_int sy)
/* Set selection. */
void
-screen_set_selection(struct screen *s,
- u_int sx, u_int sy, u_int ex, u_int ey, struct grid_cell *gc)
+screen_set_selection(struct screen *s, u_int sx, u_int sy,
+ u_int ex, u_int ey, u_int rectflag, struct grid_cell *gc)
{
struct screen_sel *sel = &s->sel;
memcpy(&sel->cell, gc, sizeof sel->cell);
sel->flag = 1;
+ sel->rectflag = rectflag;
- /* starting line < ending line -- downward selection. */
- if (sy < ey) {
- sel->sx = sx; sel->sy = sy;
- sel->ex = ex; sel->ey = ey;
- return;
- }
-
- /* starting line > ending line -- upward selection. */
- if (sy > ey) {
- if (sx > 0) {
- sel->sx = ex; sel->sy = ey;
- sel->ex = sx - 1; sel->ey = sy;
- } else {
- sel->sx = ex; sel->sy = ey;
- sel->ex = -1; sel->ey = sy - 1;
- }
- return;
- }
-
- /* starting line == ending line. */
- if (ex < sx) {
- sel->sx = ex; sel->sy = ey;
- sel->ex = sx - 1; sel->ey = sy;
- } else {
- sel->sx = sx; sel->sy = sy;
- sel->ex = ex; sel->ey = ey;
- }
+ sel->sx = sx; sel->sy = sy;
+ sel->ex = ex; sel->ey = ey;
}
/* Clear selection. */
@@ -279,16 +255,81 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
{
struct screen_sel *sel = &s->sel;
- if (!sel->flag || py < sel->sy || py > sel->ey)
+ if (!sel->flag)
return (0);
- if (py == sel->sy && py == sel->ey) {
- if (px < sel->sx || px > sel->ex)
- return (0);
- return (1);
+ if (sel->rectflag) {
+ if (sel->sy < sel->ey) {
+ /* start line < end line -- downward selection. */
+ if (py < sel->sy || py > sel->ey)
+ return (0);
+ } else if (sel->sy > sel->ey) {
+ /* start line > end line -- upward selection. */
+ if (py > sel->sy || py < sel->ey)
+ return (0);
+ } else {
+ /* starting line == ending line. */
+ if (py != sel->sy)
+ return (0);
+ }
+
+ /*
+ * Need to include the selection start row, but not the cursor
+ * row, which means the selection changes depending on which
+ * one is on the left.
+ */
+ if (sel->ex < sel->sx) {
+ /* Cursor (ex) is on the left. */
+ if (px <= sel->ex)
+ return (0);
+
+ if (px > sel->sx)
+ return (0);
+ } else {
+ /* Selection start (sx) is on the left. */
+ if (px < sel->sx)
+ return (0);
+
+ if (px >= sel->ex)
+ return (0);
+ }
+ } else {
+ /*
+ * Like emacs, keep the top-left-most character, and drop the
+ * bottom-right-most, regardless of copy direction.
+ */
+ if (sel->sy < sel->ey) {
+ /* starting line < ending line -- downward selection. */
+ if (py < sel->sy || py > sel->ey)
+ return (0);
+
+ if ((py == sel->sy && px < sel->sx)
+ || (py == sel->ey && px > sel->ex))
+ return (0);
+ } else if (sel->sy > sel->ey) {
+ /* starting line > ending line -- upward selection. */
+ if (py > sel->sy || py < sel->ey)
+ return (0);
+
+ if ((py == sel->sy && px >= sel->sx)
+ || (py == sel->ey && px < sel->ex))
+ return (0);
+ } else {
+ /* starting line == ending line. */
+ if (py != sel->sy)
+ return (0);
+
+ if (sel->ex < sel->sx) {
+ /* cursor (ex) is on the left */
+ if (px > sel->sx || px < sel->ex)
+ return (0);
+ } else {
+ /* selection start (sx) is on the left */
+ if (px < sel->sx || px > sel->ex)
+ return (0);
+ }
+ }
}
- if ((py == sel->sy && px < sel->sx) || (py == sel->ey && px > sel->ex))
- return (0);
return (1);
}