mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 06:38:37 -05:00
Rectangular-block selection. Enabled by Alt+drag, unless you
configure it to be the default in which case it's _dis_abled by Alt+drag. [originally from svn r1350]
This commit is contained in:
parent
ec1d8c1408
commit
d2c9937691
3
putty.h
3
putty.h
@ -326,6 +326,7 @@ typedef struct {
|
|||||||
unsigned char colours[22][3];
|
unsigned char colours[22][3];
|
||||||
/* Selection options */
|
/* Selection options */
|
||||||
int mouse_is_xterm;
|
int mouse_is_xterm;
|
||||||
|
int rect_select;
|
||||||
int rawcnp;
|
int rawcnp;
|
||||||
int mouse_override;
|
int mouse_override;
|
||||||
short wordness[256];
|
short wordness[256];
|
||||||
@ -452,7 +453,7 @@ void term_paint(Context, int, int, int, int);
|
|||||||
void term_scroll(int, int);
|
void term_scroll(int, int);
|
||||||
void term_pwron(void);
|
void term_pwron(void);
|
||||||
void term_clrsb(void);
|
void term_clrsb(void);
|
||||||
void term_mouse(Mouse_Button, Mouse_Action, int, int, int, int);
|
void term_mouse(Mouse_Button, Mouse_Action, int, int, int, int, int);
|
||||||
void term_deselect(void);
|
void term_deselect(void);
|
||||||
void term_update(void);
|
void term_update(void);
|
||||||
void term_invalidate(void);
|
void term_invalidate(void);
|
||||||
|
@ -235,6 +235,7 @@ void save_settings(char *section, int do_host, Config * cfg)
|
|||||||
}
|
}
|
||||||
write_setting_i(sesskey, "RawCNP", cfg->rawcnp);
|
write_setting_i(sesskey, "RawCNP", cfg->rawcnp);
|
||||||
write_setting_i(sesskey, "MouseIsXterm", cfg->mouse_is_xterm);
|
write_setting_i(sesskey, "MouseIsXterm", cfg->mouse_is_xterm);
|
||||||
|
write_setting_i(sesskey, "RectSelect", cfg->rect_select);
|
||||||
write_setting_i(sesskey, "MouseOverride", cfg->mouse_override);
|
write_setting_i(sesskey, "MouseOverride", cfg->mouse_override);
|
||||||
for (i = 0; i < 256; i += 32) {
|
for (i = 0; i < 256; i += 32) {
|
||||||
char buf[20], buf2[256];
|
char buf[20], buf2[256];
|
||||||
@ -440,6 +441,7 @@ void load_settings(char *section, int do_host, Config * cfg)
|
|||||||
}
|
}
|
||||||
gppi(sesskey, "RawCNP", 0, &cfg->rawcnp);
|
gppi(sesskey, "RawCNP", 0, &cfg->rawcnp);
|
||||||
gppi(sesskey, "MouseIsXterm", 0, &cfg->mouse_is_xterm);
|
gppi(sesskey, "MouseIsXterm", 0, &cfg->mouse_is_xterm);
|
||||||
|
gppi(sesskey, "RectSelect", 0, &cfg->rect_select);
|
||||||
gppi(sesskey, "MouseOverride", 1, &cfg->mouse_override);
|
gppi(sesskey, "MouseOverride", 1, &cfg->mouse_override);
|
||||||
for (i = 0; i < 256; i += 32) {
|
for (i = 0; i < 256; i += 32) {
|
||||||
static char *defaults[] = {
|
static char *defaults[] = {
|
||||||
|
108
terminal.c
108
terminal.c
@ -86,6 +86,10 @@ typedef struct {
|
|||||||
#define incpos(p) ( (p).x == cols ? ((p).x = 0, (p).y++, 1) : ((p).x++, 0) )
|
#define incpos(p) ( (p).x == cols ? ((p).x = 0, (p).y++, 1) : ((p).x++, 0) )
|
||||||
#define decpos(p) ( (p).x == 0 ? ((p).x = cols, (p).y--, 1) : ((p).x--, 0) )
|
#define decpos(p) ( (p).x == 0 ? ((p).x = cols, (p).y--, 1) : ((p).x--, 0) )
|
||||||
|
|
||||||
|
/* Product-order comparisons for rectangular block selection. */
|
||||||
|
#define posPlt(p1,p2) ( (p1).y <= (p2).y && (p1).x < (p2).x )
|
||||||
|
#define posPle(p1,p2) ( (p1).y <= (p2).y && (p1).x <= (p2).x )
|
||||||
|
|
||||||
static bufchain inbuf; /* terminal input buffer */
|
static bufchain inbuf; /* terminal input buffer */
|
||||||
static pos curs; /* cursor */
|
static pos curs; /* cursor */
|
||||||
static pos savecurs; /* saved cursor position */
|
static pos savecurs; /* saved cursor position */
|
||||||
@ -162,6 +166,9 @@ static enum {
|
|||||||
static enum {
|
static enum {
|
||||||
NO_SELECTION, ABOUT_TO, DRAGGING, SELECTED
|
NO_SELECTION, ABOUT_TO, DRAGGING, SELECTED
|
||||||
} selstate;
|
} selstate;
|
||||||
|
static enum {
|
||||||
|
LEXICOGRAPHIC, RECTANGULAR
|
||||||
|
} seltype;
|
||||||
static enum {
|
static enum {
|
||||||
SM_CHAR, SM_WORD, SM_LINE
|
SM_CHAR, SM_WORD, SM_LINE
|
||||||
} selmode;
|
} selmode;
|
||||||
@ -2586,7 +2593,7 @@ static void do_paint(Context ctx, int may_optimise)
|
|||||||
for (i = 0; i < rows; i++) {
|
for (i = 0; i < rows; i++) {
|
||||||
unsigned long *ldata;
|
unsigned long *ldata;
|
||||||
int lattr;
|
int lattr;
|
||||||
int idx, dirty_line, dirty_run;
|
int idx, dirty_line, dirty_run, selected;
|
||||||
unsigned long attr = 0;
|
unsigned long attr = 0;
|
||||||
int updated_line = 0;
|
int updated_line = 0;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
@ -2626,9 +2633,12 @@ static void do_paint(Context ctx, int may_optimise)
|
|||||||
tattr |= ATTR_WIDE;
|
tattr |= ATTR_WIDE;
|
||||||
|
|
||||||
/* Video reversing things */
|
/* Video reversing things */
|
||||||
|
if (seltype == LEXICOGRAPHIC)
|
||||||
|
selected = posle(selstart, scrpos) && poslt(scrpos, selend);
|
||||||
|
else
|
||||||
|
selected = posPle(selstart, scrpos) && posPlt(scrpos, selend);
|
||||||
tattr = (tattr ^ rv
|
tattr = (tattr ^ rv
|
||||||
^ (posle(selstart, scrpos) &&
|
^ (selected ? ATTR_REVERSE : 0));
|
||||||
poslt(scrpos, selend) ? ATTR_REVERSE : 0));
|
|
||||||
|
|
||||||
/* 'Real' blinking ? */
|
/* 'Real' blinking ? */
|
||||||
if (blink_is_real && (tattr & ATTR_BLINK)) {
|
if (blink_is_real && (tattr & ATTR_BLINK)) {
|
||||||
@ -2816,25 +2826,38 @@ void term_scroll(int rel, int where)
|
|||||||
term_update();
|
term_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clipme(pos top, pos bottom)
|
static void clipme(pos top, pos bottom, int rect)
|
||||||
{
|
{
|
||||||
wchar_t *workbuf;
|
wchar_t *workbuf;
|
||||||
wchar_t *wbptr; /* where next char goes within workbuf */
|
wchar_t *wbptr; /* where next char goes within workbuf */
|
||||||
|
int old_top_x;
|
||||||
int wblen = 0; /* workbuf len */
|
int wblen = 0; /* workbuf len */
|
||||||
int buflen; /* amount of memory allocated to workbuf */
|
int buflen; /* amount of memory allocated to workbuf */
|
||||||
|
|
||||||
buflen = 5120; /* Default size */
|
buflen = 5120; /* Default size */
|
||||||
workbuf = smalloc(buflen * sizeof(wchar_t));
|
workbuf = smalloc(buflen * sizeof(wchar_t));
|
||||||
wbptr = workbuf; /* start filling here */
|
wbptr = workbuf; /* start filling here */
|
||||||
|
old_top_x = top.x; /* needed for rect==1 */
|
||||||
|
|
||||||
while (poslt(top, bottom)) {
|
while (poslt(top, bottom)) {
|
||||||
int nl = FALSE;
|
int nl = FALSE;
|
||||||
unsigned long *ldata = lineptr(top.y);
|
unsigned long *ldata = lineptr(top.y);
|
||||||
pos nlpos;
|
pos nlpos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nlpos will point at the maximum position on this line we
|
||||||
|
* should copy up to. So we start it at the end of the
|
||||||
|
* line...
|
||||||
|
*/
|
||||||
nlpos.y = top.y;
|
nlpos.y = top.y;
|
||||||
nlpos.x = cols;
|
nlpos.x = cols;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ... move it backwards if there's unused space at the end
|
||||||
|
* of the line (and also set `nl' if this is the case,
|
||||||
|
* because in normal selection mode this means we need a
|
||||||
|
* newline at the end)...
|
||||||
|
*/
|
||||||
if (!(ldata[cols] & LATTR_WRAPPED)) {
|
if (!(ldata[cols] & LATTR_WRAPPED)) {
|
||||||
while (((ldata[nlpos.x - 1] & 0xFF) == 0x20 ||
|
while (((ldata[nlpos.x - 1] & 0xFF) == 0x20 ||
|
||||||
(DIRECT_CHAR(ldata[nlpos.x - 1]) &&
|
(DIRECT_CHAR(ldata[nlpos.x - 1]) &&
|
||||||
@ -2844,6 +2867,20 @@ static void clipme(pos top, pos bottom)
|
|||||||
if (poslt(nlpos, bottom))
|
if (poslt(nlpos, bottom))
|
||||||
nl = TRUE;
|
nl = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ... and then clip it to the terminal x coordinate if
|
||||||
|
* we're doing rectangular selection. (In this case we
|
||||||
|
* still did the above, so that copying e.g. the right-hand
|
||||||
|
* column from a table doesn't fill with spaces on the
|
||||||
|
* right.)
|
||||||
|
*/
|
||||||
|
if (rect) {
|
||||||
|
if (nlpos.x > bottom.x)
|
||||||
|
nlpos.x = bottom.x;
|
||||||
|
nl = (top.y < bottom.y);
|
||||||
|
}
|
||||||
|
|
||||||
while (poslt(top, bottom) && poslt(top, nlpos)) {
|
while (poslt(top, bottom) && poslt(top, nlpos)) {
|
||||||
#if 0
|
#if 0
|
||||||
char cbuf[16], *p;
|
char cbuf[16], *p;
|
||||||
@ -2931,7 +2968,7 @@ static void clipme(pos top, pos bottom)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
top.y++;
|
top.y++;
|
||||||
top.x = 0;
|
top.x = rect ? old_top_x : 0;
|
||||||
}
|
}
|
||||||
wblen++;
|
wblen++;
|
||||||
*wbptr++ = 0;
|
*wbptr++ = 0;
|
||||||
@ -2945,7 +2982,7 @@ void term_copyall(void)
|
|||||||
pos top;
|
pos top;
|
||||||
top.y = -count234(scrollback);
|
top.y = -count234(scrollback);
|
||||||
top.x = 0;
|
top.x = 0;
|
||||||
clipme(top, curs);
|
clipme(top, curs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3149,10 +3186,12 @@ static pos sel_spread_half(pos p, int dir)
|
|||||||
|
|
||||||
static void sel_spread(void)
|
static void sel_spread(void)
|
||||||
{
|
{
|
||||||
|
if (seltype == LEXICOGRAPHIC) {
|
||||||
selstart = sel_spread_half(selstart, -1);
|
selstart = sel_spread_half(selstart, -1);
|
||||||
decpos(selend);
|
decpos(selend);
|
||||||
selend = sel_spread_half(selend, +1);
|
selend = sel_spread_half(selend, +1);
|
||||||
incpos(selend);
|
incpos(selend);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_do_paste(void)
|
void term_do_paste(void)
|
||||||
@ -3204,11 +3243,12 @@ void term_do_paste(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
|
void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
|
||||||
int shift, int ctrl)
|
int shift, int ctrl, int alt)
|
||||||
{
|
{
|
||||||
pos selpoint;
|
pos selpoint;
|
||||||
unsigned long *ldata;
|
unsigned long *ldata;
|
||||||
int raw_mouse = xterm_mouse && !(cfg.mouse_override && shift);
|
int raw_mouse = xterm_mouse && !(cfg.mouse_override && shift);
|
||||||
|
int default_seltype;
|
||||||
|
|
||||||
if (y < 0) {
|
if (y < 0) {
|
||||||
y = 0;
|
y = 0;
|
||||||
@ -3290,9 +3330,23 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
|
|||||||
|
|
||||||
b = translate_button(b);
|
b = translate_button(b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the selection type (rectangular or normal) at the start
|
||||||
|
* of a selection attempt, from the state of Alt.
|
||||||
|
*/
|
||||||
|
if (!alt ^ !cfg.rect_select)
|
||||||
|
default_seltype = RECTANGULAR;
|
||||||
|
else
|
||||||
|
default_seltype = LEXICOGRAPHIC;
|
||||||
|
|
||||||
|
if (selstate == NO_SELECTION) {
|
||||||
|
seltype = default_seltype;
|
||||||
|
}
|
||||||
|
|
||||||
if (b == MBT_SELECT && a == MA_CLICK) {
|
if (b == MBT_SELECT && a == MA_CLICK) {
|
||||||
deselect();
|
deselect();
|
||||||
selstate = ABOUT_TO;
|
selstate = ABOUT_TO;
|
||||||
|
seltype = default_seltype;
|
||||||
selanchor = selpoint;
|
selanchor = selpoint;
|
||||||
selmode = SM_CHAR;
|
selmode = SM_CHAR;
|
||||||
} else if (b == MBT_SELECT && (a == MA_2CLK || a == MA_3CLK)) {
|
} else if (b == MBT_SELECT && (a == MA_2CLK || a == MA_3CLK)) {
|
||||||
@ -3308,6 +3362,12 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
|
|||||||
if (selstate == ABOUT_TO && poseq(selanchor, selpoint))
|
if (selstate == ABOUT_TO && poseq(selanchor, selpoint))
|
||||||
return;
|
return;
|
||||||
if (b == MBT_EXTEND && a != MA_DRAG && selstate == SELECTED) {
|
if (b == MBT_EXTEND && a != MA_DRAG && selstate == SELECTED) {
|
||||||
|
if (seltype == LEXICOGRAPHIC) {
|
||||||
|
/*
|
||||||
|
* For normal selection, we extend by moving
|
||||||
|
* whichever end of the current selection is closer
|
||||||
|
* to the mouse.
|
||||||
|
*/
|
||||||
if (posdiff(selpoint, selstart) <
|
if (posdiff(selpoint, selstart) <
|
||||||
posdiff(selend, selstart) / 2) {
|
posdiff(selend, selstart) / 2) {
|
||||||
selanchor = selend;
|
selanchor = selend;
|
||||||
@ -3315,11 +3375,32 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
|
|||||||
} else {
|
} else {
|
||||||
selanchor = selstart;
|
selanchor = selstart;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* For rectangular selection, we have a choice of
|
||||||
|
* _four_ places to put selanchor and selpoint: the
|
||||||
|
* four corners of the selection.
|
||||||
|
*/
|
||||||
|
if (2*selpoint.x < selstart.x + selend.x)
|
||||||
|
selanchor.x = selend.x-1;
|
||||||
|
else
|
||||||
|
selanchor.x = selstart.x;
|
||||||
|
|
||||||
|
if (2*selpoint.y < selstart.y + selend.y)
|
||||||
|
selanchor.y = selend.y;
|
||||||
|
else
|
||||||
|
selanchor.y = selstart.y;
|
||||||
|
}
|
||||||
selstate = DRAGGING;
|
selstate = DRAGGING;
|
||||||
}
|
}
|
||||||
if (selstate != ABOUT_TO && selstate != DRAGGING)
|
if (selstate != ABOUT_TO && selstate != DRAGGING)
|
||||||
selanchor = selpoint;
|
selanchor = selpoint;
|
||||||
selstate = DRAGGING;
|
selstate = DRAGGING;
|
||||||
|
if (seltype == LEXICOGRAPHIC) {
|
||||||
|
/*
|
||||||
|
* For normal selection, we set (selstart,selend) to
|
||||||
|
* (selpoint,selanchor) in some order.
|
||||||
|
*/
|
||||||
if (poslt(selpoint, selanchor)) {
|
if (poslt(selpoint, selanchor)) {
|
||||||
selstart = selpoint;
|
selstart = selpoint;
|
||||||
selend = selanchor;
|
selend = selanchor;
|
||||||
@ -3329,6 +3410,17 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
|
|||||||
selend = selpoint;
|
selend = selpoint;
|
||||||
incpos(selend);
|
incpos(selend);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* For rectangular selection, we may need to
|
||||||
|
* interchange x and y coordinates (if the user has
|
||||||
|
* dragged in the -x and +y directions, or vice versa).
|
||||||
|
*/
|
||||||
|
selstart.x = min(selanchor.x, selpoint.x);
|
||||||
|
selend.x = 1+max(selanchor.x, selpoint.x);
|
||||||
|
selstart.y = min(selanchor.y, selpoint.y);
|
||||||
|
selend.y = max(selanchor.y, selpoint.y);
|
||||||
|
}
|
||||||
sel_spread();
|
sel_spread();
|
||||||
} else if ((b == MBT_SELECT || b == MBT_EXTEND) && a == MA_RELEASE) {
|
} else if ((b == MBT_SELECT || b == MBT_EXTEND) && a == MA_RELEASE) {
|
||||||
if (selstate == DRAGGING) {
|
if (selstate == DRAGGING) {
|
||||||
@ -3336,7 +3428,7 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
|
|||||||
* We've completed a selection. We now transfer the
|
* We've completed a selection. We now transfer the
|
||||||
* data to the clipboard.
|
* data to the clipboard.
|
||||||
*/
|
*/
|
||||||
clipme(selstart, selend);
|
clipme(selstart, selend, (seltype == RECTANGULAR));
|
||||||
selstate = SELECTED;
|
selstate = SELECTED;
|
||||||
} else
|
} else
|
||||||
selstate = NO_SELECTION;
|
selstate = NO_SELECTION;
|
||||||
|
@ -712,7 +712,7 @@ void charclass(struct ctlpos *cp, char *stext, int sid, int listid,
|
|||||||
PUSHBTNHEIGHT ? EDITHEIGHT : PUSHBTNHEIGHT);
|
PUSHBTNHEIGHT ? EDITHEIGHT : PUSHBTNHEIGHT);
|
||||||
const static int percents[] = { 30, 40, 30 };
|
const static int percents[] = { 30, 40, 30 };
|
||||||
int i, xpos, percent;
|
int i, xpos, percent;
|
||||||
const int LISTHEIGHT = 66;
|
const int LISTHEIGHT = 52;
|
||||||
|
|
||||||
/* The static control. */
|
/* The static control. */
|
||||||
r.left = GAPBETWEEN;
|
r.left = GAPBETWEEN;
|
||||||
|
17
windlg.c
17
windlg.c
@ -479,6 +479,9 @@ enum { IDCX_ABOUT =
|
|||||||
IDC_MBWINDOWS,
|
IDC_MBWINDOWS,
|
||||||
IDC_MBXTERM,
|
IDC_MBXTERM,
|
||||||
IDC_MOUSEOVERRIDE,
|
IDC_MOUSEOVERRIDE,
|
||||||
|
IDC_SELTYPESTATIC,
|
||||||
|
IDC_SELTYPELEX,
|
||||||
|
IDC_SELTYPERECT,
|
||||||
IDC_CCSTATIC,
|
IDC_CCSTATIC,
|
||||||
IDC_CCLIST,
|
IDC_CCLIST,
|
||||||
IDC_CCSET,
|
IDC_CCSET,
|
||||||
@ -763,9 +766,10 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
|
CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
|
||||||
cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
|
cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
|
||||||
|
CheckRadioButton(hwnd, IDC_SELTYPELEX, IDC_SELTYPERECT,
|
||||||
|
cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT);
|
||||||
CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
|
CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
|
||||||
CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
|
CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
|
||||||
{
|
{
|
||||||
@ -1141,7 +1145,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (panel == selectionpanelstart) {
|
if (panel == selectionpanelstart) {
|
||||||
/* The Selection panel. Accelerators used: [acgo] d wxp hst */
|
/* The Selection panel. Accelerators used: [acgo] d wxp hst nr */
|
||||||
struct ctlpos cp;
|
struct ctlpos cp;
|
||||||
ctlposinit(&cp, hwnd, 80, 3, 13);
|
ctlposinit(&cp, hwnd, 80, 3, 13);
|
||||||
bartitle(&cp, "Options controlling copy and paste",
|
bartitle(&cp, "Options controlling copy and paste",
|
||||||
@ -1161,6 +1165,11 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
|
|||||||
checkbox(&cp,
|
checkbox(&cp,
|
||||||
"Shift overrides a&pplication's use of mouse",
|
"Shift overrides a&pplication's use of mouse",
|
||||||
IDC_MOUSEOVERRIDE);
|
IDC_MOUSEOVERRIDE);
|
||||||
|
radioline(&cp,
|
||||||
|
"Default selection mode (Alt+drag does the other one):",
|
||||||
|
IDC_SELTYPESTATIC, 2,
|
||||||
|
"&Normal", IDC_SELTYPELEX,
|
||||||
|
"&Rectangular block", IDC_SELTYPERECT, NULL);
|
||||||
endbox(&cp);
|
endbox(&cp);
|
||||||
beginbox(&cp, "Control the select-one-word-at-a-time mode",
|
beginbox(&cp, "Control the select-one-word-at-a-time mode",
|
||||||
IDC_BOX_SELECTION3);
|
IDC_BOX_SELECTION3);
|
||||||
@ -2407,6 +2416,10 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
|
|||||||
case IDC_MBXTERM:
|
case IDC_MBXTERM:
|
||||||
cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
|
cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
|
||||||
break;
|
break;
|
||||||
|
case IDC_SELTYPELEX:
|
||||||
|
case IDC_SELTYPERECT:
|
||||||
|
cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
|
||||||
|
break;
|
||||||
case IDC_MOUSEOVERRIDE:
|
case IDC_MOUSEOVERRIDE:
|
||||||
cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
|
cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
|
||||||
break;
|
break;
|
||||||
|
32
window.c
32
window.c
@ -1335,13 +1335,13 @@ static void reset_window(int reinit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void click(Mouse_Button b, int x, int y, int shift, int ctrl)
|
static void click(Mouse_Button b, int x, int y, int shift, int ctrl, int alt)
|
||||||
{
|
{
|
||||||
int thistime = GetMessageTime();
|
int thistime = GetMessageTime();
|
||||||
|
|
||||||
if (send_raw_mouse && !(cfg.mouse_override && shift)) {
|
if (send_raw_mouse && !(cfg.mouse_override && shift)) {
|
||||||
lastbtn = MBT_NOTHING;
|
lastbtn = MBT_NOTHING;
|
||||||
term_mouse(b, MA_CLICK, x, y, shift, ctrl);
|
term_mouse(b, MA_CLICK, x, y, shift, ctrl, alt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1354,7 +1354,7 @@ static void click(Mouse_Button b, int x, int y, int shift, int ctrl)
|
|||||||
lastact = MA_CLICK;
|
lastact = MA_CLICK;
|
||||||
}
|
}
|
||||||
if (lastact != MA_NOTHING)
|
if (lastact != MA_NOTHING)
|
||||||
term_mouse(b, lastact, x, y, shift, ctrl);
|
term_mouse(b, lastact, x, y, shift, ctrl, alt);
|
||||||
lasttime = thistime;
|
lasttime = thistime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1385,6 +1385,19 @@ static void show_mouseptr(int show)
|
|||||||
cursor_visible = show;
|
cursor_visible = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_alt_pressed(void)
|
||||||
|
{
|
||||||
|
BYTE keystate[256];
|
||||||
|
int r = GetKeyboardState(keystate);
|
||||||
|
if (!r)
|
||||||
|
return FALSE;
|
||||||
|
if (keystate[VK_MENU] & 0x80)
|
||||||
|
return TRUE;
|
||||||
|
if (keystate[VK_RMENU] & 0x80)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||||
WPARAM wParam, LPARAM lParam)
|
WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
@ -1730,14 +1743,15 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
|
|
||||||
if (send_raw_mouse) {
|
if (send_raw_mouse) {
|
||||||
/* send a mouse-down followed by a mouse up */
|
/* send a mouse-down followed by a mouse up */
|
||||||
|
|
||||||
term_mouse(b,
|
term_mouse(b,
|
||||||
MA_CLICK,
|
MA_CLICK,
|
||||||
TO_CHR_X(X_POS(lParam)),
|
TO_CHR_X(X_POS(lParam)),
|
||||||
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
||||||
wParam & MK_CONTROL);
|
wParam & MK_CONTROL, is_alt_pressed());
|
||||||
term_mouse(b, MA_RELEASE, TO_CHR_X(X_POS(lParam)),
|
term_mouse(b, MA_RELEASE, TO_CHR_X(X_POS(lParam)),
|
||||||
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
||||||
wParam & MK_CONTROL);
|
wParam & MK_CONTROL, is_alt_pressed());
|
||||||
} else {
|
} else {
|
||||||
/* trigger a scroll */
|
/* trigger a scroll */
|
||||||
term_scroll(0,
|
term_scroll(0,
|
||||||
@ -1754,6 +1768,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
case WM_RBUTTONUP:
|
case WM_RBUTTONUP:
|
||||||
{
|
{
|
||||||
int button, press;
|
int button, press;
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
button = MBT_LEFT;
|
button = MBT_LEFT;
|
||||||
@ -1786,13 +1801,14 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
if (press) {
|
if (press) {
|
||||||
click(button,
|
click(button,
|
||||||
TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam)),
|
TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam)),
|
||||||
wParam & MK_SHIFT, wParam & MK_CONTROL);
|
wParam & MK_SHIFT, wParam & MK_CONTROL,
|
||||||
|
is_alt_pressed());
|
||||||
SetCapture(hwnd);
|
SetCapture(hwnd);
|
||||||
} else {
|
} else {
|
||||||
term_mouse(button, MA_RELEASE,
|
term_mouse(button, MA_RELEASE,
|
||||||
TO_CHR_X(X_POS(lParam)),
|
TO_CHR_X(X_POS(lParam)),
|
||||||
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
||||||
wParam & MK_CONTROL);
|
wParam & MK_CONTROL, is_alt_pressed());
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1815,7 +1831,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
b = MBT_RIGHT;
|
b = MBT_RIGHT;
|
||||||
term_mouse(b, MA_DRAG, TO_CHR_X(X_POS(lParam)),
|
term_mouse(b, MA_DRAG, TO_CHR_X(X_POS(lParam)),
|
||||||
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
|
||||||
wParam & MK_CONTROL);
|
wParam & MK_CONTROL, is_alt_pressed());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case WM_NCMOUSEMOVE:
|
case WM_NCMOUSEMOVE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user