blob: 871d93769e93477e9f99a7a91996425cd2ea8d4d [file] [log] [blame]
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19// -=- WMCursor.cxx
20
21// *** DOESN'T SEEM TO WORK WITH GetCursorInfo POS CODE BUILT-IN UNDER NT4SP6
22// *** INSTEAD, WE LOOK FOR Win2000/Win98 OR ABOVE
23#define WINVER 0x0500
24
25#include <rfb_win32/WMCursor.h>
26#include <rfb_win32/OSVersion.h>
27#include <rfb_win32/Win32Util.h>
28#include <rfb/Exception.h>
29#include <rfb/LogWriter.h>
30
31using namespace rdr;
32using namespace rfb;
33using namespace rfb::win32;
34
35static LogWriter vlog("WMCursor");
36
37
38typedef BOOL (WINAPI *_GetCursorInfo_proto)(PCURSORINFO pci);
39DynamicFn<_GetCursorInfo_proto> _GetCursorInfo(_T("user32.dll"), "GetCursorInfo");
40
41
42WMCursor::WMCursor() : hooks(0), library(0), use_getCursorInfo(false), cursor(0) {
43#if (WINVER >= 0x0500)
44 // Check the OS version
45 bool is_win98 = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
46 (osVersion.dwMajorVersion > 4) || ((osVersion.dwMajorVersion == 4) && (osVersion.dwMinorVersion > 0));
47 bool is_win2K = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osVersion.dwMajorVersion >= 5);
48
49 // Use GetCursorInfo if OS version is sufficient
50 use_getCursorInfo = (is_win98 || is_win2K) && _GetCursorInfo.isValid();
51#else
52#pragma message ("not building in GetCursorInfo support")
53#endif
54 if (!use_getCursorInfo) {
55 hooks = new WMCursorHooks();
56 if (hooks && hooks->start()) {
57 vlog.info("falling back to cursor hooking");
58 } else {
59 delete hooks;
60 hooks = 0;
61 vlog.error("unable to monitor cursor shape");
62 }
63 } else {
64 vlog.info("using GetCursorInfo");
65 }
66 cursor = (HCURSOR)LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
67}
68
69WMCursor::~WMCursor() {
70 if (hooks) delete hooks;
71 if (library) FreeLibrary(library);
72}
73
74WMCursor::Info
75WMCursor::getCursorInfo() {
76 Info result;
77#if (WINVER >= 0x0500)
78 if (use_getCursorInfo) {
79 CURSORINFO info;
80 info.cbSize = sizeof(CURSORINFO);
81 if ((*_GetCursorInfo)(&info)) {
82 result.cursor = info.hCursor;
83 result.position = Point(info.ptScreenPos.x, info.ptScreenPos.y);
84 result.visible = info.flags & CURSOR_SHOWING;
85 return result;
86 }
87 }
88#endif
89 // Fall back to the old way of doing things
90 POINT pos;
91 if (hooks) cursor = hooks->getCursor();
92 result.cursor = cursor;
93 result.visible = cursor != 0;
94 GetCursorPos(&pos);
95 result.position.x = pos.x;
96 result.position.y = pos.y;
97 return result;
98}