version 1.13, 2010/01/03 17:12:04 |
version 1.14, 2010/02/06 17:35:01 |
|
|
|
|
/* Set selection. */ |
/* Set selection. */ |
void |
void |
screen_set_selection(struct screen *s, |
screen_set_selection(struct screen *s, u_int sx, u_int sy, |
u_int sx, u_int sy, u_int ex, u_int ey, struct grid_cell *gc) |
u_int ex, u_int ey, u_int rectflag, struct grid_cell *gc) |
{ |
{ |
struct screen_sel *sel = &s->sel; |
struct screen_sel *sel = &s->sel; |
|
|
memcpy(&sel->cell, gc, sizeof sel->cell); |
memcpy(&sel->cell, gc, sizeof sel->cell); |
sel->flag = 1; |
sel->flag = 1; |
|
sel->rectflag = rectflag; |
|
|
/* starting line < ending line -- downward selection. */ |
sel->sx = sx; sel->sy = sy; |
if (sy < ey) { |
sel->ex = ex; sel->ey = 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; |
|
} |
|
} |
} |
|
|
/* Clear selection. */ |
/* Clear selection. */ |
|
|
{ |
{ |
struct screen_sel *sel = &s->sel; |
struct screen_sel *sel = &s->sel; |
|
|
if (!sel->flag || py < sel->sy || py > sel->ey) |
if (!sel->flag) |
return (0); |
return (0); |
|
|
if (py == sel->sy && py == sel->ey) { |
if (sel->rectflag) { |
if (px < sel->sx || px > sel->ex) |
if (sel->sy < sel->ey) { |
return (0); |
/* start line < end line -- downward selection. */ |
return (1); |
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); |
return (1); |
} |
} |