diff --git win/tkWinPointer.c win/tkWinPointer.c
index 6f1f840f1..251b5b9d7 100644
--- win/tkWinPointer.c
+++ win/tkWinPointer.c
@@ -81,6 +81,12 @@ TkWinGetModifierState(void)
     if (GetKeyState(VK_RBUTTON) & 0x8000) {
 	state |= Button3Mask;
     }
+    if (GetKeyState(VK_XBUTTON1) & 0x8000) {
+	state |= Button4Mask;
+    }
+    if (GetKeyState(VK_XBUTTON2) & 0x8000) {
+	state |= Button5Mask;
+    }
     return state;
 }
 
diff --git win/tkWinX.c win/tkWinX.c
index fd576a400..0293bc67b 100644
--- win/tkWinX.c
+++ win/tkWinX.c
@@ -930,9 +930,12 @@ Tk_TranslateWinEvent(
     case WM_MBUTTONDBLCLK:
     case WM_RBUTTONDOWN:
     case WM_RBUTTONDBLCLK:
+    case WM_XBUTTONDOWN:
+    case WM_XBUTTONDBLCLK:
     case WM_LBUTTONUP:
     case WM_MBUTTONUP:
     case WM_RBUTTONUP:
+    case WM_XBUTTONUP:
     case WM_MOUSEMOVE:
 	Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
 	return 1;
@@ -1783,6 +1786,14 @@ TkWinResendEvent(
 	msg = WM_RBUTTONDOWN;
 	wparam = MK_RBUTTON;
 	break;
+    case Button4:
+	msg = WM_XBUTTONDOWN;
+	wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1);
+	break;
+    case Button5:
+	msg = WM_XBUTTONDOWN;
+	wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2);
+	break;
     default:
 	return 0;
     }
@@ -1796,6 +1807,12 @@ TkWinResendEvent(
     if (eventPtr->xbutton.state & Button3Mask) {
 	wparam |= MK_RBUTTON;
     }
+    if (eventPtr->xbutton.state & Button4Mask) {
+	wparam |= MK_XBUTTON1;
+    }
+    if (eventPtr->xbutton.state & Button5Mask) {
+	wparam |= MK_XBUTTON2;
+    }
     if (eventPtr->xbutton.state & ShiftMask) {
 	wparam |= MK_SHIFT;
     }
