blob: 4d696cbc933369ef0b9a55173419dc4d64bfe947 [file] [log] [blame]
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00003 * 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
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000023
24#include <rfb_win32/WMCursor.h>
25#include <rfb_win32/OSVersion.h>
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000026#include <rfb_win32/DynamicFn.h>
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000027#include <rfb/Exception.h>
28#include <rfb/LogWriter.h>
29
30using namespace rdr;
31using namespace rfb;
32using namespace rfb::win32;
33
34static LogWriter vlog("WMCursor");
35
36
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000037#ifdef CURSOR_SHOWING
38#define RFB_HAVE_GETCURSORINFO
39#else
40#pragma message(" NOTE: Not building GetCursorInfo support.")
41#endif
42
43#ifdef RFB_HAVE_GETCURSORINFO
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000044typedef BOOL (WINAPI *_GetCursorInfo_proto)(PCURSORINFO pci);
45DynamicFn<_GetCursorInfo_proto> _GetCursorInfo(_T("user32.dll"), "GetCursorInfo");
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000046#endif
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000047
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000048WMCursor::WMCursor() : hooks(0), use_getCursorInfo(false), cursor(0) {
49#ifdef RFB_HAVE_GETCURSORINFO
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000050 // Check the OS version
51 bool is_win98 = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
52 (osVersion.dwMajorVersion > 4) || ((osVersion.dwMajorVersion == 4) && (osVersion.dwMinorVersion > 0));
53 bool is_win2K = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osVersion.dwMajorVersion >= 5);
54
55 // Use GetCursorInfo if OS version is sufficient
56 use_getCursorInfo = (is_win98 || is_win2K) && _GetCursorInfo.isValid();
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000057#endif
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000058 cursor = (HCURSOR)LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000059 if (!use_getCursorInfo) {
60 hooks = new WMCursorHooks();
61 if (hooks && hooks->start()) {
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000062 vlog.info("falling back to cursor hooking: %p", hooks);
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000063 } else {
64 delete hooks;
65 hooks = 0;
66 vlog.error("unable to monitor cursor shape");
67 }
68 } else {
69 vlog.info("using GetCursorInfo");
70 }
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000071}
72
73WMCursor::~WMCursor() {
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000074 vlog.debug("deleting WMCursorHooks (%p)", hooks);
75 if (hooks)
76 delete hooks;
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000077}
78
79WMCursor::Info
80WMCursor::getCursorInfo() {
81 Info result;
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000082#ifdef RFB_HAVE_GETCURSORINFO
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000083 if (use_getCursorInfo) {
84 CURSORINFO info;
85 info.cbSize = sizeof(CURSORINFO);
86 if ((*_GetCursorInfo)(&info)) {
87 result.cursor = info.hCursor;
88 result.position = Point(info.ptScreenPos.x, info.ptScreenPos.y);
89 result.visible = info.flags & CURSOR_SHOWING;
90 return result;
91 }
92 }
93#endif
94 // Fall back to the old way of doing things
95 POINT pos;
Constantin Kaplinsky0a1eca12006-04-16 07:28:14 +000096 if (hooks)
97 cursor = hooks->getCursor();
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +000098 result.cursor = cursor;
99 result.visible = cursor != 0;
100 GetCursorPos(&pos);
101 result.position.x = pos.x;
102 result.position.y = pos.y;
103 return result;
104}