diff options
-rw-r--r-- | gfx.c | 3 | ||||
-rw-r--r-- | gfx.h | 23 | ||||
-rw-r--r-- | openttd.c | 1 | ||||
-rw-r--r-- | video/sdl_v.c | 9 | ||||
-rw-r--r-- | video/win32_v.c | 53 |
5 files changed, 78 insertions, 11 deletions
@@ -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; @@ -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; @@ -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; |