summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx.c3
-rw-r--r--gfx.h23
-rw-r--r--openttd.c1
-rw-r--r--video/sdl_v.c9
-rw-r--r--video/win32_v.c53
5 files changed, 78 insertions, 11 deletions
diff --git a/gfx.c b/gfx.c
index 8c7a94feb..3dab6b132 100644
--- a/gfx.c
+++ b/gfx.c
@@ -1654,6 +1654,9 @@ void DrawMouseCursor(void)
int w;
int h;
+ /* Redraw mouse cursor but only when it's inside the window */
+ if (!_cursor.in_window) return;
+
// Don't draw the mouse cursor if it's already drawn
if (_cursor.visible) {
if (!_cursor.dirty) return;
diff --git a/gfx.h b/gfx.h
index 66eb5eee1..4e605a24e 100644
--- a/gfx.h
+++ b/gfx.h
@@ -21,17 +21,18 @@ struct DrawPixelInfo {
typedef struct CursorVars {
- Point pos, size, offs, delta;
- Point draw_pos, draw_size;
- CursorID sprite;
-
- int wheel; // mouse wheel movement
- const CursorID *animate_list, *animate_cur;
- uint animate_timeout;
-
- bool visible;
- bool dirty;
- bool fix_at;
+ Point pos, size, offs, delta; ///< position, size, offset from top-left, and movement
+ Point draw_pos, draw_size; ///< position and size bounding-box for drawing
+ CursorID sprite; ///< current image of cursor
+
+ int wheel; ///< mouse wheel movement
+ const CursorID *animate_list, *animate_cur; ///< in case of animated cursor, list of frames
+ uint animate_timeout; ///< current frame in list of animated cursor
+
+ bool visible; ///< cursor is visible
+ bool dirty; ///< the rect occupied by the mouse is dirty (redraw)
+ bool fix_at; ///< mouse is moving, but cursor is not (used for scrolling)
+ bool in_window; ///< mouse inside this window, determines drawing logic
} CursorVars;
diff --git a/openttd.c b/openttd.c
index bc928779f..15b20e140 100644
--- a/openttd.c
+++ b/openttd.c
@@ -450,6 +450,7 @@ int ttd_main(int argc, char* argv[])
// initialize the ingame console
IConsoleInit();
+ _cursor.in_window = true;
InitializeGUI();
IConsoleCmdExec("exec scripts/autoexec.scr 0");
diff --git a/video/sdl_v.c b/video/sdl_v.c
index 3b27c7ad6..d190237fb 100644
--- a/video/sdl_v.c
+++ b/video/sdl_v.c
@@ -345,6 +345,15 @@ static int PollEvent(void)
}
break;
+ case SDL_ACTIVEEVENT:
+ if (ev.active.gain == 1) // mouse entered the window, enable cursor
+ _cursor.in_window = true;
+ else if (ev.active.gain == 0) {
+ UndrawMouseCursor(); // mouse left the window, undraw cursor
+ _cursor.in_window = false;
+ }
+ break;
+
case SDL_QUIT:
// do not ask to quit on the main screen
if (_game_mode != GM_MENU) {
diff --git a/video/win32_v.c b/video/win32_v.c
index 3ecda2528..aff4f2526 100644
--- a/video/win32_v.c
+++ b/video/win32_v.c
@@ -184,9 +184,40 @@ int RedrawScreenDebug(void)
}
#endif
+/* Windows 95 will not have a WM_MOUSELEAVE message, so define it if
+ * needed. There is no such event as WM_MOUSEENTER, we just made this up :) */
+#define WM_MOUSEENTER WM_USER + 1
+#if !defined(WM_MOUSELEAVE)
+#define WM_MOUSELEAVE 0x02A3
+#endif
+#define TID_POLLMOUSE 1
+#define MOUSE_POLL_DELAY 75
+
+static void CALLBACK TrackMouseTimerProc(HWND hwnd, UINT msg, UINT event, DWORD time)
+{
+ RECT rc;
+ POINT pt;
+
+ /* Get the rectangle of our window and translate it to screen coordinates.
+ * Compare this with the current screen coordinates of the mouse and if it
+ * falls outside of the area or our window we have left the window. */
+ GetClientRect(hwnd, &rc);
+ MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT)&rc, 2);
+ GetCursorPos(&pt);
+
+ if (!PtInRect(&rc, pt) || (WindowFromPoint(pt) != hwnd)) {
+ KillTimer(hwnd, event);
+ PostMessage(hwnd, WM_MOUSELEAVE, 0, 0L);
+ }
+}
+
static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
+ case WM_CREATE:
+ SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
+ break;
+
case WM_PAINT: {
PAINTSTRUCT ps;
HDC dc,dc2;
@@ -259,11 +290,33 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
_right_button_down = false;
return 0;
+ case WM_MOUSEENTER:
+ printf("enter\n");
+ _cursor.in_window = true;
+ DrawMouseCursor();
+ break;
+
+ case WM_MOUSELEAVE:
+ printf("enter\n");
+ UndrawMouseCursor();
+ _cursor.in_window = false;
+ break;
+
case WM_MOUSEMOVE: {
int x = (int16)LOWORD(lParam);
int y = (int16)HIWORD(lParam);
POINT pt;
+ /* If the mouse was not in the window and it has moved it means it has
+ * come into the window, so send a WM_MOUSEENTER message. Also start
+ * tracking the mouse for exiting the window */
+ if (!_cursor.in_window) {
+ _cursor.in_window = true;
+ SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
+
+ if (hwnd != GetCapture()) PostMessage(hwnd, WM_MOUSEENTER, 0, 0L);
+ }
+
if (_wnd.double_size) {
x /= 2;
y /= 2;