sl@0
|
1 |
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// wins\specific\multitouch.cpp
|
sl@0
|
15 |
//
|
sl@0
|
16 |
//
|
sl@0
|
17 |
#include "multitouch.h"
|
sl@0
|
18 |
#include "resource.h"
|
sl@0
|
19 |
|
sl@0
|
20 |
#define KDefaultMaxProximity -100
|
sl@0
|
21 |
#define KDefaultMaxPressure 5000
|
sl@0
|
22 |
#define KDefaultPressureStep 500
|
sl@0
|
23 |
#define KDefaultProximityStep 5
|
sl@0
|
24 |
|
sl@0
|
25 |
// Static members
|
sl@0
|
26 |
DMultiMouse DMultiMouse::iMice[KMaxMice];
|
sl@0
|
27 |
int DMultiMouse::iNumMice = 0;
|
sl@0
|
28 |
DMultiMouse* DMultiMouse::iPrimary = 0;
|
sl@0
|
29 |
int DMultiMouse::iMouseId = 0;
|
sl@0
|
30 |
int DMultiTouch::iNumberOfMice = 0;
|
sl@0
|
31 |
bool DMultiTouch::iMultiTouchSupported= FALSE;
|
sl@0
|
32 |
bool DMultiTouch::iMultiTouchCreated= FALSE;
|
sl@0
|
33 |
bool DMultiTouch::iMultiTouchTempEnabled= FALSE;
|
sl@0
|
34 |
|
sl@0
|
35 |
// Function pointers for raw input APIs
|
sl@0
|
36 |
TYPEOF_RegisterRawInputDevices pfnRegisterRawInputDevices= NULL;
|
sl@0
|
37 |
TYPEOF_GetRawInputData pfnGetRawInputData= NULL;
|
sl@0
|
38 |
TYPEOF_GetRawInputDeviceList pfnGetRawInputDeviceList=NULL;
|
sl@0
|
39 |
|
sl@0
|
40 |
/**
|
sl@0
|
41 |
* Initialise the proximity and pressure information if undefined by the user
|
sl@0
|
42 |
*/
|
sl@0
|
43 |
DMultiTouch::DMultiTouch(TInt aProximityStep, TInt aPressureStep)
|
sl@0
|
44 |
{
|
sl@0
|
45 |
iZMaxRange = KDefaultMaxProximity;
|
sl@0
|
46 |
iMaxPressure = KDefaultMaxPressure;
|
sl@0
|
47 |
iProximityStep = (aProximityStep == -1) ? KDefaultProximityStep : aProximityStep;
|
sl@0
|
48 |
iPressureStep = (aPressureStep == -1) ? KDefaultPressureStep : aPressureStep;
|
sl@0
|
49 |
}
|
sl@0
|
50 |
|
sl@0
|
51 |
/**
|
sl@0
|
52 |
* Register all the mice
|
sl@0
|
53 |
*/
|
sl@0
|
54 |
BOOL DMultiTouch::Register()
|
sl@0
|
55 |
{
|
sl@0
|
56 |
RAWINPUTDEVICE device;
|
sl@0
|
57 |
device.usUsagePage = 0x01;
|
sl@0
|
58 |
device.usUsage = 0x02;
|
sl@0
|
59 |
device.dwFlags = RIDEV_NOLEGACY; // adds HID mouse and also ignores legacy mouse messages
|
sl@0
|
60 |
device.hwndTarget = 0;
|
sl@0
|
61 |
ShowCursors();
|
sl@0
|
62 |
return pfnRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE));
|
sl@0
|
63 |
}
|
sl@0
|
64 |
|
sl@0
|
65 |
/**
|
sl@0
|
66 |
* Unregister mice devices
|
sl@0
|
67 |
*/
|
sl@0
|
68 |
BOOL DMultiTouch::UnRegister()
|
sl@0
|
69 |
{
|
sl@0
|
70 |
RAWINPUTDEVICE device;
|
sl@0
|
71 |
device.usUsagePage = 0x01;
|
sl@0
|
72 |
device.usUsage = 0x02;
|
sl@0
|
73 |
device.dwFlags = RIDEV_REMOVE;
|
sl@0
|
74 |
device.hwndTarget = NULL;
|
sl@0
|
75 |
HideCursors();
|
sl@0
|
76 |
return pfnRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE));
|
sl@0
|
77 |
}
|
sl@0
|
78 |
|
sl@0
|
79 |
|
sl@0
|
80 |
/* * Handle multi-input Window messages
|
sl@0
|
81 |
*/
|
sl@0
|
82 |
void DMultiTouch::OnWmInput(HWND aHWnd,TUint aMessage,TUint aWParam,TUint aLParam,HWND aParentHwnd)
|
sl@0
|
83 |
{
|
sl@0
|
84 |
RAWINPUT ri;
|
sl@0
|
85 |
UINT dwSize = sizeof(ri);
|
sl@0
|
86 |
if (pfnGetRawInputData((HRAWINPUT)aLParam, RID_INPUT, &ri, &dwSize, sizeof(RAWINPUTHEADER))==(UINT)-1)
|
sl@0
|
87 |
{
|
sl@0
|
88 |
OutputDebugString(TEXT("GetRawInputData has an error !\n"));
|
sl@0
|
89 |
}
|
sl@0
|
90 |
else if (ri.header.dwType == RIM_TYPEMOUSE)
|
sl@0
|
91 |
{
|
sl@0
|
92 |
DMultiMouse* mouse = DMultiMouse::Find(ri.header.hDevice);
|
sl@0
|
93 |
if (mouse)
|
sl@0
|
94 |
{
|
sl@0
|
95 |
if (!DMultiMouse::iPrimary)
|
sl@0
|
96 |
{
|
sl@0
|
97 |
DMultiMouse::iPrimary = mouse;
|
sl@0
|
98 |
DMultiMouse::iPrimary->iIsPrimary = TRUE;
|
sl@0
|
99 |
}
|
sl@0
|
100 |
mouse->HandleRawMouseEvent(ri.data.mouse, aParentHwnd);
|
sl@0
|
101 |
}
|
sl@0
|
102 |
}
|
sl@0
|
103 |
DefWindowProcA(aHWnd, aMessage, aWParam, aLParam);
|
sl@0
|
104 |
}
|
sl@0
|
105 |
|
sl@0
|
106 |
void DMultiTouch::HideCursors()
|
sl@0
|
107 |
{
|
sl@0
|
108 |
for (int ii=0; ii<DMultiMouse::iNumMice; ii++)
|
sl@0
|
109 |
{
|
sl@0
|
110 |
DMultiMouse::iMice[ii].iCursorWnd.Hide();
|
sl@0
|
111 |
}
|
sl@0
|
112 |
}
|
sl@0
|
113 |
|
sl@0
|
114 |
void DMultiTouch::ShowCursors()
|
sl@0
|
115 |
{
|
sl@0
|
116 |
for (int ii=0; ii<DMultiMouse::iNumMice; ii++)
|
sl@0
|
117 |
{
|
sl@0
|
118 |
DMultiMouse::iMice[ii].iCursorWnd.Show();
|
sl@0
|
119 |
}
|
sl@0
|
120 |
}
|
sl@0
|
121 |
|
sl@0
|
122 |
/**
|
sl@0
|
123 |
* The cursor window procedure
|
sl@0
|
124 |
*/
|
sl@0
|
125 |
static LRESULT CALLBACK CursorWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
sl@0
|
126 |
{
|
sl@0
|
127 |
if (msg==WM_PAINT)
|
sl@0
|
128 |
{
|
sl@0
|
129 |
PAINTSTRUCT ps;
|
sl@0
|
130 |
HDC hdc = BeginPaint(hwnd, &ps);
|
sl@0
|
131 |
CursorWindow* wnd = (CursorWindow*)GetWindowLong(hwnd, GWL_USERDATA);
|
sl@0
|
132 |
DrawIconEx(hdc,0,0, wnd->iCursor,0,0,0,NULL, DI_NORMAL | DI_DEFAULTSIZE);
|
sl@0
|
133 |
EndPaint(hwnd, &ps);
|
sl@0
|
134 |
return 0;
|
sl@0
|
135 |
}
|
sl@0
|
136 |
return DefWindowProc(hwnd, msg, wp, lp);
|
sl@0
|
137 |
}
|
sl@0
|
138 |
|
sl@0
|
139 |
CursorWindow::CursorWindow(): iHwnd(NULL),iCursor(NULL),iNumber(0)
|
sl@0
|
140 |
{
|
sl@0
|
141 |
}
|
sl@0
|
142 |
|
sl@0
|
143 |
HWND CursorWindow::Create(HMODULE hm, HWND hwndParent, int number)
|
sl@0
|
144 |
{
|
sl@0
|
145 |
// Create the window
|
sl@0
|
146 |
static ATOM atom = NULL;
|
sl@0
|
147 |
if (!atom)
|
sl@0
|
148 |
{
|
sl@0
|
149 |
WNDCLASSEX wcex;
|
sl@0
|
150 |
ZeroMemory(&wcex, sizeof(wcex));
|
sl@0
|
151 |
wcex.cbSize = sizeof(WNDCLASSEX);
|
sl@0
|
152 |
wcex.style = CS_OWNDC;
|
sl@0
|
153 |
wcex.lpfnWndProc = (WNDPROC)CursorWndProc;
|
sl@0
|
154 |
wcex.hInstance = (HINSTANCE)hm;
|
sl@0
|
155 |
wcex.lpszClassName = TEXT("CursorWndClass");
|
sl@0
|
156 |
wcex.hbrBackground = CreateSolidBrush(RGB(255,0,0));//Background color is also for the number
|
sl@0
|
157 |
atom = RegisterClassEx(&wcex);
|
sl@0
|
158 |
}
|
sl@0
|
159 |
iHwnd = CreateWindowA((LPCSTR)atom, NULL, WS_CHILD|WS_CLIPSIBLINGS, 0,0,64,64, hwndParent, NULL, hm, NULL);
|
sl@0
|
160 |
SetWindowLong(iHwnd, GWL_USERDATA, (LONG)this);
|
sl@0
|
161 |
iNumber = number;
|
sl@0
|
162 |
return iHwnd;
|
sl@0
|
163 |
}
|
sl@0
|
164 |
|
sl@0
|
165 |
void CursorWindow::Show()
|
sl@0
|
166 |
{
|
sl@0
|
167 |
ShowWindow(iHwnd, SW_NORMAL);
|
sl@0
|
168 |
}
|
sl@0
|
169 |
|
sl@0
|
170 |
void CursorWindow::Hide()
|
sl@0
|
171 |
{
|
sl@0
|
172 |
ShowWindow(iHwnd, SW_HIDE);
|
sl@0
|
173 |
}
|
sl@0
|
174 |
|
sl@0
|
175 |
BOOL CursorWindow::SetCursor(HCURSOR hc)
|
sl@0
|
176 |
{
|
sl@0
|
177 |
// Duplicate the cursor (because we're going to draw a number on the mask)
|
sl@0
|
178 |
if (iCursor)
|
sl@0
|
179 |
{
|
sl@0
|
180 |
DestroyCursor(iCursor);
|
sl@0
|
181 |
iCursor = NULL;
|
sl@0
|
182 |
}
|
sl@0
|
183 |
iCursor = CopyCursor(hc);
|
sl@0
|
184 |
|
sl@0
|
185 |
// Get information about the cursor, and select its mask bitmap into a temporary DC.
|
sl@0
|
186 |
ICONINFO ii;
|
sl@0
|
187 |
GetIconInfo(iCursor, &ii);
|
sl@0
|
188 |
iHotspot.x = ii.xHotspot;
|
sl@0
|
189 |
iHotspot.y = ii.yHotspot;
|
sl@0
|
190 |
HDC hdc = CreateCompatibleDC(NULL);
|
sl@0
|
191 |
SelectObject(hdc, ii.hbmMask);
|
sl@0
|
192 |
|
sl@0
|
193 |
// Get the cursor's pixel size
|
sl@0
|
194 |
BITMAPINFO bmi;
|
sl@0
|
195 |
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
sl@0
|
196 |
bmi.bmiHeader.biBitCount = 0;
|
sl@0
|
197 |
GetDIBits(hdc, ii.hbmMask, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
|
sl@0
|
198 |
int cx = bmi.bmiHeader.biWidth;
|
sl@0
|
199 |
int cy = bmi.bmiHeader.biHeight;
|
sl@0
|
200 |
|
sl@0
|
201 |
// Monochrome cursors have a double-height hbmMask. The top half contains the AND
|
sl@0
|
202 |
// bitmap (which we do want) and the bottom half contains the XOR bitmap (which we
|
sl@0
|
203 |
// dont want). Colour cursors have a single normal-height AND mask.
|
sl@0
|
204 |
BOOL isMonochrome = (ii.hbmColor==NULL);
|
sl@0
|
205 |
int cyy = isMonochrome ? (cy>>1) : cy;
|
sl@0
|
206 |
|
sl@0
|
207 |
// Draw the number into the mask
|
sl@0
|
208 |
char ach[4];
|
sl@0
|
209 |
int ld = iNumber/10;
|
sl@0
|
210 |
int rd = iNumber % 10;
|
sl@0
|
211 |
if (ld > 0)
|
sl@0
|
212 |
{
|
sl@0
|
213 |
wsprintf((LPTSTR)ach, (LPCTSTR)TEXT("%d%d"), ld,rd);
|
sl@0
|
214 |
}
|
sl@0
|
215 |
else
|
sl@0
|
216 |
{
|
sl@0
|
217 |
wsprintf((LPTSTR)ach, (LPCTSTR)TEXT("%d"), rd);
|
sl@0
|
218 |
}
|
sl@0
|
219 |
|
sl@0
|
220 |
HFONT hf = CreateFontA(12,0, 0,0,FW_THIN, FALSE,FALSE,FALSE, 0,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, "Arial");
|
sl@0
|
221 |
SelectObject(hdc, hf);
|
sl@0
|
222 |
SetBkMode(hdc, TRANSPARENT);
|
sl@0
|
223 |
TextOutA(hdc, 0,cyy-12, ach, 2);
|
sl@0
|
224 |
DeleteObject(hf);
|
sl@0
|
225 |
|
sl@0
|
226 |
// Get the bits of the mask (in 32-bit colour)
|
sl@0
|
227 |
HANDLE heap = GetProcessHeap();
|
sl@0
|
228 |
bmi.bmiHeader.biBitCount = 32;
|
sl@0
|
229 |
DWORD* bits = (DWORD*)HeapAlloc(heap, 0, cx*cy*4);
|
sl@0
|
230 |
GetDIBits(hdc, ii.hbmMask, 0, cy, bits, &bmi, DIB_RGB_COLORS);
|
sl@0
|
231 |
|
sl@0
|
232 |
// Set the window to the size of the cursor
|
sl@0
|
233 |
SetWindowPos(iHwnd, NULL,0,0,cx,cyy, SWP_NOMOVE);
|
sl@0
|
234 |
|
sl@0
|
235 |
// Create a cursor-shaped region by starting out with an empty region
|
sl@0
|
236 |
// and ORing in each zero-valued mask pixel.
|
sl@0
|
237 |
HRGN rgn = CreateRectRgn(0,0,0,0);
|
sl@0
|
238 |
for (int y=0 ; y<cyy ; y++)
|
sl@0
|
239 |
{
|
sl@0
|
240 |
for (int x=0 ; x<cx ; x++)
|
sl@0
|
241 |
{
|
sl@0
|
242 |
if (bits[(cy-y-1)*cx+x]==0)
|
sl@0
|
243 |
{
|
sl@0
|
244 |
HRGN rgnPix = CreateRectRgn(x,y, x+1,y+1);
|
sl@0
|
245 |
CombineRgn(rgn, rgn, rgnPix, RGN_OR);
|
sl@0
|
246 |
DeleteObject(rgnPix);
|
sl@0
|
247 |
}
|
sl@0
|
248 |
}
|
sl@0
|
249 |
}
|
sl@0
|
250 |
|
sl@0
|
251 |
// Cleanup
|
sl@0
|
252 |
HeapFree(heap, 0, bits);
|
sl@0
|
253 |
DeleteDC(hdc);
|
sl@0
|
254 |
|
sl@0
|
255 |
// Set the window's clipping region to the cursor-shaped region
|
sl@0
|
256 |
SetWindowRgn(iHwnd, rgn, TRUE);
|
sl@0
|
257 |
return TRUE;
|
sl@0
|
258 |
}
|
sl@0
|
259 |
|
sl@0
|
260 |
void CursorWindow::GetPosition(POINT& pt)
|
sl@0
|
261 |
{
|
sl@0
|
262 |
pt.x = 0;
|
sl@0
|
263 |
pt.y = 0;
|
sl@0
|
264 |
MapWindowPoints(iHwnd, GetParent(iHwnd), &pt, 1);
|
sl@0
|
265 |
pt.x += iHotspot.x;
|
sl@0
|
266 |
pt.y += iHotspot.y;
|
sl@0
|
267 |
}
|
sl@0
|
268 |
|
sl@0
|
269 |
void CursorWindow::SetPosition(POINT& pt)
|
sl@0
|
270 |
{
|
sl@0
|
271 |
SetWindowPos(iHwnd, NULL, pt.x - iHotspot.x, pt.y - iHotspot.y, 0, 0, SWP_NOSIZE);
|
sl@0
|
272 |
}
|
sl@0
|
273 |
|
sl@0
|
274 |
/**
|
sl@0
|
275 |
* Add the mouse device to the collection
|
sl@0
|
276 |
*/
|
sl@0
|
277 |
TInt DMultiMouse::Add(RAWINPUTDEVICELIST& aDev)
|
sl@0
|
278 |
{
|
sl@0
|
279 |
if (iNumMice < KMaxMice)
|
sl@0
|
280 |
{
|
sl@0
|
281 |
DMultiMouse& mouse = iMice[iNumMice];
|
sl@0
|
282 |
mouse.iDevice = aDev.hDevice;
|
sl@0
|
283 |
iNumMice++;
|
sl@0
|
284 |
return KErrNone;
|
sl@0
|
285 |
}
|
sl@0
|
286 |
else
|
sl@0
|
287 |
{
|
sl@0
|
288 |
return KErrOverflow;
|
sl@0
|
289 |
}
|
sl@0
|
290 |
}
|
sl@0
|
291 |
|
sl@0
|
292 |
DMultiMouse::DMultiMouse() :
|
sl@0
|
293 |
iX(-1), iY(-1), iZ(0), iDevice(0),iId(-1)
|
sl@0
|
294 |
{
|
sl@0
|
295 |
}
|
sl@0
|
296 |
|
sl@0
|
297 |
DMultiMouse* DMultiMouse::Find(HANDLE aHandle)
|
sl@0
|
298 |
{
|
sl@0
|
299 |
for (TInt ii=0; ii<iNumMice; ii++)
|
sl@0
|
300 |
{
|
sl@0
|
301 |
DMultiMouse& mouse = iMice[ii];
|
sl@0
|
302 |
if (mouse.iDevice == aHandle)
|
sl@0
|
303 |
return &mouse;
|
sl@0
|
304 |
}
|
sl@0
|
305 |
return NULL;
|
sl@0
|
306 |
}
|
sl@0
|
307 |
|
sl@0
|
308 |
void DMultiMouse::HandleRawMouseEvent(RAWMOUSE& aEvent, HWND aWnd)
|
sl@0
|
309 |
{
|
sl@0
|
310 |
// give this pointer an id, if it doesn't already have one
|
sl@0
|
311 |
if (iId == -1)
|
sl@0
|
312 |
{
|
sl@0
|
313 |
iId = iMouseId++;
|
sl@0
|
314 |
}
|
sl@0
|
315 |
|
sl@0
|
316 |
// Create the cursor window and set the cursor if not done yet
|
sl@0
|
317 |
if (iCursorWnd.iHwnd == NULL)
|
sl@0
|
318 |
{
|
sl@0
|
319 |
iCursorWnd.Create((HINSTANCE)0, aWnd,iId);
|
sl@0
|
320 |
iCursorWnd.SetCursor(LoadCursorA(NULL, (LPCSTR)IDC_ARROW));
|
sl@0
|
321 |
}
|
sl@0
|
322 |
|
sl@0
|
323 |
CorrectSystemMouse();
|
sl@0
|
324 |
|
sl@0
|
325 |
// recalc mouse position
|
sl@0
|
326 |
if (iX == -1)
|
sl@0
|
327 |
{
|
sl@0
|
328 |
// initial position
|
sl@0
|
329 |
iX = iPrimary->iX;
|
sl@0
|
330 |
iY = iPrimary->iY;
|
sl@0
|
331 |
}
|
sl@0
|
332 |
|
sl@0
|
333 |
if (aEvent.usFlags & MOUSE_MOVE_ABSOLUTE)
|
sl@0
|
334 |
{
|
sl@0
|
335 |
// absolute position info can update all pointers
|
sl@0
|
336 |
iX = aEvent.lLastX;
|
sl@0
|
337 |
iY = aEvent.lLastY;
|
sl@0
|
338 |
}
|
sl@0
|
339 |
else if (!iIsPrimary)
|
sl@0
|
340 |
{
|
sl@0
|
341 |
// relative position info updates non-primary pointers,
|
sl@0
|
342 |
iX += aEvent.lLastX;
|
sl@0
|
343 |
iY += aEvent.lLastY;
|
sl@0
|
344 |
}
|
sl@0
|
345 |
|
sl@0
|
346 |
// Show the cursor window
|
sl@0
|
347 |
ShowMousePos(aWnd);
|
sl@0
|
348 |
|
sl@0
|
349 |
TInt message = WM_MOUSEMOVE;
|
sl@0
|
350 |
|
sl@0
|
351 |
// get button state
|
sl@0
|
352 |
if (aEvent.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
|
sl@0
|
353 |
{
|
sl@0
|
354 |
message = WM_LBUTTONDOWN;
|
sl@0
|
355 |
iZ = 0;
|
sl@0
|
356 |
}
|
sl@0
|
357 |
|
sl@0
|
358 |
if (aEvent.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
|
sl@0
|
359 |
{
|
sl@0
|
360 |
message = WM_LBUTTONUP;
|
sl@0
|
361 |
iZ = 0;
|
sl@0
|
362 |
}
|
sl@0
|
363 |
|
sl@0
|
364 |
if (aEvent.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
|
sl@0
|
365 |
{
|
sl@0
|
366 |
message = WM_RBUTTONDOWN;
|
sl@0
|
367 |
}
|
sl@0
|
368 |
|
sl@0
|
369 |
if (aEvent.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
|
sl@0
|
370 |
{
|
sl@0
|
371 |
message = WM_RBUTTONUP;
|
sl@0
|
372 |
}
|
sl@0
|
373 |
|
sl@0
|
374 |
if (aEvent.usButtonFlags & RI_MOUSE_WHEEL)
|
sl@0
|
375 |
{
|
sl@0
|
376 |
message = WM_MOUSEWHEEL;
|
sl@0
|
377 |
if ((TInt16)(aEvent.usButtonData&0x8000)== 0) // positive number
|
sl@0
|
378 |
{
|
sl@0
|
379 |
if (iZ < TheMultiTouch->iMaxPressure)
|
sl@0
|
380 |
{
|
sl@0
|
381 |
if (iZ>=0)
|
sl@0
|
382 |
{ // pressure range
|
sl@0
|
383 |
iZ += TheMultiTouch->iPressureStep;//Pressure step
|
sl@0
|
384 |
if (iZ > TheMultiTouch->iMaxPressure)
|
sl@0
|
385 |
{
|
sl@0
|
386 |
iZ = TheMultiTouch->iMaxPressure;
|
sl@0
|
387 |
}
|
sl@0
|
388 |
}
|
sl@0
|
389 |
else
|
sl@0
|
390 |
{ // proximity range
|
sl@0
|
391 |
iZ += TheMultiTouch->iProximityStep; //Proximity step
|
sl@0
|
392 |
}
|
sl@0
|
393 |
}
|
sl@0
|
394 |
}
|
sl@0
|
395 |
else
|
sl@0
|
396 |
{
|
sl@0
|
397 |
if (iZ > TheMultiTouch->iZMaxRange)
|
sl@0
|
398 |
{
|
sl@0
|
399 |
if (iZ <= 0)
|
sl@0
|
400 |
{// proximity range
|
sl@0
|
401 |
iZ -= TheMultiTouch->iProximityStep;//Proximity step
|
sl@0
|
402 |
if (iZ < TheMultiTouch->iZMaxRange)
|
sl@0
|
403 |
{
|
sl@0
|
404 |
iZ = TheMultiTouch->iZMaxRange;
|
sl@0
|
405 |
}
|
sl@0
|
406 |
}
|
sl@0
|
407 |
else
|
sl@0
|
408 |
{// pressure range
|
sl@0
|
409 |
iZ -= TheMultiTouch->iPressureStep;//Pressure step
|
sl@0
|
410 |
}
|
sl@0
|
411 |
}
|
sl@0
|
412 |
}
|
sl@0
|
413 |
}
|
sl@0
|
414 |
|
sl@0
|
415 |
MultiTouchWndPointer(message, iX, iY, iZ, iId);
|
sl@0
|
416 |
|
sl@0
|
417 |
}
|
sl@0
|
418 |
|
sl@0
|
419 |
/**
|
sl@0
|
420 |
* Show the cursor window when the cursor is inside the client area
|
sl@0
|
421 |
*/
|
sl@0
|
422 |
void DMultiMouse::ShowMousePos(HWND aHWnd)
|
sl@0
|
423 |
{
|
sl@0
|
424 |
RECT client = {0,0,0,0};
|
sl@0
|
425 |
if(aHWnd)
|
sl@0
|
426 |
{
|
sl@0
|
427 |
GetWindowRect(aHWnd, &client);
|
sl@0
|
428 |
POINT pt = {iX-client.left,iY-client.top};
|
sl@0
|
429 |
iCursorWnd.SetPosition(pt);
|
sl@0
|
430 |
}
|
sl@0
|
431 |
iCursorWnd.Show();
|
sl@0
|
432 |
}
|
sl@0
|
433 |
|
sl@0
|
434 |
void DMultiMouse::CorrectSystemMouse()
|
sl@0
|
435 |
{
|
sl@0
|
436 |
if (iIsPrimary)
|
sl@0
|
437 |
{
|
sl@0
|
438 |
POINT pos;
|
sl@0
|
439 |
if (GetCursorPos(&pos)) // if failed, pos contains garbage.
|
sl@0
|
440 |
{
|
sl@0
|
441 |
iX = pos.x;
|
sl@0
|
442 |
iY = pos.y;
|
sl@0
|
443 |
}
|
sl@0
|
444 |
}
|
sl@0
|
445 |
else
|
sl@0
|
446 |
{
|
sl@0
|
447 |
SetCursorPos(iPrimary->iX,iPrimary->iY);
|
sl@0
|
448 |
}
|
sl@0
|
449 |
}
|
sl@0
|
450 |
|
sl@0
|
451 |
/**
|
sl@0
|
452 |
* a static function to check how many mice are connected
|
sl@0
|
453 |
*/
|
sl@0
|
454 |
bool DMultiTouch::Init()
|
sl@0
|
455 |
{
|
sl@0
|
456 |
HMODULE hModule = GetModuleHandleA("user32.dll");
|
sl@0
|
457 |
if(hModule == NULL)
|
sl@0
|
458 |
return FALSE;
|
sl@0
|
459 |
|
sl@0
|
460 |
OSVERSIONINFO osvi;
|
sl@0
|
461 |
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
sl@0
|
462 |
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
sl@0
|
463 |
|
sl@0
|
464 |
GetVersionEx(&osvi);
|
sl@0
|
465 |
// Check for Win 2K or higher version
|
sl@0
|
466 |
if (osvi.dwMajorVersion < 5)
|
sl@0
|
467 |
{
|
sl@0
|
468 |
return FALSE;
|
sl@0
|
469 |
}
|
sl@0
|
470 |
|
sl@0
|
471 |
// Not supported on Win2K
|
sl@0
|
472 |
if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0))
|
sl@0
|
473 |
{
|
sl@0
|
474 |
return FALSE;
|
sl@0
|
475 |
}
|
sl@0
|
476 |
|
sl@0
|
477 |
pfnRegisterRawInputDevices = (TYPEOF_RegisterRawInputDevices)GetProcAddress(hModule, "RegisterRawInputDevices");
|
sl@0
|
478 |
pfnGetRawInputData = (TYPEOF_GetRawInputData)GetProcAddress(hModule, "GetRawInputData");
|
sl@0
|
479 |
pfnGetRawInputDeviceList = (TYPEOF_GetRawInputDeviceList)GetProcAddress(hModule, "GetRawInputDeviceList");
|
sl@0
|
480 |
|
sl@0
|
481 |
if((pfnRegisterRawInputDevices == NULL) || (pfnGetRawInputData == NULL) || (pfnGetRawInputDeviceList == NULL))
|
sl@0
|
482 |
{
|
sl@0
|
483 |
return FALSE;
|
sl@0
|
484 |
}
|
sl@0
|
485 |
|
sl@0
|
486 |
UINT nDevices;
|
sl@0
|
487 |
|
sl@0
|
488 |
if (pfnGetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
|
sl@0
|
489 |
{
|
sl@0
|
490 |
return FALSE;
|
sl@0
|
491 |
}
|
sl@0
|
492 |
|
sl@0
|
493 |
RAWINPUTDEVICELIST* pRawInputDeviceList = new RAWINPUTDEVICELIST[ nDevices ];
|
sl@0
|
494 |
if (!pRawInputDeviceList)
|
sl@0
|
495 |
{
|
sl@0
|
496 |
return FALSE;
|
sl@0
|
497 |
}
|
sl@0
|
498 |
|
sl@0
|
499 |
pfnGetRawInputDeviceList(pRawInputDeviceList, &nDevices,
|
sl@0
|
500 |
sizeof(RAWINPUTDEVICELIST));
|
sl@0
|
501 |
|
sl@0
|
502 |
|
sl@0
|
503 |
for (UINT i=0; i<nDevices; i++)
|
sl@0
|
504 |
{
|
sl@0
|
505 |
RAWINPUTDEVICELIST& dev = pRawInputDeviceList[i];
|
sl@0
|
506 |
if (dev.dwType == RIM_TYPEMOUSE)
|
sl@0
|
507 |
{
|
sl@0
|
508 |
if (DMultiMouse::Add(dev)!=KErrNone)
|
sl@0
|
509 |
{
|
sl@0
|
510 |
//free the device list
|
sl@0
|
511 |
delete[] pRawInputDeviceList;
|
sl@0
|
512 |
return FALSE;
|
sl@0
|
513 |
}
|
sl@0
|
514 |
}
|
sl@0
|
515 |
}
|
sl@0
|
516 |
|
sl@0
|
517 |
delete[] pRawInputDeviceList;
|
sl@0
|
518 |
|
sl@0
|
519 |
// Multitouch is supported when more than 2 mice are connected (including the hidden RID mouse)
|
sl@0
|
520 |
return DMultiMouse::iNumMice > 2;
|
sl@0
|
521 |
}
|
sl@0
|
522 |
|