#define VK_PROCESSKEY 0xE5
#endif
-/* Needed for mouse wheel support and not defined in earlier SDKs. */
+/* Mouse wheel support. */
#ifndef WM_MOUSEWHEEL
-#define WM_MOUSEWHEEL 0x020A
+#define WM_MOUSEWHEEL 0x020A /* not defined in earlier SDKs */
+#endif
+#ifndef WHEEL_DELTA
+#define WHEEL_DELTA 120
#endif
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static void another_font(int);
static void deinit_fonts(void);
static void set_input_locale(HKL);
+static int do_mouse_wheel_msg(UINT message, WPARAM wParam, LPARAM lParam);
static int is_full_screen(void);
static void make_full_screen(void);
static LPARAM pend_netevent_lParam = 0;
static void enact_pending_netevent(void);
static void flash_window(int mode);
+static void sys_cursor_update(void);
static time_t last_movement = 0;
+static int caret_x = -1, caret_y = -1;
+
#define FONT_NORMAL 0
#define FONT_BOLD 1
#define FONT_UNDERLINE 2
static OSVERSIONINFO osVersion;
+static UINT wm_mousewheel = WM_MOUSEWHEEL;
+
/* Dummy routine, only required in plink. */
void ldisc_update(int echo, int edit)
{
}
/*
+ * If we're running a version of Windows that doesn't support
+ * WM_MOUSEWHEEL, find out what message number we should be
+ * using instead.
+ */
+ if (osVersion.dwMajorVersion < 4 ||
+ (osVersion.dwMajorVersion == 4 &&
+ osVersion.dwPlatformId != VER_PLATFORM_WIN32_NT))
+ wm_mousewheel = RegisterWindowMessage("MSWHEEL_ROLLMSG");
+
+ /*
* See if we can find our Help file.
*/
{
timer_id = 0;
}
HideCaret(hwnd);
- term_out();
+ if (GetCapture() != hwnd)
+ term_out();
term_update();
ShowCaret(hwnd);
case WM_TIMER:
if (pending_netevent)
enact_pending_netevent();
- term_out();
+ if (GetCapture() != hwnd)
+ term_out();
noise_regular();
HideCaret(hwnd);
term_update();
#define TO_CHR_X(x) ((((x)<0 ? (x)-font_width+1 : (x))-offset_width) / font_width)
#define TO_CHR_Y(y) ((((y)<0 ? (y)-font_height+1: (y))-offset_height) / font_height)
-#define WHEEL_DELTA 120
- case WM_MOUSEWHEEL:
- {
- wheel_accumulator += (short) HIWORD(wParam);
- wParam = LOWORD(wParam);
-
- /* process events when the threshold is reached */
- while (abs(wheel_accumulator) >= WHEEL_DELTA) {
- int b;
-
- /* reduce amount for next time */
- if (wheel_accumulator > 0) {
- b = MBT_WHEEL_UP;
- wheel_accumulator -= WHEEL_DELTA;
- } else if (wheel_accumulator < 0) {
- b = MBT_WHEEL_DOWN;
- wheel_accumulator += WHEEL_DELTA;
- } else
- break;
-
- if (send_raw_mouse) {
- /* send a mouse-down followed by a mouse up */
-
- term_mouse(b,
- MA_CLICK,
- TO_CHR_X(X_POS(lParam)),
- TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
- wParam & MK_CONTROL, is_alt_pressed());
- term_mouse(b, MA_RELEASE, TO_CHR_X(X_POS(lParam)),
- TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
- wParam & MK_CONTROL, is_alt_pressed());
- } else {
- /* trigger a scroll */
- term_scroll(0,
- b == MBT_WHEEL_UP ? -rows / 2 : rows / 2);
- }
- }
- return 0;
- }
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
*/
noise_ultralight(lParam);
- if (wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
+ if (wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) &&
+ GetCapture() == hwnd) {
Mouse_Button b;
if (wParam & MK_LBUTTON)
b = MBT_LEFT;
show_mouseptr(1);
has_focus = FALSE;
DestroyCaret();
+ caret_x = caret_y = -1; /* ensure caret is replaced next time */
term_out();
term_update();
break;
case WM_FULLSCR_ON_MAX:
fullscr_on_max = TRUE;
break;
+ case WM_MOVE:
+ sys_cursor_update();
+ break;
case WM_SIZE:
#ifdef RDB_DEBUG_PATCH
debug((27, "WM_SIZE %s (%d,%d)",
reset_window(0);
}
}
+ sys_cursor_update();
return 0;
case WM_VSCROLL:
switch (LOWORD(wParam)) {
/* wParam == Font number */
/* lParam == Locale */
set_input_locale((HKL)lParam);
+ sys_cursor_update();
break;
case WM_IME_NOTIFY:
if(wParam == IMN_SETOPENSTATUS) {
SetCursor(LoadCursor(NULL, IDC_ARROW));
return TRUE;
}
+ default:
+ if (message == wm_mousewheel) {
+ int shift_pressed=0, control_pressed=0, alt_pressed=0;
+
+ if (message == WM_MOUSEWHEEL) {
+ wheel_accumulator += (short)HIWORD(wParam);
+ shift_pressed=LOWORD(wParam) & MK_SHIFT;
+ control_pressed=LOWORD(wParam) & MK_CONTROL;
+ } else {
+ BYTE keys[256];
+ wheel_accumulator += (int)wParam;
+ if (GetKeyboardState(keys)!=0) {
+ shift_pressed=keys[VK_SHIFT]&0x80;
+ control_pressed=keys[VK_CONTROL]&0x80;
+ }
+ }
+
+ /* process events when the threshold is reached */
+ while (abs(wheel_accumulator) >= WHEEL_DELTA) {
+ int b;
+
+ /* reduce amount for next time */
+ if (wheel_accumulator > 0) {
+ b = MBT_WHEEL_UP;
+ wheel_accumulator -= WHEEL_DELTA;
+ } else if (wheel_accumulator < 0) {
+ b = MBT_WHEEL_DOWN;
+ wheel_accumulator += WHEEL_DELTA;
+ } else
+ break;
+
+ if (send_raw_mouse &&
+ !(cfg.mouse_override && shift_pressed)) {
+ /* send a mouse-down followed by a mouse up */
+ term_mouse(b,
+ MA_CLICK,
+ TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)), shift_pressed,
+ control_pressed, is_alt_pressed());
+ term_mouse(b, MA_RELEASE, TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)), shift_pressed,
+ control_pressed, is_alt_pressed());
+ } else {
+ /* trigger a scroll */
+ term_scroll(0,
+ b == MBT_WHEEL_UP ? -rows / 2 : rows / 2);
+ }
+ }
+ return 0;
+ }
}
return DefWindowProc(hwnd, message, wParam, lParam);
*/
void sys_cursor(int x, int y)
{
+ int cx, cy;
+
+ if (!has_focus) return;
+
+ /*
+ * Avoid gratuitously re-updating the cursor position and IMM
+ * window if there's no actual change required.
+ */
+ cx = x * font_width + offset_width;
+ cy = y * font_height + offset_height;
+ if (cx == caret_x && cy == caret_y)
+ return;
+ caret_x = cx;
+ caret_y = cy;
+
+ sys_cursor_update();
+}
+
+static void sys_cursor_update(void)
+{
COMPOSITIONFORM cf;
HIMC hIMC;
if (!has_focus) return;
-
- SetCaretPos(x * font_width + offset_width,
- y * font_height + offset_height);
+
+ if (caret_x < 0 || caret_y < 0)
+ return;
+
+ SetCaretPos(caret_x, caret_y);
/* IMM calls on Win98 and beyond only */
if(osVersion.dwPlatformId == VER_PLATFORM_WIN32s) return; /* 3.11 */
/* we should have the IMM functions */
hIMC = ImmGetContext(hwnd);
cf.dwStyle = CFS_POINT;
- cf.ptCurrentPos.x = x * font_width + offset_width;
- cf.ptCurrentPos.y = y * font_height + offset_height;
+ cf.ptCurrentPos.x = caret_x;
+ cf.ptCurrentPos.y = caret_y;
ImmSetCompositionWindow(hIMC, &cf);
ImmReleaseContext(hwnd, hIMC);
p += sprintf((char *) p, "\x1B%c", xkey);
else {
int app_flg = (app_cursor_keys && !cfg.no_applic_c);
- /* VT100 & VT102 manuals both state the app cursor keys
- * only work if the app keypad is on.
+#if 0
+ /*
+ * RDB: VT100 & VT102 manuals both state the
+ * app cursor keys only work if the app keypad
+ * is on.
+ *
+ * SGT: That may well be true, but xterm
+ * disagrees and so does at least one
+ * application, so I've #if'ed this out and the
+ * behaviour is back to PuTTY's original: app
+ * cursor and app keypad are independently
+ * switchable modes. If anyone complains about
+ * _this_ I'll have to put in a configurable
+ * option.
*/
if (!app_keypad_keys)
app_flg = 0;
+#endif
/* Useful mapping of Ctrl-arrows */
if (shift_state == 2)
app_flg = !app_flg;