|
1 /* |
|
2 * Copyright (c) 2004 - 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 |
|
22 #include <eikenv.h> |
|
23 #include <eikappui.h> |
|
24 #include <eikapp.h> |
|
25 #include <apparc.h> |
|
26 #include <coemain.h> |
|
27 #include <coecntrl.h> |
|
28 #include <w32std.h> |
|
29 #include <BTMouseBitMaps.mbg> |
|
30 #include "clientimagecommander.h" |
|
31 |
|
32 #ifndef DBG |
|
33 #ifdef _DEBUG |
|
34 #define DBG(a) a |
|
35 #else |
|
36 #define DBG(a) |
|
37 #endif |
|
38 #endif |
|
39 |
|
40 _LIT( KBTMOUSEMBMFileName, "\\resource\\apps\\BTMouseBitMaps.mbm" ); |
|
41 |
|
42 |
|
43 // ============================ MEMBER FUNCTIONS =============================== |
|
44 |
|
45 // ----------------------------------------------------------------------------- |
|
46 // RImageCommander::RImageCommander() |
|
47 // Create a new animation object. |
|
48 // ----------------------------------------------------------------------------- |
|
49 // |
|
50 EXPORT_C RImageCommander::RImageCommander( RAnimDll &aAnimDll, RWsSession& aWsSession ) : |
|
51 RAnim( aAnimDll ), iSession(aWsSession), |
|
52 iBaseBitmap(NULL), |
|
53 iBaseMaskBitmap(NULL), |
|
54 iMouseButtonPressed(EFalse), |
|
55 iWakeUpCalculator(0) |
|
56 { |
|
57 DBG(RDebug::Print(_L("RImageCommander::RImageCommander"))); |
|
58 |
|
59 // No implementation required |
|
60 } |
|
61 |
|
62 EXPORT_C RImageCommander::~RImageCommander( ) |
|
63 { |
|
64 iSprite.Close(); |
|
65 |
|
66 if ( iPointBufferQueue ) |
|
67 { |
|
68 delete iPointBufferQueue; |
|
69 iPointBufferQueue = NULL; |
|
70 } |
|
71 |
|
72 if ( iBaseBitmap) |
|
73 { |
|
74 delete iBaseBitmap; |
|
75 iBaseBitmap = NULL; |
|
76 } |
|
77 |
|
78 if ( iBaseMaskBitmap ) |
|
79 { |
|
80 delete iBaseMaskBitmap; |
|
81 iBaseMaskBitmap = NULL; |
|
82 } |
|
83 RAnim::Close(); |
|
84 } |
|
85 |
|
86 // ----------------------------------------------------------------------------- |
|
87 // RImageCommander::ImageConstruct() |
|
88 // Construct a new animation object. |
|
89 // ----------------------------------------------------------------------------- |
|
90 // |
|
91 EXPORT_C void RImageCommander::ImageConstructL( RWindowGroup& aWindowGroup, TSize aSize ) |
|
92 { |
|
93 // Send the parameters to the animation server object construction |
|
94 |
|
95 DBG(RDebug::Print(_L("RImageCommander::ImageConstructL IN"))); |
|
96 |
|
97 iPointBufferQueue = NULL; |
|
98 iPointBufferQueue = CPointQueue::NewL(this,KMsgBTMouseBufferQueue); |
|
99 |
|
100 CreateSpriteL(aSize, aWindowGroup); |
|
101 |
|
102 DBG(RDebug::Print(_L("RImageCommander::ImageConstructL Construct Anim"))); |
|
103 |
|
104 TPtrC8 des(NULL,0); |
|
105 RAnim::Construct( iSprite, 0, des ); |
|
106 |
|
107 DBG(RDebug::Print(_L("RImageCommander::ImageConstructL OUT"))); |
|
108 } |
|
109 |
|
110 // ---------------------------------------------------------------------------- |
|
111 // RImageCommander::CreateSpriteL(TSize aSize, RWindowGroup& aGroup) |
|
112 // ---------------------------------------------------------------------------- |
|
113 // |
|
114 void RImageCommander::CreateSpriteL(TSize aSize, RWindowGroup& aGroup) |
|
115 { |
|
116 DBG(RDebug::Print(_L("RImageCommander::CreateSpriteL START"))); |
|
117 TSpriteMember member; |
|
118 |
|
119 |
|
120 DBG(RDebug::Print(_L("RImageCommander::CreateSpriteL size %d,%d"), aSize.iWidth, aSize.iHeight)); |
|
121 (void)aSize; |
|
122 |
|
123 iSprite=RWsSprite(iSession); |
|
124 TInt error = iSprite.Construct(aGroup, TPoint(),ESpriteNoChildClip|ESpriteNoShadows); |
|
125 User::LeaveIfError(error); |
|
126 iBaseBitmap = new (ELeave) CFbsBitmap; |
|
127 // Drive Letter: |
|
128 TFileName file(CEikonEnv::Static()->EikAppUi()->Application()->AppFullName().Left(2)); |
|
129 // Path and file name: |
|
130 file.Append( KBTMOUSEMBMFileName ); // always safe |
|
131 |
|
132 User::LeaveIfError(iBaseBitmap->Load(file, EMbmBtmousebitmapsCursor)); |
|
133 iBaseMaskBitmap = new (ELeave) CFbsBitmap; |
|
134 User::LeaveIfError(iBaseMaskBitmap->Load(file, EMbmBtmousebitmapsCursormask)); |
|
135 FillInSpriteMember(member, iBaseBitmap, iBaseMaskBitmap); |
|
136 User::LeaveIfError(iSprite.AppendMember(member)); |
|
137 |
|
138 DBG(RDebug::Print(_L("RImageCommander::CreateSpriteL END"))); |
|
139 |
|
140 } |
|
141 |
|
142 // ---------------------------------------------------------------------------- |
|
143 // RImageCommander::FillInSpriteMember(TSpriteMember& aMember, CFbsBitmap* icon, CFbsBitmap* iconMask) |
|
144 // ---------------------------------------------------------------------------- |
|
145 // |
|
146 void RImageCommander::FillInSpriteMember(TSpriteMember& aMember, CFbsBitmap* icon, CFbsBitmap* iconMask) |
|
147 { |
|
148 DBG(RDebug::Print(_L("RImageCommander::FillInSpriteMember")); |
|
149 |
|
150 if ( ( icon == NULL) || ( iconMask == NULL) ) |
|
151 { |
|
152 RDebug::Print(_L("RImageCommander::FillInSpriteMember no icons !")); |
|
153 } |
|
154 ) |
|
155 aMember.iBitmap=icon; |
|
156 aMember.iMaskBitmap=iconMask; |
|
157 aMember.iInvertMask=EFalse; |
|
158 aMember.iDrawMode = CGraphicsContext::EDrawModeWriteAlpha; |
|
159 aMember.iOffset=TPoint(0,0); |
|
160 |
|
161 DBG(RDebug::Print(_L("RImageCommander::FillInSpriteMember END"))); |
|
162 |
|
163 } |
|
164 |
|
165 // ----------------------------------------------------------------------------- |
|
166 // RImageCommander::ImageCommand() |
|
167 // Send a command (aCommand) to the animation server object. |
|
168 // Because there is no way to return an error from the server side using this |
|
169 // method, it is important that any server side code for these commands should |
|
170 // not be able to fail or leave. If the operation can fail, then the method |
|
171 // TInt CommandReply(TInt aOpcode) should be used instead |
|
172 // ----------------------------------------------------------------------------- |
|
173 // |
|
174 EXPORT_C void RImageCommander::ImageCommand( TInt aCommand ) |
|
175 { |
|
176 // Could optionally decode the commands here |
|
177 DBG(RDebug::Print(_L("RImageCommander::ImageCommand %d"), aCommand)); |
|
178 |
|
179 RAnim::Command( aCommand ); |
|
180 |
|
181 DBG(RDebug::Print(_L("RImageCommander::ImageCommand OUT"))); |
|
182 |
|
183 } |
|
184 |
|
185 TRawEvent::TType RImageCommander::PointerEventToRawEvent(TPointerEvent::TType aEventType) |
|
186 { |
|
187 TRawEvent::TType aType; |
|
188 switch(aEventType) |
|
189 { |
|
190 case TPointerEvent::EButton1Down: |
|
191 { |
|
192 aType=TRawEvent::EButton1Down; |
|
193 break; |
|
194 } |
|
195 case TPointerEvent::EButton1Up: |
|
196 { |
|
197 aType=TRawEvent::EButton1Up; |
|
198 break; |
|
199 } |
|
200 case TPointerEvent::EMove: |
|
201 { |
|
202 aType=TRawEvent::EPointerMove; |
|
203 break; |
|
204 } |
|
205 case TPointerEvent::ESwitchOn: |
|
206 { |
|
207 aType=TRawEvent::EPointerSwitchOn; |
|
208 break; |
|
209 } |
|
210 default: |
|
211 { |
|
212 aType=TRawEvent::ENone; |
|
213 break; |
|
214 } |
|
215 } |
|
216 return aType; |
|
217 } |
|
218 |
|
219 TInt RImageCommander::SendPointerEvent(TPointerEvent::TType aEventType) |
|
220 { |
|
221 DBG(RDebug::Print(_L("RImageCommander::SendPointerEvent"))); |
|
222 |
|
223 TRawEvent rawEvent; |
|
224 TPoint point(iCurrentPoint); |
|
225 TRawEvent::TType type = PointerEventToRawEvent(aEventType); |
|
226 rawEvent.Set(type, point.iX, point.iY, 30); |
|
227 typedef TPckgBuf< TRawEvent > TRawEventDataPckg; |
|
228 TRawEventDataPckg rawEventPckg(rawEvent); |
|
229 RAnim::Command( KSendRawEvent, rawEventPckg ); |
|
230 return KErrNone; |
|
231 } |
|
232 |
|
233 |
|
234 TBool RImageCommander::RestrictPos() |
|
235 { |
|
236 TBool notInScreen(EFalse); |
|
237 TPixelsAndRotation sizeAndRotation; |
|
238 sizeAndRotation.iPixelSize.SetSize(360,640); // Just a guess |
|
239 CWsScreenDevice* screen(CEikonEnv::Static()->ScreenDevice()); |
|
240 if (screen) |
|
241 { |
|
242 TInt mode(screen->CurrentScreenMode()); |
|
243 screen->GetScreenModeSizeAndRotation(mode, sizeAndRotation); |
|
244 } |
|
245 TRect validRect(sizeAndRotation.iPixelSize); |
|
246 if (! validRect.Contains(iCurrentPoint)) |
|
247 { |
|
248 notInScreen = ETrue; |
|
249 if (iCurrentPoint.iX<0) |
|
250 iCurrentPoint.iX=0; |
|
251 else if (iCurrentPoint.iX>=validRect.iBr.iX) |
|
252 iCurrentPoint.iX=validRect.iBr.iX-1; |
|
253 |
|
254 if (iCurrentPoint.iY<0) |
|
255 iCurrentPoint.iY=0; |
|
256 else if (iCurrentPoint.iY>=validRect.iBr.iY) |
|
257 iCurrentPoint.iY=validRect.iBr.iY-1; |
|
258 } |
|
259 return notInScreen; |
|
260 } |
|
261 |
|
262 inline TBool RImageCommander::CheckCurrentPoint() |
|
263 { |
|
264 DBG(TPoint pos(iCurrentPoint)); |
|
265 |
|
266 TBool outSide(RestrictPos()); |
|
267 |
|
268 DBG( |
|
269 if (outSide) |
|
270 { |
|
271 RDebug::Print(_L("RImageCommander::CheckCurrentPoint not in screen (%d,%d)"), pos.iX, pos.iY); |
|
272 } |
|
273 ) |
|
274 return outSide; |
|
275 } |
|
276 |
|
277 TInt RImageCommander::SendWakeUp() |
|
278 { |
|
279 TRawEvent rawEvent; |
|
280 rawEvent.Set(TRawEvent::ESwitchOn); |
|
281 return UserSvr::AddEvent(rawEvent); |
|
282 } |
|
283 |
|
284 void RImageCommander::HandlePointL(const TPoint& aPoint) |
|
285 { |
|
286 DBG(RDebug::Print(_L("RImageCommander::HandlePointL pos (%d,%d)"), |
|
287 aPoint.iX, aPoint.iY)); |
|
288 |
|
289 if ( ( aPoint.iX != 0) || ( aPoint.iY != 0) ) |
|
290 { |
|
291 iCurrentPoint += aPoint; |
|
292 TBool notInScreen(CheckCurrentPoint()); |
|
293 if (iMouseButtonPressed) |
|
294 { |
|
295 // Dragging possible now: |
|
296 if (notInScreen) |
|
297 { |
|
298 SendPointerEvent(TPointerEvent::EButton1Up); |
|
299 iMouseButtonPressed = EFalse; |
|
300 } |
|
301 else |
|
302 { |
|
303 SendPointerEvent(TPointerEvent::EMove); |
|
304 } |
|
305 } |
|
306 else |
|
307 { |
|
308 typedef TPckgBuf< TPoint > TPointDataPckg; |
|
309 TPointDataPckg pointPckg(iCurrentPoint); |
|
310 RAnim::Command( KChangeCursor, pointPckg ); |
|
311 } |
|
312 } |
|
313 iWakeUpCalculator++; |
|
314 if (iWakeUpCalculator > KWakeUpNeeded) |
|
315 { |
|
316 SendWakeUp(); |
|
317 iWakeUpCalculator = 0; |
|
318 } |
|
319 } |
|
320 |
|
321 void RImageCommander::SendEventL(TPointerEvent::TType aEventType) |
|
322 { |
|
323 DBG(RDebug::Print(_L("RImageCommander::SendEventL (%d)"), aEventType)); |
|
324 |
|
325 if (aEventType == TPointerEvent::EButton1Down) |
|
326 { |
|
327 iMouseButtonPressed = ETrue; |
|
328 SendWakeUp(); |
|
329 } |
|
330 else if (aEventType == TPointerEvent::EButton1Up) |
|
331 { |
|
332 iMouseButtonPressed = EFalse; |
|
333 } |
|
334 SendPointerEvent(aEventType); |
|
335 } |
|
336 |
|
337 // ======== class CPointQueue======== |
|
338 // |
|
339 // --------------------------------------------------------------------------- |
|
340 // CPointQueue::CPointQueue |
|
341 // Constructor. Adds the active object to the active scheduler |
|
342 // and issues a request for server notification. |
|
343 // --------------------------------------------------------------------------- |
|
344 // |
|
345 |
|
346 CPointQueue::CPointQueue(MPointHandler* aHandler):CActive( EPriorityHigh ), |
|
347 iHandler(aHandler) |
|
348 { |
|
349 // issue asynchronous request and set this object active |
|
350 DBG(RDebug::Print(_L("(CCPointQueue::CPointQueue"))); |
|
351 |
|
352 CActiveScheduler::Add( this ); |
|
353 |
|
354 DBG( RDebug::Print(_L("(CCPointQueue::CPointQueue Out"))); |
|
355 |
|
356 } |
|
357 |
|
358 // --------------------------------------------------------------------------- |
|
359 // CPointQueue::NewL |
|
360 // factory constructor. |
|
361 // --------------------------------------------------------------------------- |
|
362 // |
|
363 CPointQueue* CPointQueue::NewL(MPointHandler* aHandler,const TDesC& aName) |
|
364 { |
|
365 DBG(RDebug::Print(_L("(CCPointQueue::NewL"))); |
|
366 |
|
367 CPointQueue* queue = new(ELeave)CPointQueue(aHandler); |
|
368 CleanupStack::PushL(queue); |
|
369 queue->ConstructL(aName); |
|
370 CleanupStack::Pop(queue); |
|
371 // Start receiving: |
|
372 queue->GetPoint(); |
|
373 |
|
374 DBG(RDebug::Print(_L("(CCPointQueue::NewL Out"))); |
|
375 |
|
376 return queue; |
|
377 } |
|
378 |
|
379 // --------------------------------------------------------------------------- |
|
380 // CPointQueue::ConstructL |
|
381 // 2nd phase constructor |
|
382 // --------------------------------------------------------------------------- |
|
383 // |
|
384 void CPointQueue::ConstructL(const TDesC& aName) |
|
385 { |
|
386 (void) aName; |
|
387 //Open message queue |
|
388 TInt err = iPointBufQueue.OpenGlobal(KMsgBTMouseBufferQueue); |
|
389 if (err == KErrNotFound) |
|
390 { |
|
391 User::LeaveIfError(iPointBufQueue.CreateGlobal(KMsgBTMouseBufferQueue, KPointQueueLen)); |
|
392 } |
|
393 else |
|
394 { |
|
395 User::LeaveIfError( err ); |
|
396 } |
|
397 } |
|
398 // --------------------------------------------------------------------------- |
|
399 // CPointQueue::CPointQueue |
|
400 // Destructor. Cancels any outstanding requests |
|
401 // --------------------------------------------------------------------------- |
|
402 // |
|
403 CPointQueue::~CPointQueue() |
|
404 { |
|
405 Cancel(); |
|
406 iPointBufQueue.Close(); |
|
407 } |
|
408 |
|
409 // --------------------------------------------------------------------------- |
|
410 // CPointQueue::DoCancel |
|
411 // Cancels the notification requests |
|
412 // --------------------------------------------------------------------------- |
|
413 // |
|
414 void CPointQueue::DoCancel() |
|
415 { |
|
416 iPointBufQueue.CancelDataAvailable(); |
|
417 } |
|
418 |
|
419 // --------------------------------------------------------------------------- |
|
420 // CPointQueue::RunL |
|
421 // --------------------------------------------------------------------------- |
|
422 // |
|
423 void CPointQueue::RunL() |
|
424 { |
|
425 DBG(RDebug::Print(_L("CCPointQueue::RunL"))); |
|
426 |
|
427 TInt ret; |
|
428 //iHandler is always there. No need to check it |
|
429 TPointBuffer points; |
|
430 ret = iPointBufQueue.Receive(points); |
|
431 DBG(RDebug::Print(_L("CCPointQueue::RunL , ret = %d, points %d"), ret, points.iNum)); |
|
432 |
|
433 if (ret == KErrNone) |
|
434 { |
|
435 TPoint pos(0,0); |
|
436 for(TInt ii = 0; ii < points.iNum; ii++) |
|
437 { |
|
438 pos += points.iPoint[ii]; |
|
439 if ( ( points.iType[ii] == KBufferPenDown ) || |
|
440 ( points.iType[ii] == KBufferPenUp ) ) |
|
441 { |
|
442 iHandler->SendEventL( ( points.iType[ii] == KBufferPenDown ) ? |
|
443 TPointerEvent::EButton1Down : |
|
444 TPointerEvent::EButton1Up ); |
|
445 iHandler->HandlePointL(pos); |
|
446 pos.SetXY(0,0); |
|
447 } |
|
448 } |
|
449 iHandler->HandlePointL(pos); |
|
450 } |
|
451 // re-issue request |
|
452 GetPoint(); |
|
453 } |
|
454 |
|
455 // --------------------------------------------------------------------------- |
|
456 // CPointQueue::RunError |
|
457 // --------------------------------------------------------------------------- |
|
458 // |
|
459 TInt CPointQueue::RunError(TInt /*aError*/) |
|
460 { |
|
461 DBG(RDebug::Print(_L("CCPointQueue::RunError"))); |
|
462 // re-issue request |
|
463 GetPoint(); |
|
464 return KErrNone; |
|
465 } |
|
466 |
|
467 // --------------------------------------------------------------------------- |
|
468 // CPointQueue::GetPoint |
|
469 // Reissue request for point |
|
470 // --------------------------------------------------------------------------- |
|
471 // |
|
472 void CPointQueue::GetPoint() |
|
473 { |
|
474 DBG(RDebug::Print(_L("CCPointQueue::GetPoint"))); |
|
475 |
|
476 if(!IsActive()) |
|
477 { |
|
478 iPointBufQueue.NotifyDataAvailable(iStatus); |
|
479 SetActive(); |
|
480 } |
|
481 DBG(RDebug::Print(_L("CCPointQueue::GetPoint Out"))); |
|
482 } |
|
483 // End of File |