|
1 /* |
|
2 * Copyright (c) 2003-2009 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: CMIDCanvas - Implements the native part of the Canvas class. |
|
15 * |
|
16 */ |
|
17 |
|
18 // Using auto_ptr |
|
19 #include <memory> |
|
20 |
|
21 // API used for getting the layout for the network indicator bitmap and for |
|
22 // retrieving info if pen is enabled (in CMIDCanvas::HandlePointerEventL |
|
23 // function). |
|
24 #include <AknUtils.h> |
|
25 |
|
26 // Using Layout_Meta_Data::IsLandscapeOrientation() |
|
27 #include <layoutmetadata.cdl.h> |
|
28 |
|
29 |
|
30 // Using CRepository class used in CMIDCanvas::IsNetworkIndicatorEnabledL |
|
31 // function. |
|
32 #include <centralrepository.h> |
|
33 #ifdef RD_JAVA_NGA_ENABLED |
|
34 #include <logger.h> |
|
35 #include <e32cmn.h> |
|
36 #include <EGL/egl.h> |
|
37 #include <GLES/gl.h> |
|
38 #endif // RD_JAVA_NGA_ENABLED |
|
39 |
|
40 |
|
41 // Using debug macros. |
|
42 #include <j2me/jdebug.h> |
|
43 |
|
44 // OMJ storage |
|
45 #include <securitystoragedatadefs.h> |
|
46 #include <javastorageentry.h> |
|
47 #include <javastorage.h> |
|
48 #include <javastoragenames.h> |
|
49 #include <javauid.h> |
|
50 #include <javasymbianoslayer.h> |
|
51 |
|
52 #include "javaoslayer.h" |
|
53 |
|
54 // Using constants for S60 LCDUI Plugin internal keys. |
|
55 #include "S60LCDUIInternalCRKeys.h" |
|
56 |
|
57 #include "CMIDCanvas.h" |
|
58 |
|
59 // Using CMIDUIManager for iKeyDecoder and iScaler initialization. |
|
60 #include "CMIDUIManager.h" |
|
61 |
|
62 // Using CMIDScaler as member iScaler. |
|
63 #include "CMIDScaler.h" |
|
64 |
|
65 // Using CMIDKeyDecoder as member iKeyDecoder. |
|
66 #include "CMIDKeyDecoder.h" |
|
67 |
|
68 // Using CMIDNetworkIndicator as member iNetworkIndicator. |
|
69 #include "CMIDNetworkIndicator.h" |
|
70 |
|
71 // Using CMIDCallIndicator as member iCallIndicator. |
|
72 #include "CMIDCallIndicator.h" |
|
73 |
|
74 // Using CMIDRemConObserver as memeber iRemConObserver. |
|
75 #include "CMIDRemConObserver.h" |
|
76 |
|
77 |
|
78 #ifdef RD_TACTILE_FEEDBACK |
|
79 // Using CMIDTactileFeedbackExtension as member iTactileFeedback. |
|
80 #include "CMIDTactileFeedbackExtension.h" |
|
81 #endif // RD_TACTILE_FEEDBACK |
|
82 |
|
83 #include "MMIDCustomComponent.h" |
|
84 |
|
85 // Using CoreUiAvkonLcdui for the splash screen |
|
86 #include "coreuiavkonlcdui.h" |
|
87 |
|
88 #ifdef DEFER_BITBLT |
|
89 const TInt KEstCyclesPerPixel = 32; |
|
90 #endif // DEFER_BITBLT |
|
91 |
|
92 const TInt KAllowedTimeBetweenDragEvents = 50000; // 50ms |
|
93 |
|
94 // Used with component controls |
|
95 const TInt KComponentMainControl = 0; |
|
96 const TInt KComponentFocusedNone = -1; |
|
97 |
|
98 // Using enumeration TFocusState. |
|
99 #include "MMIDTextEditor.h" |
|
100 |
|
101 #ifdef RD_JAVA_NGA_ENABLED |
|
102 // Max dimension for openGL texture, must be power of 2 |
|
103 const TInt KMaxBlitSize = 256; |
|
104 const TInt KTexturesCount = 1; |
|
105 const TInt KBytesPerPixel = 4; |
|
106 const TInt KPhoneScreen = 0; |
|
107 // The color that is used to clear the framebuffer when |
|
108 // mixing 3D & 2D rendering |
|
109 #define KTransparentClearColor TRgb(0x000000, 0x0) |
|
110 #define KOpaqueClearColor TRgb(0xFFFFFF, 0xFF) |
|
111 |
|
112 #ifdef _DEBUG |
|
113 #define ASSERT_GL() AssertGL() |
|
114 #else |
|
115 #define ASSERT_GL() |
|
116 #endif |
|
117 |
|
118 #endif // RD_JAVA_NGA_ENABLED |
|
119 |
|
120 #define KZeroSize TSize() |
|
121 |
|
122 |
|
123 // --------------------------------------------------------------------------- |
|
124 // TBitBltData |
|
125 // BitBlt buffer data datatype. |
|
126 // --------------------------------------------------------------------------- |
|
127 // |
|
128 struct TBitBltData |
|
129 { |
|
130 TRect iRect; |
|
131 }; |
|
132 |
|
133 |
|
134 // ======== LOCAL FUNCTIONS ======== |
|
135 |
|
136 // --------------------------------------------------------------------------- |
|
137 // BitBltData |
|
138 // Get BitBlt buffer data from buffered operation passed to buffer processor. |
|
139 // Used in CMIDCanvas::ProcessL function. |
|
140 // --------------------------------------------------------------------------- |
|
141 // |
|
142 inline const TBitBltData& BitBltData(const TMIDBufferOp* aOp) |
|
143 { |
|
144 ASSERT(aOp->Size() >= TInt(1 + ( |
|
145 sizeof(TBitBltData) / sizeof(TMIDBufferOp)))); |
|
146 |
|
147 return *static_cast< const TBitBltData* >(aOp->Data()); |
|
148 } |
|
149 |
|
150 |
|
151 // --------------------------------------------------------------------------- |
|
152 // IsDownScaling |
|
153 // Check if downscaling in use. |
|
154 // @param aSourceSize Source rect size. |
|
155 // @param aDestRect Destination rect. |
|
156 // --------------------------------------------------------------------------- |
|
157 // |
|
158 inline TBool IsDownScaling(const TSize& aSourceSize, const TRect& aDestRect) |
|
159 { |
|
160 return (aSourceSize.iWidth > aDestRect.Width() || |
|
161 aSourceSize.iHeight > aDestRect.Height()); |
|
162 } |
|
163 |
|
164 |
|
165 // ======== MEMBER FUNCTIONS ======== |
|
166 |
|
167 // --------------------------------------------------------------------------- |
|
168 // CMIDCanvas::NewL |
|
169 // Two-phased constructor. Use this method to create a CMIDCanvas instance. |
|
170 // --------------------------------------------------------------------------- |
|
171 // |
|
172 CMIDCanvas* CMIDCanvas::NewL( |
|
173 MMIDEnv& aEnv, |
|
174 CCoeControl& aWindow, |
|
175 MMIDComponent::TType aComponentType, |
|
176 TBool aUpdateRequired) |
|
177 { |
|
178 CMIDCanvas* self = new(ELeave) CMIDCanvas(aEnv, |
|
179 aComponentType, |
|
180 aUpdateRequired); |
|
181 |
|
182 CleanupStack::PushL(self); |
|
183 self->ConstructL(aWindow); |
|
184 CleanupStack::Pop(self); |
|
185 |
|
186 return self; |
|
187 } |
|
188 |
|
189 |
|
190 // --------------------------------------------------------------------------- |
|
191 // CMIDCanvas::~CMIDCanvas |
|
192 // Destructor. |
|
193 // --------------------------------------------------------------------------- |
|
194 // |
|
195 CMIDCanvas::~CMIDCanvas() |
|
196 { |
|
197 DEBUG("+ CMIDCanvas::~CMIDCanvas"); |
|
198 |
|
199 // Notify custom components that this container is disposing. |
|
200 TInt customCount = iCustomComponents.Count(); |
|
201 |
|
202 for (TInt i = 0; i < customCount; i++) |
|
203 { |
|
204 iCustomComponents[i]->CustomComponentContainerDisposing(); |
|
205 } |
|
206 |
|
207 // Close the array. Objects are not owned. |
|
208 iCustomComponents.Close(); |
|
209 |
|
210 // Inform all listeners |
|
211 TInt contentsCount(iDirectContents.Count()); |
|
212 |
|
213 for (TInt j = 0; j < contentsCount; j++) |
|
214 { |
|
215 iDirectContents[j]->MdcContainerDestroyed(); |
|
216 } |
|
217 |
|
218 iDirectContents.Reset(); |
|
219 |
|
220 // Unregister the component from the observer |
|
221 // if it were previously registered from MdcAddContent. |
|
222 iEnv.ToLcduiObserver().UnregisterControl(*this); |
|
223 |
|
224 #ifdef CANVAS_DIRECT_ACCESS |
|
225 StopDirectAccess(); |
|
226 delete iDirectAccess; |
|
227 #endif // CANVAS_DIRECT_ACCESS |
|
228 |
|
229 // Network indicator |
|
230 if (iNetworkIndicator) |
|
231 { |
|
232 iNetworkIndicator->Close(); // Use cancel here. |
|
233 delete iNetworkIndicator; |
|
234 } |
|
235 |
|
236 // Call indicator |
|
237 if (iCallIndicator) |
|
238 { |
|
239 iCallIndicator->Cancel(); |
|
240 delete iCallIndicator; |
|
241 } |
|
242 |
|
243 // Canvas removes itself from the CMIDRemConObserver. |
|
244 ASSERT(iKeyDecoder); |
|
245 |
|
246 if (iRemConObserver && iKeyDecoder->MediaKeysEnabled()) |
|
247 { |
|
248 iRemConObserver->RemoveMediaKeysListener(this); |
|
249 } |
|
250 |
|
251 if (iDisplayable) |
|
252 { |
|
253 if (iScaler) |
|
254 { |
|
255 iDisplayable->GetUIManager()->CloseScaler(iScaler); |
|
256 } |
|
257 |
|
258 // Displayable is notified about content control deletion. |
|
259 iDisplayable->NotifyContentDestroyed(); |
|
260 } |
|
261 |
|
262 #ifdef CANVAS_DOUBLE_BUFFER |
|
263 if (iFrameBuffer) |
|
264 { |
|
265 iEnv.ReleaseCanvasFrameBuffer((*this), iFrameBuffer); |
|
266 iFrameBuffer = NULL; |
|
267 } |
|
268 |
|
269 delete iFrameContext; |
|
270 iFrameContext = NULL; |
|
271 delete iFrameDevice; |
|
272 iFrameDevice = NULL; |
|
273 #endif // CANVAS_DOUBLE_BUFFER |
|
274 |
|
275 #ifdef RD_TACTILE_FEEDBACK |
|
276 delete iTactileFeedback; |
|
277 #endif // RD_TACTILE_FEEDBACK |
|
278 |
|
279 if (iPointerEventSuppressor) |
|
280 { |
|
281 delete iPointerEventSuppressor; |
|
282 iPointerEventSuppressor = NULL; |
|
283 } |
|
284 |
|
285 #ifdef RD_JAVA_NGA_ENABLED |
|
286 CloseEgl(); |
|
287 DisposePixelSource(); |
|
288 delete[] iTexturePixels; |
|
289 delete[] iVertexArray; |
|
290 delete[] iTriangleStrip; |
|
291 #endif // RD_JAVA_NGA_ENABLED |
|
292 DEBUG("- CMIDCanvas::~CMIDCanvas"); |
|
293 } |
|
294 |
|
295 |
|
296 // --------------------------------------------------------------------------- |
|
297 // CMIDCanvas::FullScreen |
|
298 // Set fullscreen mode on/off. |
|
299 // --------------------------------------------------------------------------- |
|
300 // |
|
301 void CMIDCanvas::FullScreen(TBool aFullScreen) |
|
302 { |
|
303 DEBUG_INT("CMIDCanvas::FullScreen(%d) ++--", aFullScreen); |
|
304 if (iFullScreen != aFullScreen) |
|
305 { |
|
306 iFullScreen = aFullScreen; |
|
307 // We have to inform all components on this Canvas. |
|
308 if (iCustomComponents.Count() > 0) |
|
309 { |
|
310 for (int i = 0; i < iCustomComponents.Count(); i++) |
|
311 { |
|
312 iCustomComponents[i]->HandleFullscreenModeChange(); |
|
313 } |
|
314 } |
|
315 } |
|
316 } |
|
317 |
|
318 |
|
319 // --------------------------------------------------------------------------- |
|
320 // CMIDCanvas::IsScalingOn |
|
321 // Tells whether scaling is on or off. |
|
322 // --------------------------------------------------------------------------- |
|
323 // |
|
324 TBool CMIDCanvas::IsScalingOn() |
|
325 { |
|
326 return iScalingOn; |
|
327 } |
|
328 |
|
329 |
|
330 // --------------------------------------------------------------------------- |
|
331 // CMIDCanvas::SelectionKeyCompatibility |
|
332 // Tells whether application attribute |
|
333 // Nokia-MIDlet-S60-Selection-Key-Compatibility is set true or not. |
|
334 // --------------------------------------------------------------------------- |
|
335 // |
|
336 TBool CMIDCanvas::SelectionKeyCompatibility() |
|
337 { |
|
338 return iS60SelectionKeyCompatibility; |
|
339 } |
|
340 |
|
341 // --------------------------------------------------------------------------- |
|
342 // CMIDCanvas::CountComponentControls |
|
343 // (other items are commented in the header file) |
|
344 // --------------------------------------------------------------------------- |
|
345 // |
|
346 TInt CMIDCanvas::CountComponentControls() const |
|
347 { |
|
348 return iCustomComponentsControlCount; |
|
349 } |
|
350 |
|
351 // --------------------------------------------------------------------------- |
|
352 // CMIDCanvas::ComponentControl |
|
353 // (other items are commented in the header file) |
|
354 // --------------------------------------------------------------------------- |
|
355 // |
|
356 CCoeControl* CMIDCanvas::ComponentControl(TInt aIndex) const |
|
357 { |
|
358 TInt index = 0; |
|
359 |
|
360 TInt count = iCustomComponents.Count(); |
|
361 |
|
362 for (int i = 0; i < count; i++) |
|
363 { |
|
364 TInt compoundCount = |
|
365 iCustomComponents[i]->CustomComponentControlCount(); |
|
366 |
|
367 for (int j = 0; j < compoundCount; j++) |
|
368 { |
|
369 if (index == aIndex) |
|
370 { |
|
371 return iCustomComponents[i]->CustomComponentControl(j); |
|
372 } |
|
373 |
|
374 index++; |
|
375 } |
|
376 } |
|
377 |
|
378 return NULL; |
|
379 } |
|
380 |
|
381 // --------------------------------------------------------------------------- |
|
382 // CMIDCanvas::SetFocusedComponent |
|
383 // (other items are commented in the header file) |
|
384 // --------------------------------------------------------------------------- |
|
385 // |
|
386 void CMIDCanvas::SetFocusedComponent(MMIDCustomComponent* aComponent) |
|
387 { |
|
388 if (aComponent == NULL) |
|
389 { |
|
390 iFocusedComponent = KComponentFocusedNone; |
|
391 iPressedComponent = NULL; |
|
392 } |
|
393 else |
|
394 { |
|
395 TInt count = iCustomComponents.Count(); |
|
396 TInt index = iCustomComponents.Find(aComponent); |
|
397 if ((index != KErrNotFound) && (iFocusedComponent != index)) |
|
398 { |
|
399 iFocusedComponent = index; |
|
400 } |
|
401 } |
|
402 } |
|
403 |
|
404 // --------------------------------------------------------------------------- |
|
405 // From class CCoeControl. |
|
406 // CMIDCanvas::OfferKeyEventL |
|
407 // Process a key event. We ask the java environment to translate the key event |
|
408 // and we send it java side only if the translation allows it. The translation |
|
409 // is controlled by CMIDKeyDecoder via its interface to the java environment. |
|
410 // CBA keys are special. We only try and send them java side if we are full |
|
411 // screen and have no commands nor CommandListener, as stated in the specs. |
|
412 // Otherwise - if we are full screen with at least one command and |
|
413 // CommandListener we display the options menu or if we are not full screen |
|
414 // we simply return so that the CBA will process the key event and display the |
|
415 // options menu if needed. Note that in this context MSK is considered to be a |
|
416 // softkey, it must not be delivered as a key event to the Java side. |
|
417 // --------------------------------------------------------------------------- |
|
418 // |
|
419 TKeyResponse CMIDCanvas::OfferKeyEventL( |
|
420 const TKeyEvent& aEvent, |
|
421 TEventCode aType) |
|
422 { |
|
423 DEBUG("+ CMIDCanvas::OfferKeyEventL"); |
|
424 |
|
425 DEBUG_INT( |
|
426 "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iCode = %d", |
|
427 aEvent.iCode); |
|
428 |
|
429 DEBUG_INT( |
|
430 "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iModifiers = %d", |
|
431 aEvent.iModifiers); |
|
432 |
|
433 DEBUG_INT( |
|
434 "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iRepeats = %d", |
|
435 aEvent.iRepeats); |
|
436 |
|
437 DEBUG_INT( |
|
438 "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iScanCode = %d", |
|
439 aEvent.iScanCode); |
|
440 |
|
441 TKeyResponse response = EKeyWasNotConsumed; |
|
442 |
|
443 if ((iFocusedComponent != KComponentFocusedNone) && |
|
444 (iFocusedComponent < iCustomComponents.Count()) && |
|
445 (iCustomComponents[iFocusedComponent]-> |
|
446 CustomComponentControl(KComponentMainControl)->IsVisible())) |
|
447 { |
|
448 // Traversal check |
|
449 if ((aType == EEventKeyDown) && |
|
450 (((aEvent.iCode == EKeyUpArrow) || |
|
451 (aEvent.iCode == EKeyDownArrow)) || |
|
452 ((aEvent.iScanCode == EStdKeyUpArrow) || |
|
453 (aEvent.iScanCode == EStdKeyDownArrow)))) |
|
454 { |
|
455 // Traversing is not allowed when editing with VKB |
|
456 if (iDisplayable && !iDisplayable->IsVKBOnScreen()) |
|
457 { |
|
458 iCustomComponents[iFocusedComponent]->TraverseL(aEvent); |
|
459 response = EKeyWasConsumed; |
|
460 } |
|
461 } |
|
462 |
|
463 if (response != EKeyWasConsumed) |
|
464 { |
|
465 // Passing the keyevent to focused component |
|
466 response = iCustomComponents[iFocusedComponent]-> |
|
467 CustomComponentControl(KComponentMainControl)-> |
|
468 OfferKeyEventL(aEvent, aType); |
|
469 } |
|
470 } |
|
471 |
|
472 // Check if the key event was consumed by the child control. |
|
473 if (response == EKeyWasConsumed) |
|
474 { |
|
475 DEBUG_INT( |
|
476 "CMIDCanvas::OfferKeyEventL - key consumed by custom control: %d", |
|
477 iFocusedComponent); |
|
478 |
|
479 // Return response. |
|
480 return response; |
|
481 } |
|
482 |
|
483 |
|
484 DEBUG("CMIDCanvas::OfferKeyEventL, \ |
|
485 event not consumed by any custom component"); |
|
486 |
|
487 TInt keycode = aEvent.iScanCode; |
|
488 |
|
489 // If there is additional selection key mapping (e.g. to Enter key) and |
|
490 // scan code of delivered key is this additional key, flag is set to ETrue |
|
491 TBool additionalSelectionKey = |
|
492 (iKeyDecoder->AdditionalSelectionKeyMappingCode() != 0) && |
|
493 (keycode == iKeyDecoder->AdditionalSelectionKeyMappingCode()); |
|
494 |
|
495 if (keycode == EStdKeyDevice0 || |
|
496 keycode == EStdKeyDevice1 || |
|
497 keycode == EStdKeyDevice3 || |
|
498 additionalSelectionKey) |
|
499 { |
|
500 // CBA keys |
|
501 |
|
502 // In S60SelectionKeyCompatibility mode turned on and MSK pressed |
|
503 // don't map any command, send key event to Java. |
|
504 if (iS60SelectionKeyCompatibility && |
|
505 (keycode == EStdKeyDevice3 || additionalSelectionKey)) |
|
506 { |
|
507 SendKeyEventToJavaSideL(aEvent, aType); |
|
508 DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed"); |
|
509 return EKeyWasNotConsumed; |
|
510 } |
|
511 |
|
512 if (iDisplayable && !iDisplayable->IsFullScreenMode()) |
|
513 { |
|
514 // Pressing selection key is handled in CEikCba so that command |
|
515 // mapped to selection (MSK) key is invoked from there. |
|
516 // But CEikCba doesn't handle additional selection key |
|
517 // mapping, so it is done here. |
|
518 if (additionalSelectionKey && aType == EEventKey) |
|
519 { |
|
520 iDisplayable->ProcessMSKCommandL(); |
|
521 } |
|
522 else if (aType == EEventKeyDown && keycode == EStdKeyDevice3) |
|
523 { |
|
524 CMIDMenuHandler* menuHandler = iDisplayable->MenuHandler(); |
|
525 |
|
526 // If there is no additional selection key mapping |
|
527 // and scan code of delivered key is MSK then show menu, |
|
528 // used when ENavigationKeysFire or MSK were pressed |
|
529 if (iDisplayable->NumCommandsForOkOptionsMenu() == 0 |
|
530 && menuHandler) |
|
531 { |
|
532 menuHandler->ProcessCommandL(EAknSoftkeyEmpty); |
|
533 } |
|
534 else if (iDisplayable->NumCommandsForOkOptionsMenu() > 0 |
|
535 && menuHandler) |
|
536 { |
|
537 menuHandler->ProcessCommandL(EAknSoftkeyContextOptions); |
|
538 } |
|
539 } |
|
540 |
|
541 // Not a full screen mode, return so that the CBA gets the event. |
|
542 DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed"); |
|
543 return EKeyWasNotConsumed; |
|
544 } |
|
545 |
|
546 if (iDisplayable && iDisplayable->IsFullScreenMode() && |
|
547 iDisplayable->IsCommandListenerSet() && |
|
548 iDisplayable->CommandCount() > 0) |
|
549 { |
|
550 CMIDMenuHandler* menuHandler = iDisplayable->MenuHandler(); |
|
551 |
|
552 // If full screen and command listener is set and there are |
|
553 // Commands added to Canvas, then options menu is displayed. |
|
554 if (aType == EEventKey && menuHandler) |
|
555 { |
|
556 menuHandler->ShowMenuL( |
|
557 CMIDMenuHandler::EOptionsMenu); |
|
558 } |
|
559 |
|
560 DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed"); |
|
561 return EKeyWasNotConsumed; |
|
562 } |
|
563 } |
|
564 |
|
565 SendKeyEventToJavaSideL(aEvent, aType); |
|
566 |
|
567 DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed"); |
|
568 return EKeyWasNotConsumed; |
|
569 } |
|
570 |
|
571 |
|
572 // --------------------------------------------------------------------------- |
|
573 // From class MMIDComponent. |
|
574 // CMIDCanvas::Dispose |
|
575 // Invoked by the framework to clean up resources. |
|
576 // --------------------------------------------------------------------------- |
|
577 // |
|
578 void CMIDCanvas::Dispose() |
|
579 { |
|
580 delete this; |
|
581 } |
|
582 |
|
583 |
|
584 // --------------------------------------------------------------------------- |
|
585 // From class MMIDComponent. |
|
586 // CMIDCanvas::Type |
|
587 // Always returns the type MMIDComponent::ECanvas as component type. |
|
588 // --------------------------------------------------------------------------- |
|
589 // |
|
590 MMIDComponent::TType CMIDCanvas::Type() const |
|
591 { |
|
592 return MMIDComponent::ECanvas; |
|
593 } |
|
594 |
|
595 |
|
596 // --------------------------------------------------------------------------- |
|
597 // From class MMIDComponent. |
|
598 // CMIDCanvas::Processor |
|
599 // Always returns this-> as buffer processor associated with this component. |
|
600 // --------------------------------------------------------------------------- |
|
601 // |
|
602 MMIDBufferProcessor* CMIDCanvas::Processor() |
|
603 { |
|
604 return this; |
|
605 } |
|
606 |
|
607 |
|
608 // --------------------------------------------------------------------------- |
|
609 // From class MMIDCanvas. |
|
610 // CMIDCanvas::Control |
|
611 // Returns a reference to the CCoeControl corresponding to this canvas. |
|
612 // --------------------------------------------------------------------------- |
|
613 // |
|
614 CCoeControl& CMIDCanvas::Control() |
|
615 { |
|
616 return *this; |
|
617 } |
|
618 |
|
619 |
|
620 // --------------------------------------------------------------------------- |
|
621 // From class MMIDCanvas. |
|
622 // CMIDCanvas::FrameBuffer |
|
623 // Returns a pointer to the frame buffer. If double buffering is supported |
|
624 // this method must not return NULL. There is no ownership transfer. |
|
625 // --------------------------------------------------------------------------- |
|
626 // |
|
627 CFbsBitmap* CMIDCanvas::FrameBuffer() const |
|
628 { |
|
629 #ifdef CANVAS_DOUBLE_BUFFER |
|
630 return iFrameBuffer; |
|
631 #else |
|
632 return NULL; |
|
633 #endif // CANVAS_DOUBLE_BUFFER |
|
634 } |
|
635 |
|
636 |
|
637 // --------------------------------------------------------------------------- |
|
638 // From class MMIDCanvas. |
|
639 // CMIDCanvas::ContentSize |
|
640 // Returns the size of the canvas content. |
|
641 // --------------------------------------------------------------------------- |
|
642 // |
|
643 TSize CMIDCanvas::ContentSize() const |
|
644 { |
|
645 return iContentSize; |
|
646 } |
|
647 |
|
648 |
|
649 // --------------------------------------------------------------------------- |
|
650 // From class MMIDCanvas. |
|
651 // CMIDCanvas::PauseDirectAccess |
|
652 // Disables temporarily direct screen access. |
|
653 // This method should be called to disable direct screen access when a popup |
|
654 // menu is about to be displayed. This is a workaround for menu's failing to |
|
655 // correctly draw their shadows on Techview and other UI's that have floating |
|
656 // menubars. |
|
657 // --------------------------------------------------------------------------- |
|
658 // |
|
659 void CMIDCanvas::PauseDirectAccess() |
|
660 { |
|
661 #ifdef CANVAS_DIRECT_ACCESS |
|
662 StopDirectAccess(); |
|
663 #endif // CANVAS_DIRECT_ACCESS |
|
664 |
|
665 iFlags |= EDirectPaused; |
|
666 } |
|
667 |
|
668 |
|
669 // --------------------------------------------------------------------------- |
|
670 // From class MMIDCanvas. |
|
671 // CMIDCanvas::ResumeDirectAccess |
|
672 // Re-enables direct screen access. |
|
673 // To be called when the menu has disappeared. |
|
674 // --------------------------------------------------------------------------- |
|
675 // |
|
676 void CMIDCanvas::ResumeDirectAccess() |
|
677 { |
|
678 iFlags &= ~EDirectPaused; |
|
679 |
|
680 #ifdef CANVAS_DIRECT_ACCESS |
|
681 StartDirectAccess(); |
|
682 #endif // CANVAS_DIRECT_ACCESS |
|
683 } |
|
684 |
|
685 |
|
686 // --------------------------------------------------------------------------- |
|
687 // From class MMIDCanvas. |
|
688 // CMIDCanvas::SuppressKeys |
|
689 // Switch off key event posting. Game keys will still be tracked, but |
|
690 // keyPressed()/keyReleased() callbacks will not be called. |
|
691 // --------------------------------------------------------------------------- |
|
692 // |
|
693 void CMIDCanvas::SuppressKeys() |
|
694 { |
|
695 iFlags &= ~EPostKeyEvents; |
|
696 iEnv.ResetKeys(); |
|
697 } |
|
698 |
|
699 |
|
700 // --------------------------------------------------------------------------- |
|
701 // From class MMIDCanvas. |
|
702 // CMIDCanvas::GameActions |
|
703 // Returns the latched state of the game action keys. |
|
704 // --------------------------------------------------------------------------- |
|
705 // |
|
706 TUint32 CMIDCanvas::GameActions() |
|
707 { |
|
708 TUint32 latch = (iGameKeyLatch | iGameKeyState); |
|
709 iGameKeyLatch = 0; |
|
710 return latch; |
|
711 } |
|
712 |
|
713 |
|
714 // --------------------------------------------------------------------------- |
|
715 // From class MMIDCanvas. |
|
716 // CMIDCanvas::DirectContainer |
|
717 // Returns a direct container on which video can be rendered. |
|
718 // --------------------------------------------------------------------------- |
|
719 // |
|
720 MDirectContainer& CMIDCanvas::DirectContainer() |
|
721 { |
|
722 return *this; |
|
723 } |
|
724 |
|
725 |
|
726 // --------------------------------------------------------------------------- |
|
727 // From class MMIDCanvas. |
|
728 // CMIDCanvas::DrawBackground |
|
729 // Draw a background image. |
|
730 // --------------------------------------------------------------------------- |
|
731 // |
|
732 void CMIDCanvas::DrawBackground( |
|
733 CBitmapContext& aGc, const TPoint& aPosition, const TSize& aSize) |
|
734 { |
|
735 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
736 MAknsControlContext* cc = iDisplayable->BackGroundControlContext(); |
|
737 |
|
738 AknsDrawUtils::DrawBackground( |
|
739 skin, cc, NULL, aGc, aPosition, aSize, KAknsDrawParamDefault); |
|
740 } |
|
741 |
|
742 |
|
743 // --------------------------------------------------------------------------- |
|
744 // From class MMIDCanvas. |
|
745 // CMIDCanvas::IsGameCanvas |
|
746 // Returns the type of Canvas object. |
|
747 // --------------------------------------------------------------------------- |
|
748 // |
|
749 TBool CMIDCanvas::IsGameCanvas() const |
|
750 { |
|
751 return iIsGameCanvas; |
|
752 } |
|
753 |
|
754 |
|
755 // --------------------------------------------------------------------------- |
|
756 // From class MMIDCanvas. |
|
757 // Gets the Network indicator location for fullscreen |
|
758 // If not in fullscreenmode EFalse is returned |
|
759 // --------------------------------------------------------------------------- |
|
760 // |
|
761 TBool CMIDCanvas::NetworkIndicatorLocation( |
|
762 TPoint& aPosition, |
|
763 TSize& aSize) const |
|
764 { |
|
765 if (iFullScreen) |
|
766 { |
|
767 if (iNetworkIndicator) |
|
768 { |
|
769 iNetworkIndicator->GetLocation(aPosition, aSize); |
|
770 return ETrue; |
|
771 } |
|
772 } |
|
773 return EFalse; |
|
774 } |
|
775 |
|
776 |
|
777 #ifdef RD_TACTILE_FEEDBACK |
|
778 // --------------------------------------------------------------------------- |
|
779 // From MMIDCancas. |
|
780 // CMIDCanvas::TactileFeedbackComponent |
|
781 // Retutrns this as tactile feedback component. |
|
782 // --------------------------------------------------------------------------- |
|
783 // |
|
784 MMIDTactileFeedbackComponent* CMIDCanvas::TactileFeedbackComponent() |
|
785 { |
|
786 return this; |
|
787 } |
|
788 #endif // RD_TACTILE_FEEDBACK |
|
789 |
|
790 #ifdef RD_JAVA_NGA_ENABLED |
|
791 |
|
792 // --------------------------------------------------------------------------- |
|
793 // From class MMIDBufferProcessor. |
|
794 // CMIDCanvas::ProcessL |
|
795 // Process a block of commands, updating read pointer as you go. |
|
796 // --------------------------------------------------------------------------- |
|
797 // |
|
798 TBool CMIDCanvas::ProcessL( |
|
799 const TMIDBufferOp*& aRead, |
|
800 const TMIDBufferOp* aEnd, |
|
801 TInt& /* aCycles */, |
|
802 java::util::Monitor* aMonitor) |
|
803 { |
|
804 if (!iForeground) |
|
805 { |
|
806 DEBUG("CMIDCanvas::ProcessL() - not foreground"); |
|
807 ASSERT(!iAlfMonitor); |
|
808 aRead = aEnd; |
|
809 return EFalse; |
|
810 } |
|
811 |
|
812 switch (aRead->OpCode()) |
|
813 { |
|
814 case EDrwOpcM3GContentStart: |
|
815 { |
|
816 if (!iM3GContent && |
|
817 i3DAccelerated && |
|
818 iDirectContents.Count() == 0) |
|
819 { |
|
820 DEBUG("CMIDCanvas::ProcessL - M3G content start"); |
|
821 iM3GContent = ETrue; |
|
822 iM3GStart = ETrue; |
|
823 |
|
824 // First time when M3G content is drawn => |
|
825 // switch to EGL surface drawing. |
|
826 // Pixel source must be disposed first. |
|
827 DisposePixelSource(); |
|
828 OpenEglL(); |
|
829 |
|
830 // if we are scaling with m3g and HW acceleration |
|
831 // create a pbuffer surface to be used with m3g rendering |
|
832 if (iScalingOn && iFullScreen) |
|
833 { |
|
834 CreatePBufferSurfaceL(); |
|
835 } |
|
836 // Draw all framebuffer content to EGL surface. |
|
837 iUpperUpdateRect = TRect(Size()); |
|
838 UpdateEglContent(); |
|
839 } |
|
840 } |
|
841 break; |
|
842 case EDrwOpcBitBltRect: |
|
843 { |
|
844 const TBitBltData& data = BitBltData(aRead); |
|
845 UpdateL(data.iRect); |
|
846 } |
|
847 break; |
|
848 case EDrwOpcBitBlt: |
|
849 { |
|
850 UpdateL(iViewRect); |
|
851 } |
|
852 break; |
|
853 case EDrwOpcFirstPaint: |
|
854 { |
|
855 java::ui::CoreUiAvkonLcdui::getInstance().getJavaUiAppUi()->stopStartScreen(); |
|
856 } |
|
857 break; |
|
858 default: |
|
859 User::Leave(KErrNotSupported); |
|
860 break; |
|
861 } |
|
862 |
|
863 aRead += aRead->Size(); |
|
864 ASSERT(aRead == aEnd); |
|
865 |
|
866 // iFrameReady tells if this is async operation. |
|
867 // In async case CMIDBuffer waits until canvas |
|
868 // gets callback from Alf. |
|
869 // See CMIDBuffer.cpp and ProduceNewFrameL() |
|
870 if (iFrameReady) |
|
871 { |
|
872 iAlfMonitor = aMonitor; |
|
873 } |
|
874 return iFrameReady; |
|
875 } |
|
876 |
|
877 #else // RD_JAVA_NGA_ENABLED |
|
878 |
|
879 // --------------------------------------------------------------------------- |
|
880 // From class MMIDBufferProcessor. |
|
881 // CMIDCanvas::ProcessL |
|
882 // Process a block of commands, updating read pointer as you go. |
|
883 // --------------------------------------------------------------------------- |
|
884 // |
|
885 TBool CMIDCanvas::ProcessL( |
|
886 const TMIDBufferOp*& aRead, |
|
887 const TMIDBufferOp* aEnd, |
|
888 TInt& aCycles, |
|
889 TRequestStatus* /* aStatus */) |
|
890 { |
|
891 DEBUG("+ CMIDCanvas::ProcessL"); |
|
892 |
|
893 #ifdef CANVAS_DOUBLE_BUFFER |
|
894 while (aRead < aEnd) |
|
895 { |
|
896 switch (aRead->OpCode()) |
|
897 { |
|
898 case EDrwOpcBitBlt: |
|
899 { |
|
900 TSize size = iFrameBuffer->SizeInPixels(); |
|
901 |
|
902 #ifdef DEFER_BITBLT |
|
903 aCycles -= BitBltCycles(size); |
|
904 |
|
905 if (aCycles < 0) |
|
906 { |
|
907 return EFalse; |
|
908 } |
|
909 #endif // DEFER_BITBLT |
|
910 |
|
911 Update(TRect(size)); |
|
912 } |
|
913 break; |
|
914 |
|
915 case EDrwOpcBitBltRect: |
|
916 { |
|
917 const TBitBltData& data = BitBltData(aRead); |
|
918 TRect rect = data.iRect; |
|
919 |
|
920 // This is needed to avoid artifacting after orientation switch. |
|
921 // While changing orientation, wrong rect was not updated. |
|
922 if (iWndUpdate && (rect.Size() != iViewRect.Size()) |
|
923 && !iScalingOn) |
|
924 { |
|
925 break; |
|
926 } |
|
927 |
|
928 TRect frameRect(iFrameBuffer->SizeInPixels()); |
|
929 |
|
930 rect.Intersection(frameRect); |
|
931 |
|
932 #ifdef DEFER_BITBLT |
|
933 aCycles -= BitBltCycles(rect.Size()); |
|
934 |
|
935 if (aCycles < 0) |
|
936 { |
|
937 return EFalse; |
|
938 } |
|
939 #endif // DEFER_BITBLT |
|
940 |
|
941 Update(rect); |
|
942 } |
|
943 break; |
|
944 case EDrwOpcFirstPaint: |
|
945 { |
|
946 java::ui::CoreUiAvkonLcdui::getInstance().getJavaUiAppUi()->stopStartScreen(); |
|
947 } |
|
948 break; |
|
949 default: |
|
950 User::Leave(KErrNotSupported); |
|
951 break; |
|
952 } |
|
953 |
|
954 aRead += aRead->Size(); |
|
955 } |
|
956 #endif // CANVAS_DOUBLE_BUFFER |
|
957 |
|
958 DEBUG("- CMIDCanvas::ProcessL"); |
|
959 |
|
960 return EFalse; |
|
961 } |
|
962 #endif // RD_JAVA_NGA_ENABLED |
|
963 |
|
964 |
|
965 // --------------------------------------------------------------------------- |
|
966 // From class MMIDBufferProcessor. |
|
967 // CMIDCanvas::AbortAsync |
|
968 // Does nothing. |
|
969 // --------------------------------------------------------------------------- |
|
970 // |
|
971 void CMIDCanvas::AbortAsync() |
|
972 { |
|
973 // nop |
|
974 } |
|
975 |
|
976 |
|
977 #ifdef CANVAS_DIRECT_ACCESS |
|
978 // --------------------------------------------------------------------------- |
|
979 // From class MAbortDirectScreenAccess. |
|
980 // CMIDCanvas::AbortNow |
|
981 // This function is called by the window server when direct screen access |
|
982 // must stop (for example because a dialogue is moved in front of the area |
|
983 // where direct screen access is taking place). |
|
984 // --------------------------------------------------------------------------- |
|
985 // |
|
986 void CMIDCanvas::AbortNow( |
|
987 RDirectScreenAccess::TTerminationReasons /* aReasons */) |
|
988 { |
|
989 StopDirectAccess(); |
|
990 } |
|
991 |
|
992 |
|
993 // --------------------------------------------------------------------------- |
|
994 // From class MDirectScreenAccess. |
|
995 // CMIDCanvas::Restart |
|
996 // This function is called by the window server as soon as direct screen |
|
997 // access can resume. |
|
998 // --------------------------------------------------------------------------- |
|
999 // |
|
1000 void CMIDCanvas::Restart( |
|
1001 RDirectScreenAccess::TTerminationReasons /* aReasons */) |
|
1002 { |
|
1003 StartDirectAccess(); |
|
1004 } |
|
1005 #endif // CANVAS_DIRECT_ACCESS |
|
1006 |
|
1007 |
|
1008 // --------------------------------------------------------------------------- |
|
1009 // From class MDirectContainer. |
|
1010 // CMIDCanvas::MdcAddContent |
|
1011 // Set the content of this direct container. |
|
1012 // --------------------------------------------------------------------------- |
|
1013 // |
|
1014 void CMIDCanvas::MdcAddContent(MDirectContent* aContent) |
|
1015 { |
|
1016 TInt error = iDirectContents.Append(aContent); |
|
1017 |
|
1018 __ASSERT_DEBUG(error == KErrNone, User::Invariant()); |
|
1019 |
|
1020 // Register this control to observer |
|
1021 // in order to provide possibility to call |
|
1022 // methods from another than LCDUI ES thread. |
|
1023 // Unregistration is done in destructor. |
|
1024 #ifdef RD_JAVA_NGA_ENABLED |
|
1025 iEnv.ToLcduiObserver().RegisterControl(*this, this); |
|
1026 #else |
|
1027 iEnv.ToLcduiObserver().RegisterControl(*this); |
|
1028 #endif |
|
1029 } |
|
1030 |
|
1031 |
|
1032 // --------------------------------------------------------------------------- |
|
1033 // From class MDirectContainer. |
|
1034 // CMIDCanvas::MdcRemoveContent |
|
1035 // Remove the content from this direct container. This will called when |
|
1036 // the Player is closed. |
|
1037 // --------------------------------------------------------------------------- |
|
1038 // |
|
1039 void CMIDCanvas::MdcRemoveContent(MDirectContent* aContent) |
|
1040 { |
|
1041 TInt index = iDirectContents.Find(aContent); |
|
1042 |
|
1043 if (index != KErrNotFound) |
|
1044 { |
|
1045 iDirectContents.Remove(index); |
|
1046 if (iDirectContents.Count() == 0) |
|
1047 { |
|
1048 iRestoreContentWhenUnfaded = EFalse; |
|
1049 } |
|
1050 } |
|
1051 } |
|
1052 |
|
1053 |
|
1054 // --------------------------------------------------------------------------- |
|
1055 // From class MDirectContainer. |
|
1056 // CMIDCanvas::MdcAddContentBounds |
|
1057 // Adds a rectangle to be excluded from redrawing. |
|
1058 // --------------------------------------------------------------------------- |
|
1059 // |
|
1060 void CMIDCanvas::MdcAddContentBounds(const TRect& aRect) |
|
1061 { |
|
1062 if (iDisplayable) |
|
1063 { |
|
1064 iDisplayable->AddDirectContentArea(aRect); |
|
1065 } |
|
1066 } |
|
1067 |
|
1068 |
|
1069 // --------------------------------------------------------------------------- |
|
1070 // From class MDirectContainer. |
|
1071 // CMIDCanvas::MdcRemoveContentBounds |
|
1072 // Removes a rectangle to be excluded from redrawing. |
|
1073 // --------------------------------------------------------------------------- |
|
1074 // |
|
1075 void CMIDCanvas::MdcRemoveContentBounds(const TRect& aRect) |
|
1076 { |
|
1077 if (iDisplayable) |
|
1078 { |
|
1079 iDisplayable->RemoveDirectContentArea(aRect); |
|
1080 } |
|
1081 } |
|
1082 |
|
1083 |
|
1084 // --------------------------------------------------------------------------- |
|
1085 // From class MDirectContainer. |
|
1086 // CMIDCanvas::MdcContainerWindowRect() |
|
1087 // --------------------------------------------------------------------------- |
|
1088 // |
|
1089 TRect CMIDCanvas::MdcContainerWindowRect() const |
|
1090 { |
|
1091 // CMIDCanvas has the size of the window always |
|
1092 return MdcContentBounds(); |
|
1093 } |
|
1094 |
|
1095 |
|
1096 // --------------------------------------------------------------------------- |
|
1097 // From class MDirectContainer. |
|
1098 // CMIDCanvas::MdcContainerVisibility |
|
1099 // Get the visiblity of this direct container. |
|
1100 // --------------------------------------------------------------------------- |
|
1101 // |
|
1102 TBool CMIDCanvas::MdcContainerVisibility() const |
|
1103 { |
|
1104 return iDisplayable->IsVisible(); |
|
1105 } |
|
1106 |
|
1107 |
|
1108 // --------------------------------------------------------------------------- |
|
1109 // From class MDirectContainer. |
|
1110 // CMIDCanvas::MdcContentBounds |
|
1111 // Get the bounds of the area that the content of this direct container can |
|
1112 // occupy. |
|
1113 // Return content rect in screen co-ordinates. Position is stored in |
|
1114 // member variable because CCoeControl::PositionRelativeToScreen cannot |
|
1115 // be called from another thread. |
|
1116 // --------------------------------------------------------------------------- |
|
1117 // |
|
1118 TRect CMIDCanvas::MdcContentBounds() const |
|
1119 { |
|
1120 return TRect(iPositionRelativeToScreen, Size()); |
|
1121 } |
|
1122 |
|
1123 |
|
1124 // --------------------------------------------------------------------------- |
|
1125 // From class MDirectContainer. |
|
1126 // CMIDCanvas::MdcItemContentRect |
|
1127 // Get the area on the Item on which content can be displayed. |
|
1128 // This should only be called when the direct content is displayed on an Item, |
|
1129 // so always panic if it is called on Canvas. |
|
1130 // --------------------------------------------------------------------------- |
|
1131 // |
|
1132 void CMIDCanvas::MdcItemContentRect( |
|
1133 TRect& /* aContentRect */, |
|
1134 TRect& /* aScreenRect */) const |
|
1135 { |
|
1136 __ASSERT_DEBUG(EFalse, User::Invariant()); |
|
1137 } |
|
1138 |
|
1139 |
|
1140 // --------------------------------------------------------------------------- |
|
1141 // From class MDirectContainer. |
|
1142 // CMIDCanvas::MdcHandlePointerEventL |
|
1143 // Allows a control created for direct container content display to pass on |
|
1144 // pointer events. |
|
1145 // Though this is the leaving function nothing can leave actually. |
|
1146 // --------------------------------------------------------------------------- |
|
1147 // |
|
1148 void CMIDCanvas::MdcHandlePointerEventL(TPointerEvent& /* aPointerEvent */) |
|
1149 { |
|
1150 __ASSERT_DEBUG(EFalse, User::Invariant()); |
|
1151 } |
|
1152 |
|
1153 |
|
1154 // --------------------------------------------------------------------------- |
|
1155 // From class MDirectContainer. |
|
1156 // CMIDCanvas::MdcFlushContainer |
|
1157 // Flush the direct container content. |
|
1158 // --------------------------------------------------------------------------- |
|
1159 // |
|
1160 void CMIDCanvas::MdcFlushContainer(const TRect& aRect) |
|
1161 { |
|
1162 // Flush the framebuffer on screen |
|
1163 iEnv.ToLcduiObserver().FlushControl(*this, aRect); |
|
1164 } |
|
1165 |
|
1166 |
|
1167 // --------------------------------------------------------------------------- |
|
1168 // From class MDirectContainer. |
|
1169 // CMIDCanvas::MdcGetDSAResources |
|
1170 // Invokes callback aConsumer->MdcDSAResourcesCallback in LCDUI thread. |
|
1171 // --------------------------------------------------------------------------- |
|
1172 // |
|
1173 void CMIDCanvas::MdcGetDSAResources(MUiEventConsumer& aConsumer) |
|
1174 { |
|
1175 // May run in non-LCDUI ES thread |
|
1176 // Invoke the callback running in LCDUI ES thread |
|
1177 iEnv.ToLcduiObserver().InvokeDSAResourcesCallback(*this, aConsumer); |
|
1178 } |
|
1179 |
|
1180 |
|
1181 // --------------------------------------------------------------------------- |
|
1182 // From class MDirectContainer. |
|
1183 // CMIDCanvas::MdcGetUICallback |
|
1184 // Invokes callback aConsumer->MdcUICallback in LCDUI thread. |
|
1185 // --------------------------------------------------------------------------- |
|
1186 // |
|
1187 void CMIDCanvas::MdcGetUICallback( |
|
1188 MUiEventConsumer& aConsumer, |
|
1189 TInt aCallbackId) |
|
1190 { |
|
1191 // May run in non-LCDUI ES thread |
|
1192 // Invoke the callback running in LCDUI ES thread |
|
1193 iEnv.ToLcduiObserver().InvokeUICallback(aConsumer, aCallbackId); |
|
1194 } |
|
1195 |
|
1196 #ifdef RD_JAVA_NGA_ENABLED |
|
1197 // --------------------------------------------------------------------------- |
|
1198 // From class MDirectContainer. |
|
1199 // CMIDCanvas::MdcNotifyContentAdded |
|
1200 // Notification about added direct content, called in LCDUI thread. |
|
1201 // Canvas needs to dispose pixel source before MMAPI adds video surface |
|
1202 // to canvas window. Pixel source cannot be disposed in MdcAddContent |
|
1203 // because it may be called in MMAPI thread. |
|
1204 // --------------------------------------------------------------------------- |
|
1205 // |
|
1206 void CMIDCanvas::MdcNotifyContentAdded() |
|
1207 { |
|
1208 DisposePixelSource(); |
|
1209 CloseEgl(); |
|
1210 } |
|
1211 #endif // RD_JAVA_NGA_ENABLED |
|
1212 |
|
1213 |
|
1214 // --------------------------------------------------------------------------- |
|
1215 // From class MMIDMediaKeysListener. |
|
1216 // CMIDCanvas::HandleMediaKeyEvent |
|
1217 // This method is called when a media key has been pressed. |
|
1218 // --------------------------------------------------------------------------- |
|
1219 // |
|
1220 void CMIDCanvas::HandleMediaKeyEvent(TMIDKeyEvent& aKeyEvent) |
|
1221 { |
|
1222 if (PostKeyEvents()) |
|
1223 { |
|
1224 DEBUG_INT3( |
|
1225 "CMIDCanvas::HandleMediaKeyEvent - PostKeyEvent() - \ |
|
1226 JAVA code %d type %d repeats %d", |
|
1227 aKeyEvent.iKeyCode, |
|
1228 aKeyEvent.iEvents, |
|
1229 aKeyEvent.iRepeats); |
|
1230 |
|
1231 iEnv.PostKeyEvent(*this, aKeyEvent); |
|
1232 } |
|
1233 } |
|
1234 |
|
1235 |
|
1236 #ifdef RD_TACTILE_FEEDBACK |
|
1237 // --------------------------------------------------------------------------- |
|
1238 // From class MMIDTactileFeedbackComponent. |
|
1239 // CMIDCanvas::UpdateTactileFeedback |
|
1240 // Update tactile feedback areas. |
|
1241 // --------------------------------------------------------------------------- |
|
1242 // |
|
1243 void CMIDCanvas::UpdateTactileFeedback() |
|
1244 { |
|
1245 TInt areaCount = iTactileFeedback->GetAreasCount(); |
|
1246 |
|
1247 for (TInt i = 0; i < areaCount; i++) |
|
1248 { |
|
1249 CMIDTactileFeedbackExtension::FeedbackArea* area = |
|
1250 iTactileFeedback->GetArea(i); |
|
1251 |
|
1252 TRect physicalRect = area->rect; |
|
1253 |
|
1254 iTactileFeedback->SetFeedbackArea(area->id, |
|
1255 physicalRect, |
|
1256 (TInt)area->style); |
|
1257 } |
|
1258 } |
|
1259 |
|
1260 |
|
1261 // --------------------------------------------------------------------------- |
|
1262 // From class MMIDTactileFeedbackComponent. |
|
1263 // CMIDCanvas::RegisterFeedbackArea |
|
1264 // Register feedback area. |
|
1265 // --------------------------------------------------------------------------- |
|
1266 // |
|
1267 void CMIDCanvas::RegisterFeedbackArea(TInt aId, TRect aRect, TInt aStyle) |
|
1268 { |
|
1269 iTactileFeedback->RegisterFeedbackArea(aId, aRect, aStyle); |
|
1270 } |
|
1271 |
|
1272 |
|
1273 // --------------------------------------------------------------------------- |
|
1274 // From class MMIDTactileFeedbackComponent. |
|
1275 // CMIDCanvas::UnregisterFeedbackArea |
|
1276 // Unregister feedback area. |
|
1277 // --------------------------------------------------------------------------- |
|
1278 // |
|
1279 void CMIDCanvas::UnregisterFeedbackArea(TInt aId) |
|
1280 { |
|
1281 iTactileFeedback->UnregisterFeedbackArea(aId); |
|
1282 } |
|
1283 |
|
1284 |
|
1285 // --------------------------------------------------------------------------- |
|
1286 // From class MMIDTactileFeedbackComponent. |
|
1287 // CMIDCanvas::UnregisterFeedbackForControl |
|
1288 // Unregister feedback for the control. |
|
1289 // --------------------------------------------------------------------------- |
|
1290 // |
|
1291 void CMIDCanvas::UnregisterFeedbackForControl() |
|
1292 { |
|
1293 iTactileFeedback->UnregisterFeedbackForControl(); |
|
1294 } |
|
1295 |
|
1296 |
|
1297 // --------------------------------------------------------------------------- |
|
1298 // From class MMIDTactileFeedbackComponent. |
|
1299 // CMIDCanvas::MoveAreaToFirstPriority |
|
1300 // Move area to first priority. |
|
1301 // --------------------------------------------------------------------------- |
|
1302 // |
|
1303 void CMIDCanvas::MoveAreaToFirstPriority(TInt aId) |
|
1304 { |
|
1305 iTactileFeedback->MoveAreaToFirstPriority(aId); |
|
1306 } |
|
1307 #endif // RD_TACTILE_FEEDBACK |
|
1308 |
|
1309 // --------------------------------------------------------------------------- |
|
1310 // CMIDCanvas::RegisterComponentL |
|
1311 // Registers a new custom component to this container. |
|
1312 // (other items are commented in the header file) |
|
1313 // --------------------------------------------------------------------------- |
|
1314 // |
|
1315 void CMIDCanvas::RegisterComponentL(MMIDCustomComponent* aComponent) |
|
1316 { |
|
1317 DEBUG("CMIDCanvas::RegisterComponentL +"); |
|
1318 |
|
1319 if (iCustomComponents.Find(aComponent) == KErrNotFound) |
|
1320 { |
|
1321 DEBUG("CMIDCanvas::RegisterComponentL, registering new"); |
|
1322 |
|
1323 iCustomComponents.Append(aComponent); |
|
1324 |
|
1325 // Update custom components count in order to improve |
|
1326 // the performance when counting components |
|
1327 iCustomComponentsControlCount += |
|
1328 aComponent->CustomComponentControlCount(); |
|
1329 |
|
1330 } |
|
1331 |
|
1332 DEBUG("CMIDCanvas::RegisterComponentL -"); |
|
1333 } |
|
1334 |
|
1335 // --------------------------------------------------------------------------- |
|
1336 // CMIDCanvas::UnregisterComponent |
|
1337 // Unregisters an existing custom component from this container. |
|
1338 // (other items are commented in the header file) |
|
1339 // --------------------------------------------------------------------------- |
|
1340 // |
|
1341 void CMIDCanvas::UnregisterComponent(MMIDCustomComponent* aComponent) |
|
1342 { |
|
1343 DEBUG("CMIDCanvas::UnregisterComponent +"); |
|
1344 |
|
1345 TInt index = iCustomComponents.Find(aComponent); |
|
1346 |
|
1347 if (index != KErrNotFound) |
|
1348 { |
|
1349 // Update of iFocusedComponent index. |
|
1350 if (index < iFocusedComponent) |
|
1351 { |
|
1352 iFocusedComponent--; |
|
1353 } |
|
1354 else if (index == iFocusedComponent) |
|
1355 { |
|
1356 iFocusedComponent = KComponentFocusedNone; |
|
1357 } |
|
1358 |
|
1359 if ((iPressedComponent) && (iPressedComponent == aComponent)) |
|
1360 { |
|
1361 iPressedComponent = NULL; |
|
1362 } |
|
1363 |
|
1364 iCustomComponents.Remove(index); |
|
1365 // Compress the array to keep the object indexes in order. |
|
1366 iCustomComponents.Compress(); |
|
1367 // Update custom components count in order to improve |
|
1368 // the performance when counting components |
|
1369 iCustomComponentsControlCount -= |
|
1370 aComponent->CustomComponentControlCount(); |
|
1371 |
|
1372 // Redraw the whole canvas. |
|
1373 DrawDeferred(); |
|
1374 } |
|
1375 |
|
1376 DEBUG("CMIDCanvas::UnregisterComponent -"); |
|
1377 } |
|
1378 |
|
1379 // --------------------------------------------------------------------------- |
|
1380 // CMIDCanvas::IsFullScreen |
|
1381 // (other items are commented in the header file) |
|
1382 // --------------------------------------------------------------------------- |
|
1383 // |
|
1384 TBool CMIDCanvas::IsFullScreen() const |
|
1385 { |
|
1386 return iFullScreen; |
|
1387 } |
|
1388 |
|
1389 // --------------------------------------------------------------------------- |
|
1390 // CMIDCanvas::SetComponentIndexL |
|
1391 // Changes the index of the specified custom component. |
|
1392 // (other items are commented in the header file) |
|
1393 // --------------------------------------------------------------------------- |
|
1394 // |
|
1395 void CMIDCanvas::SetComponentIndexL( |
|
1396 MMIDCustomComponent* aComponent, |
|
1397 TInt aNewIndex) |
|
1398 { |
|
1399 DEBUG("CMIDCanvas::SetComponentIndexL +"); |
|
1400 |
|
1401 // Adjust the index if it is out of bounds. |
|
1402 TInt count = iCustomComponents.Count(); |
|
1403 if (aNewIndex >= count) |
|
1404 { |
|
1405 aNewIndex = count - 1; |
|
1406 } |
|
1407 |
|
1408 // The index must not be negative. |
|
1409 __ASSERT_DEBUG(aNewIndex >= 0, User::Invariant()); |
|
1410 |
|
1411 TInt index = iCustomComponents.Find(aComponent); |
|
1412 |
|
1413 // Do not adjust the position if there is no need for it |
|
1414 // or if the component does not exist in the array. |
|
1415 if (index != KErrNotFound && index != aNewIndex) |
|
1416 { |
|
1417 // Update index of focused component |
|
1418 |
|
1419 if (index == iFocusedComponent) |
|
1420 { |
|
1421 iFocusedComponent = aNewIndex; |
|
1422 } |
|
1423 else if ((iFocusedComponent < index) && (iFocusedComponent >= aNewIndex)) |
|
1424 { |
|
1425 iFocusedComponent++; |
|
1426 } |
|
1427 else if ((iFocusedComponent > index) && (iFocusedComponent <= aNewIndex)) |
|
1428 { |
|
1429 iFocusedComponent--; |
|
1430 } |
|
1431 |
|
1432 // Remove the old index from the components array. |
|
1433 iCustomComponents.Remove(index); |
|
1434 |
|
1435 // Add the component to the new index. Note that the array |
|
1436 // should contain memory for all the components since |
|
1437 // Remove should not decrease the memory used by the array |
|
1438 // Therefore, the following operation is leave-safe and |
|
1439 // return value is ignored intentionally. |
|
1440 iCustomComponents.Insert(aComponent, aNewIndex); |
|
1441 |
|
1442 // Redraw the whole canvas. |
|
1443 DrawDeferred(); |
|
1444 } |
|
1445 |
|
1446 DEBUG("CMIDCanvas::SetComponentIndexL -"); |
|
1447 } |
|
1448 |
|
1449 // --------------------------------------------------------------------------- |
|
1450 // CMIDCanvas::ComponentIndex |
|
1451 // Returns the index of the given component in this container. |
|
1452 // (other items are commented in the header file) |
|
1453 // --------------------------------------------------------------------------- |
|
1454 // |
|
1455 TInt CMIDCanvas::ComponentIndex(MMIDCustomComponent* aComponent) const |
|
1456 { |
|
1457 DEBUG("CMIDCanvas::ComponentIndex"); |
|
1458 |
|
1459 return iCustomComponents.Find(aComponent); |
|
1460 } |
|
1461 |
|
1462 // --------------------------------------------------------------------------- |
|
1463 // CMIDCanvas::PostEvent |
|
1464 // Post an event to Java side. |
|
1465 // --------------------------------------------------------------------------- |
|
1466 // |
|
1467 TBool CMIDCanvas::PostEvent( |
|
1468 TEventType aType, |
|
1469 TInt aData0, |
|
1470 TInt aData1) const |
|
1471 { |
|
1472 return iEnv.PostJavaEvent(const_cast< CMIDCanvas& >(*this), |
|
1473 EDisplayable, |
|
1474 aType, |
|
1475 aData0, |
|
1476 aData1, |
|
1477 0); |
|
1478 } |
|
1479 |
|
1480 #ifdef RD_JAVA_NGA_ENABLED |
|
1481 |
|
1482 // --------------------------------------------------------------------------- |
|
1483 // CMIDCanvas::Update |
|
1484 // Update screen from frame buffer. |
|
1485 // --------------------------------------------------------------------------- |
|
1486 // |
|
1487 void CMIDCanvas::UpdateL(const TRect& aRect) |
|
1488 { |
|
1489 // Drawing Network indicator only when Update is called. |
|
1490 if (iFullScreen && iNetworkIndicator) |
|
1491 { |
|
1492 iNetworkIndicator->SetDrawIndicator(ETrue); |
|
1493 } |
|
1494 |
|
1495 // iRestoreContentWhenUnfaded is used when Canvas should be faded |
|
1496 // DrawNow need to be called, otherwise Canvas will be unfaded |
|
1497 if (iDirectContents.Count() == 0 && !iRestoreContentWhenUnfaded && IsFocused()) |
|
1498 { |
|
1499 // In case direct content content was removed |
|
1500 // from canvas, recreate pixel source here |
|
1501 if (!iAlfCompositionPixelSource && |
|
1502 !IsEglAvailable()) |
|
1503 { |
|
1504 InitPixelSourceL(); |
|
1505 } |
|
1506 DrawWindowNgaL(aRect); |
|
1507 } |
|
1508 else |
|
1509 { |
|
1510 // Must draw via CCoeControl framework |
|
1511 DrawNow(aRect); |
|
1512 } |
|
1513 |
|
1514 // This is needed to avoid artifacting after orientation switch. |
|
1515 // It is called once after orientation change. |
|
1516 if (iWndUpdate) |
|
1517 { |
|
1518 iWndUpdate = EFalse; |
|
1519 } |
|
1520 } |
|
1521 |
|
1522 #else // !RD_JAVA_NGA_ENABLED |
|
1523 // --------------------------------------------------------------------------- |
|
1524 // CMIDCanvas::Update |
|
1525 // Update screen from frame buffer. |
|
1526 // --------------------------------------------------------------------------- |
|
1527 // |
|
1528 void CMIDCanvas::Update(const TRect& aRect) |
|
1529 { |
|
1530 DEBUG("- CMIDCanvas::Update"); |
|
1531 |
|
1532 #ifdef CANVAS_DOUBLE_BUFFER |
|
1533 if (IsVisible()) |
|
1534 { |
|
1535 // Drawing Network indicator only when Update is called. |
|
1536 if (iFullScreen && iNetworkIndicator) |
|
1537 { |
|
1538 iNetworkIndicator->SetDrawIndicator(ETrue); |
|
1539 } |
|
1540 |
|
1541 #ifdef CANVAS_DIRECT_ACCESS |
|
1542 // Check if some direct screen content is drawn. |
|
1543 if (iDirectContents.Count() > 0) |
|
1544 { |
|
1545 // There is some direct screen content drawn, DSA is not free for |
|
1546 // us at the moment. |
|
1547 DrawNow(aRect); |
|
1548 } |
|
1549 else |
|
1550 { |
|
1551 // No direct screen content is drawn, so we can try to use DSA. |
|
1552 StartDirectAccess(); |
|
1553 |
|
1554 if (iDirectGc) |
|
1555 { |
|
1556 // DSA is ready to use, draw directly. |
|
1557 DrawDirect(aRect); |
|
1558 } |
|
1559 else |
|
1560 #endif // CANVAS_DIRECT_ACCESS |
|
1561 { |
|
1562 ActivateGc(); |
|
1563 DrawWindow(aRect); |
|
1564 DeactivateGc(); |
|
1565 } |
|
1566 #ifdef CANVAS_DIRECT_ACCESS |
|
1567 } |
|
1568 #endif // CANVAS_DIRECT_ACCESS |
|
1569 |
|
1570 // This is needed to avoid artifacting after orientation switch. |
|
1571 // It is called once after orientation change. |
|
1572 if (iWndUpdate) |
|
1573 { |
|
1574 iWndUpdate = EFalse; |
|
1575 } |
|
1576 } |
|
1577 #endif // CANVAS_DOUBLE_BUFFER |
|
1578 |
|
1579 DEBUG("+ CMIDCanvas::Update"); |
|
1580 } |
|
1581 |
|
1582 #endif // RD_JAVA_NGA_ENABLED |
|
1583 |
|
1584 // --------------------------------------------------------------------------- |
|
1585 // CMIDCanvas::PrepareDraw |
|
1586 // Prepare drawing. Used in DrawWindow and DrawDirect. |
|
1587 // aWindowRect is in bitmap coords. |
|
1588 // --------------------------------------------------------------------------- |
|
1589 // |
|
1590 inline void CMIDCanvas::PrepareDraw( |
|
1591 CGraphicsContext& aGc, TRect& aWinRect) const |
|
1592 { |
|
1593 const TRect rect = Rect(); |
|
1594 #ifdef RD_JAVA_NGA_ENABLED |
|
1595 if (iDirectContents.Count() > 0) |
|
1596 { |
|
1597 |
|
1598 // Content may be centered in which case we need to clear the background. |
|
1599 if (rect != iViewRect) |
|
1600 { |
|
1601 // Clear background with black if centered. |
|
1602 aGc.SetBrushColor(KRgbBlack); |
|
1603 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
1604 |
|
1605 DrawUtils::ClearBetweenRects(aGc, rect, iViewRect); |
|
1606 } |
|
1607 } |
|
1608 #else |
|
1609 // Content may be centered in which case we need to clear the background. |
|
1610 if (rect != iViewRect) |
|
1611 { |
|
1612 // Clear background with black if centered. |
|
1613 aGc.SetBrushColor(KRgbBlack); |
|
1614 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
1615 |
|
1616 DrawUtils::ClearBetweenRects(aGc, rect, iViewRect); |
|
1617 } |
|
1618 #endif // RD_JAVA_NGA_ENABLED |
|
1619 |
|
1620 if (iFullScreen && iNetworkIndicator) |
|
1621 { |
|
1622 // Network indicator or call indicator is drawn to the off-screen |
|
1623 // buffer if connection is open. |
|
1624 iNetworkIndicator->DrawNetworkIndicator( |
|
1625 *iFrameContext, aWinRect, iViewRect); |
|
1626 } |
|
1627 |
|
1628 if (iViewRect.Size() == iContentSize) |
|
1629 { |
|
1630 // Transform the source rect to window coords. |
|
1631 aWinRect.Move(iViewRect.iTl); |
|
1632 |
|
1633 // Clip to viewport. |
|
1634 aWinRect.Intersection(iViewRect); |
|
1635 } |
|
1636 else |
|
1637 { |
|
1638 aWinRect = iViewRect; |
|
1639 } |
|
1640 } |
|
1641 |
|
1642 |
|
1643 #ifdef RD_JAVA_NGA_ENABLED |
|
1644 // --------------------------------------------------------------------------- |
|
1645 // CMIDCanvas::DrawWindowNgaL |
|
1646 // Draw using pixel source of EGL surface depending on what canvas content |
|
1647 // has been drawn. |
|
1648 // --------------------------------------------------------------------------- |
|
1649 // |
|
1650 void CMIDCanvas::DrawWindowNgaL(const TRect& aRect) |
|
1651 { |
|
1652 ASSERT(IsEglAvailable() || iAlfCompositionPixelSource); |
|
1653 |
|
1654 if (iFullScreen && iNetworkIndicator) |
|
1655 { |
|
1656 TRect windowRect(aRect); |
|
1657 iNetworkIndicator->DrawNetworkIndicator( |
|
1658 *iFrameContext, windowRect, iViewRect); |
|
1659 } |
|
1660 |
|
1661 if (!IsEglAvailable()) |
|
1662 { |
|
1663 // No M3G content, use pixel source |
|
1664 ActivatePixelSourceL(); |
|
1665 DEBUG("CMIDCanvas::Draw - Pixel Source activated"); |
|
1666 } |
|
1667 else // M3G content, use EGL surface |
|
1668 { |
|
1669 // Invalidates window so that wserv does not |
|
1670 // draw window content on top our EGL surface. |
|
1671 // This is needed only once when starting to use EGL surface. |
|
1672 if (iM3GStart) |
|
1673 { |
|
1674 DEBUG("CMIDCanvas::DrawWindow - invalidate"); |
|
1675 Window().Invalidate(); |
|
1676 iM3GStart = EFalse; |
|
1677 } |
|
1678 |
|
1679 if (iScalingOn && iFullScreen) |
|
1680 { |
|
1681 SetCurrentEglType(EEglPbuffer); |
|
1682 BlitFrameBufferPixels(); |
|
1683 SetCurrentEglType(EEglWindow); |
|
1684 if (iWndUpdate) |
|
1685 { |
|
1686 DEBUG("CMIDCanvas::DrawWindowNgaL() - clearing window surface"); |
|
1687 ClearEglSurface(EEglWindow); |
|
1688 } |
|
1689 BlitPBufferScaledToWindowSurface(); |
|
1690 } |
|
1691 else |
|
1692 { |
|
1693 SetCurrentEglType(EEglWindow); |
|
1694 BlitFrameBufferPixels(); |
|
1695 } |
|
1696 |
|
1697 if (eglSwapBuffers(iEglDisplay, iEglWindowSurface) == EGL_FALSE) |
|
1698 { |
|
1699 ELOG1(EJavaUI, "eglSwapBuffers() failed, eglError=%d", eglGetError()); |
|
1700 ASSERT(EFalse); |
|
1701 } |
|
1702 SetCurrentEglType(EEglNone); |
|
1703 } |
|
1704 } |
|
1705 #endif // RD_JAVA_NGA_ENABLED |
|
1706 |
|
1707 |
|
1708 #ifdef CANVAS_DOUBLE_BUFFER |
|
1709 // --------------------------------------------------------------------------- |
|
1710 // CMIDCanvas::DrawWindow |
|
1711 // Draw through Window server using native frame buffer. |
|
1712 // --------------------------------------------------------------------------- |
|
1713 // |
|
1714 void CMIDCanvas::DrawWindow(const TRect& aRect) const |
|
1715 { |
|
1716 DEBUG("CMIDCanvas::DrawWindow ++"); |
|
1717 ASSERT(iFrameBuffer); |
|
1718 |
|
1719 CWindowGc& gc = SystemGc(); |
|
1720 |
|
1721 // If EColor16MA display mode is used, graphics context needs to set its |
|
1722 // draw mode to EDrawModeWriteAlpha for just to copy an alpha channel and |
|
1723 // not to do any blending. |
|
1724 if (iFrameBuffer->DisplayMode() == EColor16MA) |
|
1725 { |
|
1726 gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); |
|
1727 } |
|
1728 |
|
1729 TRect windowRect(aRect); |
|
1730 PrepareDraw(gc, windowRect); |
|
1731 |
|
1732 // Check if Canvas scaling is used. |
|
1733 if (iViewRect.Size() == iContentSize) |
|
1734 { |
|
1735 DEBUG("DrawWindow - Not scaled - BitBlt"); |
|
1736 gc.BitBlt(windowRect.iTl, iFrameBuffer, windowRect); |
|
1737 } |
|
1738 else if (IsDownScaling(iContentSize, iViewRect)) |
|
1739 { |
|
1740 DEBUG("DrawWindow - Downscaling - BitBlt"); |
|
1741 gc.BitBlt(windowRect.iTl, iFrameBuffer, windowRect.Size()); |
|
1742 } |
|
1743 // Upscaling |
|
1744 else if (iScaler) |
|
1745 { |
|
1746 iFrameBuffer->LockHeap(); |
|
1747 TUint32* pixelData = iFrameBuffer->DataAddress(); |
|
1748 |
|
1749 // Scale the framebuffer content. |
|
1750 CFbsBitmap* map = iScaler->Process( |
|
1751 iFrameBuffer->DisplayMode(), |
|
1752 pixelData, |
|
1753 iContentSize.iWidth, |
|
1754 iContentSize.iHeight, |
|
1755 iFrameBuffer->SizeInPixels().iWidth - iContentSize.iWidth, |
|
1756 iViewRect.Width(), |
|
1757 iViewRect.Height()); |
|
1758 |
|
1759 iFrameBuffer->UnlockHeap(); |
|
1760 |
|
1761 if (map) |
|
1762 { |
|
1763 DEBUG("DrawWindow - Upscaling - BitBlt - map ok"); |
|
1764 gc.BitBlt(windowRect.iTl, map, windowRect.Size()); |
|
1765 } |
|
1766 else |
|
1767 { |
|
1768 DEBUG("DrawWindow - Upscaling - DrawBitmap - no map"); |
|
1769 gc.DrawBitmap(windowRect, iFrameBuffer, iContentSize); |
|
1770 } |
|
1771 } |
|
1772 |
|
1773 #ifdef RD_JAVA_NGA_ENABLED |
|
1774 iCoeEnv->WsSession().Finish(); |
|
1775 #endif |
|
1776 |
|
1777 DEBUG("CMIDCanvas::DrawWindow --"); |
|
1778 } |
|
1779 #endif // CANVAS_DOUBLE_BUFFER |
|
1780 |
|
1781 |
|
1782 #ifdef CANVAS_DIRECT_ACCESS |
|
1783 // --------------------------------------------------------------------------- |
|
1784 // CMIDCanvas::StartDirectAccess |
|
1785 // Start Direct Screen Access. |
|
1786 // --------------------------------------------------------------------------- |
|
1787 // |
|
1788 void CMIDCanvas::StartDirectAccess() |
|
1789 { |
|
1790 // If DSA is not enabled or paused, or direct GC already exists just get |
|
1791 // out of here. |
|
1792 if (!DirectEnabled() || DirectPaused() || iDirectGc) |
|
1793 { |
|
1794 return; |
|
1795 } |
|
1796 |
|
1797 CCoeAppUi& appUi = *static_cast< CCoeAppUi* >(ControlEnv()->AppUi()); |
|
1798 |
|
1799 if (appUi.IsDisplayingMenuOrDialog()) |
|
1800 { |
|
1801 return; |
|
1802 } |
|
1803 |
|
1804 TRAPD(err, RestartL()); |
|
1805 |
|
1806 if (KErrNone != err) |
|
1807 { |
|
1808 StopDirectAccess(); |
|
1809 } |
|
1810 else |
|
1811 { |
|
1812 if (iDcDsaToStart && iDirectGc) |
|
1813 { |
|
1814 // Resume DSA for all direct contents |
|
1815 iDcDsaToStart = EFalse; |
|
1816 TInt contentsCount(iDirectContents.Count()); |
|
1817 |
|
1818 for (TInt j = 0; j < contentsCount; j++) |
|
1819 { |
|
1820 iDirectContents[j]->MdcResumeDSA(); |
|
1821 } |
|
1822 } |
|
1823 } |
|
1824 } |
|
1825 |
|
1826 |
|
1827 // --------------------------------------------------------------------------- |
|
1828 // CMIDCanvas::StopDirectAccess |
|
1829 // Stop Direct Screen Access. |
|
1830 // --------------------------------------------------------------------------- |
|
1831 // |
|
1832 void CMIDCanvas::StopDirectAccess() |
|
1833 { |
|
1834 iDirectGc = NULL; |
|
1835 if (!iDcDsaToStart) |
|
1836 { |
|
1837 // Abort direct DSA for all direct contents |
|
1838 |
|
1839 TInt contentsCount(iDirectContents.Count()); |
|
1840 |
|
1841 if (contentsCount > 0) |
|
1842 { |
|
1843 iDcDsaToStart = ETrue; |
|
1844 } |
|
1845 |
|
1846 for (TInt j = 0; j < contentsCount; j++) |
|
1847 { |
|
1848 iDirectContents[j]->MdcAbortDSA(); |
|
1849 } |
|
1850 } |
|
1851 |
|
1852 if (iDirectAccess) |
|
1853 { |
|
1854 iDirectAccess->Cancel(); |
|
1855 } |
|
1856 } |
|
1857 |
|
1858 |
|
1859 // --------------------------------------------------------------------------- |
|
1860 // CMIDCanvas::RestartL |
|
1861 // Restart Direct Screen Access. |
|
1862 // --------------------------------------------------------------------------- |
|
1863 // |
|
1864 void CMIDCanvas::RestartL() |
|
1865 { |
|
1866 ASSERT(DirectEnabled()); |
|
1867 ASSERT(iDirectAccess); |
|
1868 |
|
1869 if (!iDirectAccess->IsActive()) |
|
1870 { |
|
1871 iDirectAccess->StartL(); |
|
1872 } |
|
1873 |
|
1874 iDirectGc = NULL; |
|
1875 |
|
1876 if (iDirectAccess->DrawingRegion()->Count() == 1) |
|
1877 { |
|
1878 // Check that the drawing region is fully visibile (not covered) |
|
1879 TRect drawableRect((*iDirectAccess->DrawingRegion())[0]); |
|
1880 TRect canvasRect(PositionRelativeToScreen(), Size()); |
|
1881 |
|
1882 drawableRect.Intersection(canvasRect); |
|
1883 |
|
1884 // Check that the drawing region has the proper size |
|
1885 if (drawableRect == canvasRect) |
|
1886 { |
|
1887 // Prepare context for actual drawing |
|
1888 iDirectGc = iDirectAccess->Gc(); |
|
1889 |
|
1890 // Direct draw is using only BitBlt and DrawBitmap so we can |
|
1891 // always use EDrawModeWriteAlpha draw mode to optimize drawing |
|
1892 // process. If EColor16MA display mode is used, graphics context |
|
1893 // needs to set its draw mode to EDrawModeWriteAlpha to just copy |
|
1894 // an alpha channel and not do any blending. |
|
1895 if (iFrameBuffer->DisplayMode() == EColor16MA) |
|
1896 { |
|
1897 iDirectGc->SetDrawMode( |
|
1898 CGraphicsContext::EDrawModeWriteAlpha); |
|
1899 } |
|
1900 } |
|
1901 } |
|
1902 } |
|
1903 |
|
1904 |
|
1905 // --------------------------------------------------------------------------- |
|
1906 // CMIDCanvas::DrawDirect |
|
1907 // Draw using Direct Screen Access. |
|
1908 // aRect is in framebuffer coords. |
|
1909 // --------------------------------------------------------------------------- |
|
1910 // |
|
1911 void CMIDCanvas::DrawDirect(const TRect& aRect) const |
|
1912 { |
|
1913 DEBUG("+ CMIDCanvas::DrawDirect"); |
|
1914 |
|
1915 ASSERT(DirectEnabled()); |
|
1916 ASSERT(iDirectGc); |
|
1917 ASSERT(iDirectAccess); |
|
1918 ASSERT(iFrameBuffer); |
|
1919 |
|
1920 // Visible region in screen coordinates. Should only contain a single clip |
|
1921 // rect otherwise direct access should have aborted. |
|
1922 const RRegion& visibleRegion = *(iDirectAccess->DrawingRegion()); |
|
1923 |
|
1924 ASSERT(visibleRegion.Count() == 1); |
|
1925 |
|
1926 TRect windowRect(aRect); |
|
1927 PrepareDraw(*iDirectGc, windowRect); |
|
1928 |
|
1929 // Check if Canvas scaling is used. |
|
1930 if (iViewRect == iContentSize) |
|
1931 { |
|
1932 // No scaling, plain draw. |
|
1933 DEBUG("DrawDirect - NotScaled"); |
|
1934 iDirectGc->BitBlt(windowRect.iTl, iFrameBuffer, windowRect); |
|
1935 } |
|
1936 else if (IsDownScaling(iContentSize, iViewRect)) |
|
1937 { |
|
1938 DEBUG("DrawDirect - Downscaling"); |
|
1939 iDirectGc->BitBlt(windowRect.iTl, iFrameBuffer, windowRect.Size()); |
|
1940 } |
|
1941 // Upscaling |
|
1942 else if (iScaler) |
|
1943 { |
|
1944 iFrameBuffer->LockHeap(); |
|
1945 TUint32* pixelData = iFrameBuffer->DataAddress(); |
|
1946 |
|
1947 // Scale the framebuffer content. |
|
1948 CFbsBitmap* map = iScaler->Process( |
|
1949 iFrameBuffer->DisplayMode(), |
|
1950 pixelData, |
|
1951 iContentSize.iWidth, |
|
1952 iContentSize.iHeight, |
|
1953 iFrameBuffer->SizeInPixels().iWidth - iContentSize.iWidth, |
|
1954 iViewRect.Width(), |
|
1955 iViewRect.Height()); |
|
1956 |
|
1957 iFrameBuffer->UnlockHeap(); |
|
1958 |
|
1959 if (map) |
|
1960 { |
|
1961 DEBUG("DrawDirect - Upscaling - BitBlt - map ok"); |
|
1962 iDirectGc->BitBlt(windowRect.iTl, map, windowRect.Size()); |
|
1963 } |
|
1964 else |
|
1965 { |
|
1966 DEBUG("DrawDirect - Upscaling - DrawBitmap - no map"); |
|
1967 iDirectGc->DrawBitmap(windowRect, iFrameBuffer, iContentSize); |
|
1968 } |
|
1969 } |
|
1970 |
|
1971 if (UpdateRequired()) |
|
1972 { |
|
1973 windowRect.Move(PositionRelativeToScreen()); |
|
1974 windowRect.Intersection(visibleRegion.RectangleList()[0]); |
|
1975 |
|
1976 // Direct screen drawing does not show up on some devices unless the |
|
1977 // screen device Update() method is called. |
|
1978 iUpdateRegion.Clear(); |
|
1979 iUpdateRegion.AddRect(windowRect); |
|
1980 iDirectAccess->ScreenDevice()->Update(iUpdateRegion); |
|
1981 } |
|
1982 |
|
1983 DEBUG("- CMIDCanvas::DrawDirect"); |
|
1984 } |
|
1985 #endif //CANVAS_DIRECT_ACCESS |
|
1986 |
|
1987 |
|
1988 // --------------------------------------------------------------------------- |
|
1989 // From class CCoeControl. |
|
1990 // CMIDCanvas::HandleResourceChange |
|
1991 // Resource change handling. |
|
1992 // --------------------------------------------------------------------------- |
|
1993 // |
|
1994 void CMIDCanvas::HandleResourceChange(TInt aType) |
|
1995 { |
|
1996 if (aType == KEikInputLanguageChange) |
|
1997 { |
|
1998 if ((iFocusedComponent != KComponentFocusedNone) && |
|
1999 (iFocusedComponent < iCustomComponents.Count())) |
|
2000 { |
|
2001 iCustomComponents[iFocusedComponent]-> |
|
2002 CustomComponentControl(KComponentMainControl)-> |
|
2003 HandleResourceChange(aType); |
|
2004 } |
|
2005 } |
|
2006 if (aType == KEikDynamicLayoutVariantSwitch) |
|
2007 { |
|
2008 // If orientation change is done, |
|
2009 // then we have to inform all components about it. |
|
2010 if (iFocusedComponent != KComponentFocusedNone && |
|
2011 iFullScreen) |
|
2012 { |
|
2013 for (int i = 0; i < iCustomComponents.Count(); i++) |
|
2014 { |
|
2015 iCustomComponents[i]->HandleResolutionChange(); |
|
2016 } |
|
2017 } |
|
2018 } |
|
2019 else if ((aType == KEikMessageUnfadeWindows) || |
|
2020 (aType == KEikMessageFadeAllWindows)) |
|
2021 { |
|
2022 iLastFadeMessage = aType; |
|
2023 } |
|
2024 else if ((aType == KEikMessageWindowsFadeChange) && |
|
2025 ((iLastFadeMessage == KEikMessageUnfadeWindows) || |
|
2026 (iLastFadeMessage == KEikMessageFadeAllWindows))) |
|
2027 { |
|
2028 TInt contentsCount(iDirectContents.Count()); |
|
2029 |
|
2030 switch (iLastFadeMessage) |
|
2031 { |
|
2032 case KEikMessageUnfadeWindows: |
|
2033 iRestoreContentWhenUnfaded = EFalse; |
|
2034 |
|
2035 #ifdef CANVAS_DIRECT_ACCESS |
|
2036 ResumeDirectAccess(); |
|
2037 #endif // CANVAS_DIRECT_ACCESS |
|
2038 |
|
2039 for (TInt j = 0; j < contentsCount; j++) |
|
2040 { |
|
2041 iDirectContents[j]->MdcContainerVisibilityChanged(ETrue); |
|
2042 } |
|
2043 break; |
|
2044 |
|
2045 case KEikMessageFadeAllWindows: |
|
2046 iRestoreContentWhenUnfaded = ETrue; |
|
2047 |
|
2048 #ifdef CANVAS_DIRECT_ACCESS |
|
2049 PauseDirectAccess(); |
|
2050 #endif // CANVAS_DIRECT_ACCESS |
|
2051 |
|
2052 for (TInt j = 0; j < contentsCount; j++) |
|
2053 { |
|
2054 iDirectContents[j]->MdcContainerVisibilityChanged(EFalse); |
|
2055 } |
|
2056 break; |
|
2057 } |
|
2058 iLastFadeMessage = 0; |
|
2059 } |
|
2060 } |
|
2061 |
|
2062 #ifdef RD_SCALABLE_UI_V2 |
|
2063 // --------------------------------------------------------------------------- |
|
2064 // CMIDCanvas::HandlePointerEventInControlsL |
|
2065 // Pointer events handling in controls. |
|
2066 // --------------------------------------------------------------------------- |
|
2067 // |
|
2068 TBool CMIDCanvas::HandlePointerEventInControlsL( |
|
2069 const TPointerEvent& aPointerEvent) |
|
2070 { |
|
2071 TBool inControl = EFalse; |
|
2072 |
|
2073 switch (aPointerEvent.iType) |
|
2074 { |
|
2075 case TPointerEvent::EButton1Down: |
|
2076 case TPointerEvent::EButton2Down: |
|
2077 case TPointerEvent::EButton3Down: |
|
2078 // Pointer pressed |
|
2079 if ((iFocusedComponent > KComponentFocusedNone)&& |
|
2080 (iFocusedComponent < iCustomComponents.Count()) && |
|
2081 (PointerEventInControl(iCustomComponents[iFocusedComponent], |
|
2082 aPointerEvent.iPosition))) |
|
2083 { |
|
2084 // Store the control for receiving pointer events until release |
|
2085 iPressedComponent = iCustomComponents[iFocusedComponent]; |
|
2086 // Pass the pointer event |
|
2087 iPressedComponent->CustomComponentControl |
|
2088 (KComponentMainControl)->HandlePointerEventL(aPointerEvent); |
|
2089 inControl = ETrue; |
|
2090 } |
|
2091 break; |
|
2092 case TPointerEvent::EButton1Up: |
|
2093 case TPointerEvent::EButton2Up: |
|
2094 case TPointerEvent::EButton3Up: |
|
2095 // Pointer released |
|
2096 if ((iPressedComponent) && (PointerEventInControl(iPressedComponent, |
|
2097 aPointerEvent.iPosition))) |
|
2098 { |
|
2099 // Pass the pointer event |
|
2100 iPressedComponent->CustomComponentControl |
|
2101 (KComponentMainControl)->HandlePointerEventL(aPointerEvent); |
|
2102 iPressedComponent = NULL; |
|
2103 inControl = ETrue; |
|
2104 } |
|
2105 break; |
|
2106 case TPointerEvent::EDrag: |
|
2107 if (iPressedComponent) |
|
2108 { |
|
2109 iPressedComponent->ProcessPointerEventL(aPointerEvent); |
|
2110 inControl = ETrue; |
|
2111 } |
|
2112 break; |
|
2113 default: |
|
2114 break; |
|
2115 } |
|
2116 return inControl; |
|
2117 } |
|
2118 |
|
2119 // --------------------------------------------------------------------------- |
|
2120 // CMIDCanvas::PointerEventInControl |
|
2121 // Pointer events checking. |
|
2122 // --------------------------------------------------------------------------- |
|
2123 // |
|
2124 TBool CMIDCanvas::PointerEventInControl(MMIDCustomComponent* aControl, |
|
2125 TPoint aPoint) |
|
2126 { |
|
2127 TBool inControl = EFalse; |
|
2128 TInt compoundCount = aControl->CustomComponentControlCount(); |
|
2129 for (int j = 0; j < compoundCount; j++) |
|
2130 { |
|
2131 // Check if the pointer event position is in visible control's |
|
2132 // area. |
|
2133 if (aControl->CustomComponentControl(j)->IsVisible()) |
|
2134 { |
|
2135 inControl |= aControl->CustomComponentControl(j)-> |
|
2136 Rect().Contains(aPoint); |
|
2137 } |
|
2138 } |
|
2139 return inControl; |
|
2140 } |
|
2141 |
|
2142 // --------------------------------------------------------------------------- |
|
2143 // From class CCoeControl. |
|
2144 // CMIDCanvas::HandlePointerEventL |
|
2145 // Pointer events handling. |
|
2146 // --------------------------------------------------------------------------- |
|
2147 // |
|
2148 void CMIDCanvas::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
2149 { |
|
2150 if (AknLayoutUtils::PenEnabled()) |
|
2151 { |
|
2152 TPoint point = aPointerEvent.iPosition; |
|
2153 TInt count = iCustomComponents.Count(); |
|
2154 TBool consumed = EFalse; |
|
2155 |
|
2156 // Long tap not allowed in full screen mode. |
|
2157 if (!iFullScreen) |
|
2158 { |
|
2159 consumed = iDisplayable->TryDetectLongTapL(aPointerEvent); |
|
2160 } |
|
2161 |
|
2162 if (!consumed && (iFocusedComponent != KComponentFocusedNone) && |
|
2163 (iCustomComponents[iFocusedComponent]->IsTouchEnabled())) |
|
2164 { |
|
2165 consumed = HandlePointerEventInControlsL(aPointerEvent); |
|
2166 } |
|
2167 |
|
2168 if (!consumed) |
|
2169 { |
|
2170 // Points are counted from 0 to width - 1, resp. height -1, |
|
2171 // so we compute maxima for points coordinates based |
|
2172 // on native view size and java canvas size. |
|
2173 TSize nativeMaxCoords = iViewRect.Size() - TSize(1, 1); |
|
2174 TSize javaMaxCoords = iContentSize - TSize(1, 1); |
|
2175 |
|
2176 // Transform point to content coordinates. |
|
2177 // |
|
2178 // iViewRect.iTl -> (0, 0) |
|
2179 // iViewRect.iBr - TSize(1, 1) -> (iContentSize.iWidth - 1, |
|
2180 // iContentSize.iHeight - 1) |
|
2181 point -= iViewRect.iTl; |
|
2182 |
|
2183 if (javaMaxCoords != nativeMaxCoords) |
|
2184 { |
|
2185 point.iX = (point.iX * javaMaxCoords.iWidth) / |
|
2186 nativeMaxCoords.iWidth; |
|
2187 point.iY = (point.iY * javaMaxCoords.iHeight) / |
|
2188 nativeMaxCoords.iHeight; |
|
2189 } |
|
2190 |
|
2191 TEventType type; |
|
2192 TTime now; |
|
2193 |
|
2194 switch (aPointerEvent.iType) |
|
2195 { |
|
2196 case TPointerEvent::EButton1Down: |
|
2197 case TPointerEvent::EButton2Down: |
|
2198 case TPointerEvent::EButton3Down: |
|
2199 type = EPointerPressed; |
|
2200 iPointerPressedCoordinates = TPoint(point.iX, point.iY); |
|
2201 if (point.iX >= 0 && point.iX <= javaMaxCoords.iWidth && |
|
2202 point.iY >= 0 && point.iY <= javaMaxCoords.iHeight) |
|
2203 { |
|
2204 // Translated point is inside of java canvas |
|
2205 iDragEventsStartedInside = ETrue; |
|
2206 } |
|
2207 break; |
|
2208 case TPointerEvent::EButton1Up: |
|
2209 case TPointerEvent::EButton2Up: |
|
2210 case TPointerEvent::EButton3Up: |
|
2211 type = EPointerReleased; |
|
2212 if (iPointerEventSuppressionOngoing) |
|
2213 { |
|
2214 point.iX = iPointerPressedCoordinates.iX; |
|
2215 point.iY = iPointerPressedCoordinates.iY; |
|
2216 } |
|
2217 break; |
|
2218 case TPointerEvent::EDrag: |
|
2219 type = EPointerDragged; |
|
2220 // If pointerEventSuppressor time is set to 0 don't do any |
|
2221 // drag event filtering. (default time here is 500ms and it |
|
2222 // can be changed with JAD parameter |
|
2223 // Nokia-MIDlet-Tap-Detection-Options) |
|
2224 if (iPESTimeInMilliseconds != 0) |
|
2225 { |
|
2226 now.HomeTime(); |
|
2227 if (now.MicroSecondsFrom(iPreviousDragTimeStamp) < |
|
2228 KAllowedTimeBetweenDragEvents) |
|
2229 { |
|
2230 // Ignore drag event because time between drags is |
|
2231 // shorter than allowed interval. |
|
2232 return; |
|
2233 } |
|
2234 else |
|
2235 { |
|
2236 iPreviousDragTimeStamp = now; |
|
2237 } |
|
2238 } |
|
2239 break; |
|
2240 default: |
|
2241 type = ENoType; |
|
2242 } |
|
2243 |
|
2244 // Pointer Event Suppressor for helping tap detection with finger |
|
2245 // usage |
|
2246 if (iPointerEventSuppressor->SuppressPointerEvent(aPointerEvent)) |
|
2247 { |
|
2248 iPointerEventSuppressionOngoing = ETrue; |
|
2249 return; |
|
2250 } |
|
2251 else |
|
2252 { |
|
2253 iPointerEventSuppressionOngoing = EFalse; |
|
2254 } |
|
2255 |
|
2256 // To have the cursor on focused control |
|
2257 if (iFocusedComponent != KComponentFocusedNone) |
|
2258 { |
|
2259 iCustomComponents[iFocusedComponent]-> |
|
2260 CustomComponentControl(KComponentMainControl)-> |
|
2261 SetFocus(ETrue); |
|
2262 } |
|
2263 |
|
2264 // Ignore pointer events outside of Canvas content. |
|
2265 if (!iDragEventsStartedInside) |
|
2266 { |
|
2267 return; |
|
2268 } |
|
2269 |
|
2270 PostEvent(type, point.iX, point.iY); |
|
2271 |
|
2272 // Flag is reset, if release event happened. However reset |
|
2273 // has to be done after event is sent to java, because of possible |
|
2274 // dragging, which started inside of canvas. In this case |
|
2275 // also release event should be delivered to java |
|
2276 if (type == EPointerReleased) |
|
2277 { |
|
2278 iDragEventsStartedInside = EFalse; |
|
2279 } |
|
2280 } |
|
2281 } |
|
2282 } |
|
2283 #endif // RD_SCALABLE_UI_V2 |
|
2284 |
|
2285 |
|
2286 // --------------------------------------------------------------------------- |
|
2287 // From class CCoeControl. |
|
2288 // CMIDCanvas::FocusChanged |
|
2289 // Change of focus. |
|
2290 // --------------------------------------------------------------------------- |
|
2291 // |
|
2292 void CMIDCanvas::FocusChanged(TDrawNow /* aDrawNow */) |
|
2293 { |
|
2294 DEBUG("+ CMIDCanvas::FocusChanged"); |
|
2295 |
|
2296 iEnv.ResetKeys(); |
|
2297 iGameKeyState = 0; |
|
2298 iGameKeyLatch = 0; |
|
2299 |
|
2300 TInt contentsCount(iDirectContents.Count()); |
|
2301 |
|
2302 if (IsFocused()) |
|
2303 { |
|
2304 #ifdef CANVAS_DIRECT_ACCESS |
|
2305 ResumeDirectAccess(); |
|
2306 #endif // CANVAS_DIRECT_ACCESS |
|
2307 |
|
2308 if (!iRestoreContentWhenUnfaded) |
|
2309 { |
|
2310 for (TInt j = 0; j < contentsCount; j++) |
|
2311 { |
|
2312 iDirectContents[j]->MdcContainerVisibilityChanged(ETrue); |
|
2313 } |
|
2314 } |
|
2315 |
|
2316 // To have cursor on focused control. |
|
2317 if ((iFocusedComponent != KComponentFocusedNone) && |
|
2318 (iFocusedComponent < iCustomComponents.Count())) |
|
2319 { |
|
2320 iCustomComponents[iFocusedComponent]-> |
|
2321 CustomComponentControl(KComponentMainControl)-> |
|
2322 SetFocus(ETrue); |
|
2323 } |
|
2324 // Redraw the canvas after unfading |
|
2325 DrawDeferred(); |
|
2326 |
|
2327 #ifdef RD_JAVA_NGA_ENABLED |
|
2328 // To avoid situation when Canvas is redrawn but black area remains |
|
2329 if (iAlfCompositionPixelSource) |
|
2330 { |
|
2331 TRAPD(err, ActivatePixelSourceL()); |
|
2332 if (err != KErrNone) |
|
2333 { |
|
2334 DEBUG_INT("CMIDCanvas::FocusChanged - ActivatePixelSourceL error %d", err); |
|
2335 } |
|
2336 } |
|
2337 #endif // RD_JAVA_NGA_ENABLED |
|
2338 |
|
2339 } |
|
2340 else |
|
2341 { |
|
2342 #ifdef CANVAS_DIRECT_ACCESS |
|
2343 PauseDirectAccess(); |
|
2344 #endif // CANVAS_DIRECT_ACCESS |
|
2345 |
|
2346 if (!iRestoreContentWhenUnfaded) |
|
2347 { |
|
2348 for (TInt j = 0; j < contentsCount; j++) |
|
2349 { |
|
2350 iDirectContents[j]->MdcContainerVisibilityChanged(EFalse); |
|
2351 } |
|
2352 } |
|
2353 |
|
2354 // To cursor on focused control. |
|
2355 if ((iFocusedComponent != KComponentFocusedNone) && |
|
2356 (iFocusedComponent < iCustomComponents.Count())) |
|
2357 { |
|
2358 iCustomComponents[iFocusedComponent]-> |
|
2359 CustomComponentControl(KComponentMainControl)-> |
|
2360 SetFocus(EFalse); |
|
2361 } |
|
2362 // Repaint to ensure that fading will be displayed correctly for Alert |
|
2363 // or PopupTextBox when DSA is paused. |
|
2364 DrawDeferred(); |
|
2365 } |
|
2366 |
|
2367 DEBUG("- CMIDCanvas::FocusChanged"); |
|
2368 } |
|
2369 |
|
2370 |
|
2371 // --------------------------------------------------------------------------- |
|
2372 // From class CCoeControl. |
|
2373 // CMIDCanvas::SizeChanged |
|
2374 // Change of size. |
|
2375 // --------------------------------------------------------------------------- |
|
2376 // |
|
2377 void CMIDCanvas::SizeChanged() |
|
2378 { |
|
2379 DEBUG("+ CMIDCanvas::SizeChanged"); |
|
2380 |
|
2381 TSize controlSize = Size(); |
|
2382 |
|
2383 // Position in screen co-ordinates changes when mode (full/normal) is |
|
2384 // changed. |
|
2385 iPositionRelativeToScreen = PositionRelativeToScreen(); |
|
2386 TRect contentBounds = TRect(iPositionRelativeToScreen, controlSize); |
|
2387 |
|
2388 // If JAD attribute Nokia-MIDlet-Original-Display-Size for graphics |
|
2389 // scaling is defined, the iContentSize must follow it. |
|
2390 TSize orientedOrgMIDletScrSize(OrientedOrgMIDletScrSize()); |
|
2391 |
|
2392 if (contentBounds != iOldContentBounds) |
|
2393 { |
|
2394 iOldContentBounds = contentBounds; |
|
2395 |
|
2396 TSize contentSize; |
|
2397 |
|
2398 if (iFullScreen && (orientedOrgMIDletScrSize != controlSize)) |
|
2399 { |
|
2400 contentSize = orientedOrgMIDletScrSize; |
|
2401 } |
|
2402 |
|
2403 if (contentSize == KZeroSize) |
|
2404 { |
|
2405 contentSize = controlSize; |
|
2406 } |
|
2407 |
|
2408 if ((contentSize != iContentSize) || iScalingOn) |
|
2409 { |
|
2410 iContentSize = contentSize; |
|
2411 |
|
2412 #ifdef RD_JAVA_NGA_ENABLED |
|
2413 HandleSizeChanged(); |
|
2414 #endif // RD_JAVA_NGA_ENABLED |
|
2415 PostEvent(ESizeChanged, iContentSize.iWidth, iContentSize.iHeight); |
|
2416 } |
|
2417 |
|
2418 #ifdef CANVAS_DIRECT_ACCESS |
|
2419 // Stop direct screen access to avoid restarting |
|
2420 // of direct content DSA during MdcContentBoundsChanged. |
|
2421 // DSA is resumed by Layout method. |
|
2422 StopDirectAccess(); |
|
2423 #endif // CANVAS_DIRECT_ACCESS |
|
2424 |
|
2425 // Inform all listeners. |
|
2426 TInt contentsCount(iDirectContents.Count()); |
|
2427 |
|
2428 for (TInt j = 0; j < contentsCount; j++) |
|
2429 { |
|
2430 iDirectContents[j]->MdcContentBoundsChanged(contentBounds); |
|
2431 iDirectContents[j]->MdcContainerWindowRectChanged(MdcContainerWindowRect()); |
|
2432 } |
|
2433 |
|
2434 // We cannot determine whether the control size actually did change or |
|
2435 // not, so we have to do the layout no matter what. |
|
2436 Layout(); |
|
2437 } |
|
2438 DEBUG("- CMIDCanvas::SizeChanged"); |
|
2439 } |
|
2440 |
|
2441 |
|
2442 // --------------------------------------------------------------------------- |
|
2443 // From class CCoeControl. |
|
2444 // CMIDCanvas::PositionChanged |
|
2445 // Change of position. |
|
2446 // --------------------------------------------------------------------------- |
|
2447 // |
|
2448 void CMIDCanvas::PositionChanged() |
|
2449 { |
|
2450 Layout(); |
|
2451 } |
|
2452 |
|
2453 #ifdef RD_JAVA_NGA_ENABLED |
|
2454 // --------------------------------------------------------------------------- |
|
2455 // From class CCoeControl. |
|
2456 // CMIDCanvas::Draw |
|
2457 // Drawing. |
|
2458 // --------------------------------------------------------------------------- |
|
2459 // |
|
2460 void CMIDCanvas::Draw(const TRect& aRect) const |
|
2461 { |
|
2462 if (!iStartUpTraceDone) |
|
2463 { |
|
2464 java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw starts", -1, -1); |
|
2465 } |
|
2466 DEBUG("CMIDCanvas::Draw ++"); |
|
2467 |
|
2468 // While changing the orientation method DrawWindow() not called, |
|
2469 // variable iWndUpdate is set to True. If iWndUpdate is True |
|
2470 // DrawWindow() is called from method Update() |
|
2471 // This is needed to avoid artifacting after orientation switch. |
|
2472 TBool landscape = Layout_Meta_Data::IsLandscapeOrientation(); |
|
2473 |
|
2474 if (iLandscape != landscape) |
|
2475 { |
|
2476 iLandscape = landscape; |
|
2477 iWndUpdate = ETrue; |
|
2478 } |
|
2479 else |
|
2480 { |
|
2481 // iRestoreContentWhenUnfaded is used when Canvas should be faded |
|
2482 // DrawWindow need to be called, otherwise Canvas will be unfaded |
|
2483 // Sometimes iRestoreContentWhenUnfaded is not set yet and Canvas |
|
2484 // already lost focus, then IsFocused is used |
|
2485 if (iDirectContents.Count() > 0 || iRestoreContentWhenUnfaded || !IsFocused()) |
|
2486 { |
|
2487 DrawWindow(aRect); |
|
2488 } |
|
2489 else if (iAlfCompositionPixelSource) |
|
2490 { |
|
2491 CMIDCanvas* myself = const_cast<CMIDCanvas*>(this); |
|
2492 TRAP_IGNORE(myself->ActivatePixelSourceL()); |
|
2493 } |
|
2494 iWndUpdate = EFalse; |
|
2495 } |
|
2496 |
|
2497 if (!iStartUpTraceDone) |
|
2498 { |
|
2499 java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw ends", -1, -1); |
|
2500 iStartUpTraceDone = ETrue; |
|
2501 } |
|
2502 DEBUG("CMIDCanvas::Draw --"); |
|
2503 } |
|
2504 #else // !RD_JAVA_NGA_ENABLED |
|
2505 |
|
2506 // --------------------------------------------------------------------------- |
|
2507 // From class CCoeControl. |
|
2508 // CMIDCanvas::Draw |
|
2509 // Drawing. |
|
2510 // --------------------------------------------------------------------------- |
|
2511 // |
|
2512 void CMIDCanvas::Draw(const TRect& aRect) const |
|
2513 { |
|
2514 if (!iStartUpTraceDone) |
|
2515 { |
|
2516 java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw starts", -1, -1); |
|
2517 } |
|
2518 DEBUG("+ CMIDCanvas::Draw"); |
|
2519 |
|
2520 #ifdef CANVAS_DOUBLE_BUFFER |
|
2521 ASSERT(iFrameBuffer); |
|
2522 #endif // CANVAS_DOUBLE_BUFFER |
|
2523 |
|
2524 #ifdef CANVAS_ASYNC_PAINT |
|
2525 TRect rect(aRect); |
|
2526 |
|
2527 rect.Intersection(iViewRect); |
|
2528 rect.Move(-iViewRect.iTl); |
|
2529 |
|
2530 TSize size(rect.Size()); |
|
2531 |
|
2532 TInt posPacked = (rect.iTl.iX << 16) | (rect.iTl.iY); |
|
2533 TInt sizePacked = (size.iWidth << 16) | (size.iHeight); |
|
2534 |
|
2535 PostEvent(EPaint, posPacked, sizePacked); |
|
2536 #else |
|
2537 #ifdef CANVAS_DOUBLE_BUFFER |
|
2538 |
|
2539 // While changing the orientation method DrawWindow() not called, |
|
2540 // variable iWndUpdate is set to True. If iWndUpdate is True |
|
2541 // DrawWindow() is called from method Update() |
|
2542 // This is needed to avoid artifacting after orientation switch. |
|
2543 TBool landscape = Layout_Meta_Data::IsLandscapeOrientation(); |
|
2544 |
|
2545 if (iLandscape != landscape) |
|
2546 { |
|
2547 iLandscape = landscape; |
|
2548 iWndUpdate = ETrue; |
|
2549 } |
|
2550 else |
|
2551 { |
|
2552 #ifdef CANVAS_DIRECT_ACCESS |
|
2553 // Check if DSA is ready and not used by some other client. |
|
2554 if (iDirectGc && !iDirectContents.Count() && !DirectPaused()) |
|
2555 { |
|
2556 DrawDirect(aRect); // Draw directly to screen. |
|
2557 } |
|
2558 else |
|
2559 { |
|
2560 #endif // CANVAS_DIRECT_ACCESS |
|
2561 DrawWindow(aRect); // Bitblt via window server. |
|
2562 #ifdef CANVAS_DIRECT_ACCESS |
|
2563 } |
|
2564 #endif // CANVAS_DIRECT_ACCESS |
|
2565 |
|
2566 iWndUpdate = EFalse; |
|
2567 } |
|
2568 #endif // CANVAS_DOUBLE_BUFFER |
|
2569 #endif // CANVAS_ASYNC_PAINT |
|
2570 |
|
2571 if (!iStartUpTraceDone) |
|
2572 { |
|
2573 java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw ends", -1, -1); |
|
2574 iStartUpTraceDone = ETrue; |
|
2575 } |
|
2576 DEBUG("- CMIDCanvas::Draw"); |
|
2577 } |
|
2578 #endif // RD_JAVA_NGA_ENABLED |
|
2579 |
|
2580 // --------------------------------------------------------------------------- |
|
2581 // CMIDCanvas::CMIDCanvas |
|
2582 // C++ constructor. |
|
2583 // --------------------------------------------------------------------------- |
|
2584 // |
|
2585 CMIDCanvas::CMIDCanvas( |
|
2586 MMIDEnv& aEnv, |
|
2587 MMIDComponent::TType aComponentType, |
|
2588 #ifdef CANVAS_DIRECT_ACCESS |
|
2589 TBool /*aUpdateRequired*/ |
|
2590 #else |
|
2591 TBool aUpdateRequired |
|
2592 #endif // CANVAS_DIRECT_ACCESS |
|
2593 ) : |
|
2594 CCoeControl() |
|
2595 ,iEnv(aEnv) |
|
2596 #ifdef CANVAS_DOUBLE_BUFFER |
|
2597 ,iFrameBuffer(NULL) |
|
2598 #endif // CANVAS_DOUBLE_BUFFER |
|
2599 ,iIsGameCanvas(( |
|
2600 aComponentType == MMIDComponent::EGameCanvas ? ETrue : EFalse)) |
|
2601 ,iFlags(EPostKeyEvents) |
|
2602 ,iFullScreen(EFalse) |
|
2603 ,iScalingOn(EFalse) |
|
2604 ,iS60SelectionKeyCompatibility(EFalse) |
|
2605 ,iRestoreContentWhenUnfaded(EFalse) |
|
2606 ,iLastFadeMessage(0) |
|
2607 #ifdef CANVAS_DIRECT_ACCESS |
|
2608 ,iDcDsaToStart(EFalse) |
|
2609 #endif // CANVAS_DIRECT_ACCESS |
|
2610 ,iDragEventsStartedInside(EFalse) |
|
2611 { |
|
2612 DEBUG("+ CMIDCanvas::CMIDCanvas - EDirectEnabled"); |
|
2613 |
|
2614 #ifdef CANVAS_DIRECT_ACCESS |
|
2615 iFlags |= (EDirectPaused | EDirectEnabled | EUpdateRequired); |
|
2616 #else |
|
2617 |
|
2618 #if defined( __WINS__ ) || defined( __WINSCW__ ) |
|
2619 aUpdateRequired = ETrue; |
|
2620 #endif |
|
2621 |
|
2622 if (aUpdateRequired) |
|
2623 { |
|
2624 iFlags |= EUpdateRequired; |
|
2625 } |
|
2626 #endif // CANVAS_DIRECT_ACCESS |
|
2627 |
|
2628 //Default values for PointerEventSuppressor |
|
2629 iPESPointerMovementInTwips = CMIDUIManager::EPESPointerMovementInTwips; |
|
2630 iPESTimeInMilliseconds = CMIDUIManager:: EPESTimeInMilliseconds; |
|
2631 |
|
2632 DEBUG("- CMIDCanvas::CMIDCanvas"); |
|
2633 } |
|
2634 |
|
2635 |
|
2636 // --------------------------------------------------------------------------- |
|
2637 // CMIDCanvas::ConstructL |
|
2638 // Symbian 2nd phase constructor can leave. |
|
2639 // --------------------------------------------------------------------------- |
|
2640 // |
|
2641 void CMIDCanvas::ConstructL(CCoeControl& aWindow) |
|
2642 { |
|
2643 SetContainerWindowL(aWindow); |
|
2644 |
|
2645 iFocusedComponent = KComponentFocusedNone; |
|
2646 iPressedComponent = NULL; |
|
2647 iOrgMIDletScrSize = TSize(); |
|
2648 iTargetMIDletScrSize = TSize(); |
|
2649 |
|
2650 #ifdef CANVAS_DOUBLE_BUFFER |
|
2651 // Create a framebuffer large enough for full screen mode. |
|
2652 // In normal mode we will waste the border pixels. This may be offset in |
|
2653 // future by sharing the framebuffer between displayables. |
|
2654 // |
|
2655 // Allow dynamic changing of screen modes find the |
|
2656 // largest available screen size to allocate a frame buffer big enough to |
|
2657 // deal with all screen modes; |
|
2658 CWsScreenDevice* device = ControlEnv()->ScreenDevice(); |
|
2659 TInt noModes = device->NumScreenModes(); |
|
2660 TPixelsAndRotation pixelAndRot; |
|
2661 TSize frameBufferSize(0, 0); |
|
2662 |
|
2663 for (TInt ii=0 ; ii < noModes; ++ii) |
|
2664 { |
|
2665 device->GetScreenModeSizeAndRotation(ii, pixelAndRot); |
|
2666 |
|
2667 if (frameBufferSize.iHeight < pixelAndRot.iPixelSize.iHeight) |
|
2668 { |
|
2669 frameBufferSize.iHeight = pixelAndRot.iPixelSize.iHeight; |
|
2670 } |
|
2671 |
|
2672 if (frameBufferSize.iWidth < pixelAndRot.iPixelSize.iWidth) |
|
2673 { |
|
2674 frameBufferSize.iWidth = pixelAndRot.iPixelSize.iWidth; |
|
2675 } |
|
2676 } |
|
2677 |
|
2678 DEBUG_INT2("Canvas FrameBuffer Size: Width: %d, Height %d", |
|
2679 frameBufferSize.iWidth, frameBufferSize.iHeight); |
|
2680 |
|
2681 CreateFrameBufferL(frameBufferSize); |
|
2682 |
|
2683 if (iFrameBuffer) |
|
2684 { |
|
2685 iFrameDevice = CFbsBitmapDevice::NewL(iFrameBuffer); |
|
2686 User::LeaveIfError(iFrameDevice->CreateContext(iFrameContext)); |
|
2687 } |
|
2688 |
|
2689 // Set iLandscape set as True according to landscape orientation mode |
|
2690 // and initialize iWndUpdat. iWndUpdat variable notify us, when |
|
2691 // orienation was changed |
|
2692 iLandscape = Layout_Meta_Data::IsLandscapeOrientation(); |
|
2693 iWndUpdate = EFalse; |
|
2694 |
|
2695 #endif // CANVAS_DOUBLE_BUFFER |
|
2696 |
|
2697 SetScalingFactors(); |
|
2698 |
|
2699 if (iScalingOn) |
|
2700 { |
|
2701 // We need iScaler only when scaling is on. |
|
2702 iScaler = iDisplayable->GetUIManager()->OpenScalerL(); |
|
2703 } |
|
2704 |
|
2705 #ifdef CANVAS_DIRECT_ACCESS |
|
2706 ResumeDirectAccess(); |
|
2707 #endif // CANVAS_DIRECT_ACCESS |
|
2708 |
|
2709 if (IsNetworkIndicatorEnabledL()) |
|
2710 { |
|
2711 iNetworkIndicator = CMIDNetworkIndicator::NewL(this); |
|
2712 |
|
2713 // Initialize and set active CallIndicator to receive notification |
|
2714 // when voiceline status changes. |
|
2715 iCallIndicator = CMIDCallIndicator::NewL(iNetworkIndicator); |
|
2716 iCallIndicator->SetActiveLocal(); |
|
2717 } |
|
2718 |
|
2719 iKeyDecoder = iDisplayable->GetUIManager()->OpenKeyDecoderL(); |
|
2720 ASSERT(iKeyDecoder); |
|
2721 |
|
2722 // Canvas listens Media key events if CMIDRemConObserver is initialized |
|
2723 // and media keys keys are enabled. |
|
2724 iRemConObserver = iKeyDecoder->GetRemConObserver(); |
|
2725 if (iRemConObserver && iKeyDecoder->MediaKeysEnabled()) |
|
2726 { |
|
2727 iRemConObserver->AddMediaKeysListenerL(this); |
|
2728 } |
|
2729 |
|
2730 // Set S60 Selection Key Compatibility to provide MSK key events to |
|
2731 // canvas. |
|
2732 iS60SelectionKeyCompatibility = iEnv.MidletAttributeIsSetToVal( |
|
2733 LcduiMidletAttributes::KAttribS60SelectionKeyCompatibility, |
|
2734 LcduiMidletAttributeValues::KTrueValue); |
|
2735 |
|
2736 if (iDisplayable) |
|
2737 { |
|
2738 iDisplayable->SetS60SelectionKeyCompatibility( |
|
2739 iS60SelectionKeyCompatibility); |
|
2740 } |
|
2741 |
|
2742 #ifdef RD_TACTILE_FEEDBACK |
|
2743 // Create a CMIDTactileFeedbackExtension in case tactile feedback is |
|
2744 // supported. |
|
2745 iTactileFeedback = new(ELeave) CMIDTactileFeedbackExtension(this, 1); |
|
2746 #endif // RD_TACTILE_FEEDBACK |
|
2747 |
|
2748 //Create PointerEventSuppressor with default values or JAD parameter defined values |
|
2749 iPointerEventSuppressor = CAknPointerEventSuppressor::NewL(); |
|
2750 TInt pointerMovementInPixels = |
|
2751 ControlEnv()->ScreenDevice()->HorizontalTwipsToPixels(iPESPointerMovementInTwips); |
|
2752 TSize suppressorValues = |
|
2753 iDisplayable->GetUIManager()->ReadPointerEventSuppressorValues(); |
|
2754 if (!(suppressorValues.iWidth == KPESErrorValue && |
|
2755 suppressorValues.iHeight == KPESErrorValue)) |
|
2756 { |
|
2757 iPESTimeInMilliseconds = suppressorValues.iHeight; |
|
2758 pointerMovementInPixels = |
|
2759 ControlEnv()->ScreenDevice()->HorizontalTwipsToPixels(suppressorValues.iWidth); |
|
2760 } |
|
2761 iPointerEventSuppressor->SetMaxTapDuration(iPESTimeInMilliseconds * 1000); |
|
2762 iPointerEventSuppressor->SetMaxTapMove(TSize(pointerMovementInPixels, |
|
2763 pointerMovementInPixels)); |
|
2764 |
|
2765 #ifdef RD_JAVA_NGA_ENABLED |
|
2766 iForeground = EFalse; |
|
2767 iEglDisplay = EGL_NO_DISPLAY; |
|
2768 iEglWindowSurface = EGL_NO_SURFACE; |
|
2769 iEglWindowSurfaceContext = EGL_NO_CONTEXT; |
|
2770 iEglPbufferSurface = EGL_NO_SURFACE; |
|
2771 iEglPbufferSurfaceContext = EGL_NO_CONTEXT; |
|
2772 iPbufferTexture = 0; |
|
2773 |
|
2774 i3DAccelerated = |
|
2775 iEnv.IsHardwareAcceleratedL(MMIDEnv::EHardware3D) > 0; |
|
2776 |
|
2777 InitPixelSourceL(); |
|
2778 #endif // RD_JAVA_NGA_ENABLED |
|
2779 } |
|
2780 |
|
2781 |
|
2782 // --------------------------------------------------------------------------- |
|
2783 // CMIDCanvas::SetContainerWindowL |
|
2784 // Set the container window. |
|
2785 // --------------------------------------------------------------------------- |
|
2786 // |
|
2787 void CMIDCanvas::SetContainerWindowL(const CCoeControl& aWindow) |
|
2788 { |
|
2789 #ifdef CANVAS_DIRECT_ACCESS |
|
2790 StopDirectAccess(); |
|
2791 |
|
2792 if (iDirectAccess) |
|
2793 { |
|
2794 delete iDirectAccess; |
|
2795 iDirectAccess = NULL; |
|
2796 } |
|
2797 #endif // CANVAS_DIRECT_ACCESS |
|
2798 |
|
2799 iDisplayable = (CMIDDisplayable*) &aWindow; |
|
2800 CCoeControl::SetContainerWindowL(aWindow); |
|
2801 Window().SetBackgroundColor(); |
|
2802 |
|
2803 #ifdef RD_SCALABLE_UI_V2 |
|
2804 Window().SetPointerGrab(ETrue); |
|
2805 #endif // RD_SCALABLE_UI_V2 |
|
2806 |
|
2807 #ifdef CANVAS_DIRECT_ACCESS |
|
2808 if (DirectEnabled()) |
|
2809 { |
|
2810 RWsSession& session = ControlEnv()->WsSession(); |
|
2811 CWsScreenDevice* device = ControlEnv()->ScreenDevice(); |
|
2812 |
|
2813 iDirectAccess = CDirectScreenAccess::NewL( |
|
2814 session, *device, *DrawableWindow(), *this); |
|
2815 } |
|
2816 #endif // CANVAS_DIRECT_ACCESS |
|
2817 |
|
2818 // Position in screen co-ordinates is first time available when container |
|
2819 // window is set. |
|
2820 iPositionRelativeToScreen = PositionRelativeToScreen(); |
|
2821 } |
|
2822 |
|
2823 |
|
2824 // --------------------------------------------------------------------------- |
|
2825 // CMIDCanvas::SendKeyEventToJavaSideL |
|
2826 // Send key event to Java side. |
|
2827 // --------------------------------------------------------------------------- |
|
2828 // |
|
2829 void CMIDCanvas::SendKeyEventToJavaSideL( |
|
2830 const TKeyEvent& aEvent, TEventCode aType) |
|
2831 { |
|
2832 DEBUG("+ CMIDCanvas::SendKeyEventToJavaSideL"); |
|
2833 TMIDKeyEvent event; |
|
2834 |
|
2835 // See if the key can be sent java side. |
|
2836 DEBUG_INT2("CMIDCanvas::PostKeyEvent - SOS code %d SOS type %d", |
|
2837 aEvent.iCode, |
|
2838 aType); |
|
2839 |
|
2840 // map key event data |
|
2841 TKeyEvent wsEvent = aEvent; |
|
2842 |
|
2843 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iCode = %d", aEvent.iCode); |
|
2844 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iModifiers = %d", aEvent.iModifiers); |
|
2845 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iRepeats = %d", aEvent.iRepeats); |
|
2846 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iScanCode = %d", aEvent.iScanCode); |
|
2847 |
|
2848 iEnv.MappingDataForKey(wsEvent, aType); |
|
2849 |
|
2850 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iCode = %d", aEvent.iCode); |
|
2851 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iModifiers = %d", aEvent.iModifiers); |
|
2852 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iRepeats = %d", aEvent.iRepeats); |
|
2853 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iScanCode = %d", aEvent.iScanCode); |
|
2854 |
|
2855 //See if the key can be sent java side. |
|
2856 if (iEnv.TranslateKeyL(event, wsEvent, aType)) |
|
2857 { |
|
2858 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - translated TMIDKeyEvent: iEvents = %d", event.iEvents); |
|
2859 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - translated TMIDKeyEvent: iKeyCode = %d", event.iKeyCode); |
|
2860 DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - translated TMIDKeyEvent: iRepeats = %d", event.iRepeats); |
|
2861 |
|
2862 ASSERT(iKeyDecoder); |
|
2863 |
|
2864 TInt gameAction = iKeyDecoder->GameAction(event.iKeyCode); |
|
2865 |
|
2866 if (0 != gameAction) |
|
2867 { |
|
2868 if (event.iEvents & TMIDKeyEvent::EPressed) |
|
2869 { |
|
2870 GamePress(gameAction); |
|
2871 } |
|
2872 |
|
2873 if (event.iEvents & TMIDKeyEvent::EReleased) |
|
2874 { |
|
2875 GameRelease(gameAction); |
|
2876 } |
|
2877 } |
|
2878 |
|
2879 if (PostKeyEvents() || (0 == gameAction)) |
|
2880 { |
|
2881 DEBUG_INT2( |
|
2882 "CMIDCanvas::PostKeyEvent - JAVA code %d JAVA type %d", |
|
2883 event.iKeyCode, |
|
2884 event.iEvents); |
|
2885 |
|
2886 // 9-way Navigation Support |
|
2887 // Send two arrow events generated when press diagonal direction |
|
2888 switch (event.iKeyCode) |
|
2889 { |
|
2890 //KeyLeftUpArrow |
|
2891 case EKeyLeftUpArrow: |
|
2892 { |
|
2893 TMIDKeyEvent pevent; |
|
2894 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyUpArrow); |
|
2895 pevent.iEvents = event.iEvents; |
|
2896 pevent.iRepeats = event.iRepeats; |
|
2897 iEnv.PostKeyEvent(*this, pevent); |
|
2898 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyLeftArrow); |
|
2899 pevent.iEvents = event.iEvents; |
|
2900 pevent.iRepeats = event.iRepeats; |
|
2901 iEnv.PostKeyEvent(*this, pevent); |
|
2902 break; |
|
2903 } |
|
2904 //KeyRightUpArrow |
|
2905 case EKeyRightUpArrow: |
|
2906 { |
|
2907 TMIDKeyEvent pevent; |
|
2908 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyUpArrow); |
|
2909 pevent.iEvents = event.iEvents; |
|
2910 pevent.iRepeats = event.iRepeats; |
|
2911 iEnv.PostKeyEvent(*this, pevent); |
|
2912 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyRightArrow); |
|
2913 pevent.iEvents = event.iEvents; |
|
2914 pevent.iRepeats = event.iRepeats; |
|
2915 iEnv.PostKeyEvent(*this, pevent); |
|
2916 break; |
|
2917 } |
|
2918 //KeyRightDownArrow |
|
2919 case EKeyRightDownArrow: |
|
2920 { |
|
2921 TMIDKeyEvent pevent; |
|
2922 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyDownArrow); |
|
2923 pevent.iEvents = event.iEvents; |
|
2924 pevent.iRepeats = event.iRepeats; |
|
2925 iEnv.PostKeyEvent(*this, pevent); |
|
2926 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyRightArrow); |
|
2927 pevent.iEvents = event.iEvents; |
|
2928 pevent.iRepeats = event.iRepeats; |
|
2929 iEnv.PostKeyEvent(*this, pevent); |
|
2930 break; |
|
2931 } |
|
2932 //KeyLeftDownArrow |
|
2933 case EKeyLeftDownArrow: |
|
2934 { |
|
2935 TMIDKeyEvent pevent; |
|
2936 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyDownArrow); |
|
2937 pevent.iEvents = event.iEvents; |
|
2938 pevent.iRepeats = event.iRepeats; |
|
2939 iEnv.PostKeyEvent(*this, pevent); |
|
2940 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyLeftArrow); |
|
2941 pevent.iEvents = event.iEvents; |
|
2942 pevent.iRepeats = event.iRepeats; |
|
2943 iEnv.PostKeyEvent(*this, pevent); |
|
2944 break; |
|
2945 } |
|
2946 default: |
|
2947 iEnv.PostKeyEvent(*this, event); |
|
2948 } |
|
2949 } |
|
2950 } |
|
2951 DEBUG("- CMIDCanvas::SendKeyEventToJavaSideL"); |
|
2952 } |
|
2953 |
|
2954 |
|
2955 #ifdef CANVAS_DOUBLE_BUFFER |
|
2956 // --------------------------------------------------------------------------- |
|
2957 // CMIDCanvas::CreateFrameBufferL |
|
2958 // Create frame buffer. |
|
2959 // --------------------------------------------------------------------------- |
|
2960 // |
|
2961 void CMIDCanvas::CreateFrameBufferL(const TSize& aSize) |
|
2962 { |
|
2963 DEBUG_INT2("+ CMIDCanvas::CreateFrameBufferL( %D, %D)", |
|
2964 aSize.iWidth, |
|
2965 aSize.iHeight); |
|
2966 |
|
2967 iFrameBuffer = iEnv.ReserveCanvasFrameBufferL((*this), aSize); |
|
2968 |
|
2969 DEBUG("- CMIDCanvas::CreateFrameBufferL"); |
|
2970 } |
|
2971 #endif // CANVAS_DOUBLE_BUFFER |
|
2972 |
|
2973 |
|
2974 #ifdef DEFER_BITBLT |
|
2975 // --------------------------------------------------------------------------- |
|
2976 // CMIDCanvas::BitBltCycles |
|
2977 // Get BitBlt cycles count. |
|
2978 // --------------------------------------------------------------------------- |
|
2979 // |
|
2980 TInt CMIDCanvas::BitBltCycles(const TSize& aSize) const |
|
2981 { |
|
2982 TInt cycles = (aSize.iWidth * aSize.iHeight * KEstCyclesPerPixel); |
|
2983 |
|
2984 if (cycles < KMinOpCycles) cycles = KMinOpCycles; |
|
2985 if (cycles > KMaxOpCycles) cycles = KMaxOpCycles; |
|
2986 |
|
2987 return cycles; |
|
2988 } |
|
2989 #endif // DEFER_BITBLT |
|
2990 |
|
2991 |
|
2992 // --------------------------------------------------------------------------- |
|
2993 // CMIDCanvas::Layout |
|
2994 // Layout Canvas control. |
|
2995 // --------------------------------------------------------------------------- |
|
2996 // |
|
2997 void CMIDCanvas::Layout() |
|
2998 { |
|
2999 DEBUG("+ CMIDCanvas::Layout"); |
|
3000 #ifdef CANVAS_DIRECT_ACCESS |
|
3001 StopDirectAccess(); |
|
3002 #endif // CANVAS_DIRECT_ACCESS |
|
3003 |
|
3004 TRect rect(Rect()); |
|
3005 TSize size(rect.Size()); |
|
3006 TSize viewSize; |
|
3007 |
|
3008 if (iFullScreen) |
|
3009 { |
|
3010 #ifdef RD_JAVA_NGA_ENABLED |
|
3011 if (iScalingOn) |
|
3012 { |
|
3013 // Translate to screen coordinates. |
|
3014 rect.Move(iPositionRelativeToScreen); |
|
3015 } |
|
3016 #endif // RD_JAVA_NGA_ENABLED |
|
3017 |
|
3018 if (iNetworkIndicator) |
|
3019 { |
|
3020 // Refresh the layout data for network indicator. |
|
3021 iNetworkIndicator->GetLayoutData(); |
|
3022 } |
|
3023 |
|
3024 // Get original MIDlet size which eventually reflects display |
|
3025 // orientation. |
|
3026 TSize orientedOrgMIDletScrSize(OrientedOrgMIDletScrSize()); |
|
3027 |
|
3028 // If Nokia-MIDlet-Target-Display-Size is defined, Canvas will be |
|
3029 // scaled to that size. |
|
3030 if (iTargetMIDletScrSize != KZeroSize) |
|
3031 { |
|
3032 viewSize = iTargetMIDletScrSize; |
|
3033 } |
|
3034 |
|
3035 // If optional JAD parameter Nokia-MIDlet-Target-Display-Size is NOT |
|
3036 // defined and Nokia-MIDlet-Original-Display-Size is defined to |
|
3037 // smaller size than the device's screen size, we will scale the |
|
3038 // Canvas to fit the screen without changing aspect ratio. |
|
3039 // If the aspect ratio of Nokia-MIDlet-Original-Display-Size is not |
|
3040 // same as the display has, we need to leave black borders to both |
|
3041 // sides or up and down. |
|
3042 else if ( |
|
3043 (orientedOrgMIDletScrSize.iWidth != 0) && |
|
3044 (orientedOrgMIDletScrSize.iHeight != 0)) |
|
3045 { |
|
3046 TReal widthScalingFactor = |
|
3047 (TReal)size.iWidth / |
|
3048 (TReal)orientedOrgMIDletScrSize.iWidth; |
|
3049 |
|
3050 TReal heightScalingFactor = |
|
3051 (TReal)size.iHeight / |
|
3052 (TReal)orientedOrgMIDletScrSize.iHeight; |
|
3053 |
|
3054 // Aspect ratio of MIDlet is same as display. |
|
3055 if (widthScalingFactor == heightScalingFactor) |
|
3056 { |
|
3057 viewSize.SetSize(size.iWidth, size.iHeight); |
|
3058 } |
|
3059 // Aspect ratio of MIDlet is "wider" than display. |
|
3060 else if (widthScalingFactor < heightScalingFactor) |
|
3061 { |
|
3062 viewSize.SetSize(size.iWidth, |
|
3063 widthScalingFactor * iContentSize.iHeight); |
|
3064 } |
|
3065 //Aspect ratio of MIDlet is "narrower" than display. |
|
3066 else |
|
3067 { |
|
3068 viewSize.SetSize(heightScalingFactor * iContentSize.iWidth, |
|
3069 size.iHeight); |
|
3070 } |
|
3071 } |
|
3072 // If JAD parameters for graphics scaling are not defined, Canvas |
|
3073 // won't be scaled. |
|
3074 else |
|
3075 { |
|
3076 viewSize = iContentSize; |
|
3077 } |
|
3078 } |
|
3079 // If Canvas is not in full screen mode, it won't be scaled. |
|
3080 else |
|
3081 { |
|
3082 viewSize = iContentSize; |
|
3083 } |
|
3084 |
|
3085 TSize border = (size - viewSize); |
|
3086 TBool center = ((border.iWidth != 0) || (border.iHeight != 0)); |
|
3087 TPoint viewPos = rect.iTl; |
|
3088 |
|
3089 // Compute position of view rect in window. |
|
3090 // |
|
3091 // If content does not fill the control, center it, but try |
|
3092 // to keep the left hand pixel of content aligned to a word |
|
3093 // boundary of screen memory to enable faster blts. |
|
3094 if (center) |
|
3095 { |
|
3096 viewPos.iX += border.iWidth / 2; |
|
3097 viewPos.iY += border.iHeight / 2; |
|
3098 |
|
3099 const TPoint screenPos = PositionRelativeToScreen(); |
|
3100 |
|
3101 // Align to 4-pixel boundary - this is overkill but covers both |
|
3102 // EColor256 and EColor4K. Should query graphics plugin for the |
|
3103 // alignment. |
|
3104 const TInt KAlignBoundary = 4; |
|
3105 TInt alignment = KAlignBoundary |
|
3106 - ((viewPos.iX + screenPos.iX) & 0x3); |
|
3107 |
|
3108 // This alignment change is made to keep canvas as more center |
|
3109 // as it is possible. Alignment can have values between 0 and 4 |
|
3110 // so if it have value more than 2, there is a -4 subtraction |
|
3111 // to prevent moving canvas too much to right side of display. |
|
3112 if (alignment > 2) |
|
3113 { |
|
3114 alignment -= KAlignBoundary; |
|
3115 } |
|
3116 |
|
3117 viewPos.iX += alignment; |
|
3118 |
|
3119 // Fallback to original position - we'll just have to take the |
|
3120 // unaligned bitblt performance hit. |
|
3121 if (viewPos.iX < rect.iTl.iX || |
|
3122 (viewPos.iX + viewSize.iWidth) > rect.iBr.iX) |
|
3123 { |
|
3124 viewPos.iX -= alignment; |
|
3125 } |
|
3126 } |
|
3127 |
|
3128 iViewRect = TRect(viewPos, viewSize); |
|
3129 |
|
3130 #ifdef CANVAS_DIRECT_ACCESS |
|
3131 StartDirectAccess(); |
|
3132 #endif // CANVAS_DIRECT_ACCESS |
|
3133 #ifdef RD_JAVA_NGA_ENABLED |
|
3134 // To avoid situation when Orientation was changed and black screen is shown |
|
3135 TRAPD(err, UpdateL(iViewRect)); |
|
3136 if (err != KErrNone) |
|
3137 { |
|
3138 DEBUG_INT("CMIDCanvas::Layout - update error %d", err); |
|
3139 } |
|
3140 #endif // RD_JAVA_NGA_ENABLED |
|
3141 |
|
3142 TInt contentsCount(iDirectContents.Count()); |
|
3143 |
|
3144 for (TInt j = 0; j < contentsCount; j++) |
|
3145 { |
|
3146 iDirectContents[j]->MdcContentBoundsChanged( |
|
3147 TRect(PositionRelativeToScreen(), Size())); |
|
3148 } |
|
3149 |
|
3150 DEBUG_PROFILE("CMIDCanvas::Layout Canvas up and running \n"); |
|
3151 DEBUG("- CMIDCanvas::Layout"); |
|
3152 } |
|
3153 |
|
3154 |
|
3155 #ifdef CANVAS_DIRECT_ACCESS |
|
3156 // --------------------------------------------------------------------------- |
|
3157 // CMIDCanvas::DirectEnabled |
|
3158 // Tells whether Direct Screen Access is enabled or disabled. |
|
3159 // --------------------------------------------------------------------------- |
|
3160 // |
|
3161 inline TBool CMIDCanvas::DirectEnabled() const |
|
3162 { |
|
3163 return iFlags & EDirectEnabled; |
|
3164 } |
|
3165 |
|
3166 |
|
3167 // --------------------------------------------------------------------------- |
|
3168 // CMIDCanvas::DirectPaused |
|
3169 // Tells whether Direct Screen Access is paused or not. |
|
3170 // --------------------------------------------------------------------------- |
|
3171 // |
|
3172 inline TBool CMIDCanvas::DirectPaused() const |
|
3173 { |
|
3174 return iFlags & EDirectPaused; |
|
3175 } |
|
3176 |
|
3177 |
|
3178 // --------------------------------------------------------------------------- |
|
3179 // CMIDCanvas::UpdateRequired |
|
3180 // Tells whether update is required or not. |
|
3181 // --------------------------------------------------------------------------- |
|
3182 // |
|
3183 inline TBool CMIDCanvas::UpdateRequired() const |
|
3184 { |
|
3185 return iFlags & EUpdateRequired; |
|
3186 } |
|
3187 #endif //CANVAS_DIRECT_ACCESS |
|
3188 |
|
3189 |
|
3190 // --------------------------------------------------------------------------- |
|
3191 // CMIDCanvas::PostKeyEvents |
|
3192 // Tells whether posting of key events is enabled or disabled. |
|
3193 // --------------------------------------------------------------------------- |
|
3194 // |
|
3195 inline TBool CMIDCanvas::PostKeyEvents() const |
|
3196 { |
|
3197 return iFlags & EPostKeyEvents; |
|
3198 } |
|
3199 |
|
3200 |
|
3201 // --------------------------------------------------------------------------- |
|
3202 // CMIDCanvas::GamePress |
|
3203 // Process game press action. |
|
3204 // --------------------------------------------------------------------------- |
|
3205 // |
|
3206 void CMIDCanvas::GamePress(TInt aGameAction) |
|
3207 { |
|
3208 const TInt gameBit = 1 << aGameAction; |
|
3209 iGameKeyState |= gameBit; |
|
3210 iGameKeyLatch |= iGameKeyState; |
|
3211 } |
|
3212 |
|
3213 |
|
3214 // --------------------------------------------------------------------------- |
|
3215 // CMIDCanvas::GameRelease |
|
3216 // Process game release action. |
|
3217 // --------------------------------------------------------------------------- |
|
3218 // |
|
3219 void CMIDCanvas::GameRelease(TInt aGameAction) |
|
3220 { |
|
3221 const TInt gameBit = 1 << aGameAction; |
|
3222 iGameKeyState &= ~ gameBit; |
|
3223 iGameKeyLatch |= iGameKeyState; |
|
3224 } |
|
3225 |
|
3226 |
|
3227 // --------------------------------------------------------------------------- |
|
3228 // CMIDCanvas::SetScalingFactors |
|
3229 // Sets MIDlet's original size and target size resolutions if those are |
|
3230 // defined in JAD or manifest. If attribute is missing or it's not defined |
|
3231 // correctly, the value will be 0,0. This value is later used as an "error |
|
3232 // value". |
|
3233 // --------------------------------------------------------------------------- |
|
3234 // |
|
3235 void CMIDCanvas::SetScalingFactors() |
|
3236 { |
|
3237 CMIDMenuHandler* menuHandler = iDisplayable->MenuHandler(); |
|
3238 |
|
3239 ASSERT(menuHandler); |
|
3240 |
|
3241 iScalingOn = menuHandler->IsScalingEnabled(); |
|
3242 |
|
3243 iOrgMIDletScrSize = menuHandler->GetScalingParameterOrgMIDletScrSize(); |
|
3244 |
|
3245 iTargetMIDletScrSize = |
|
3246 menuHandler->GetScalingParameterTargetMIDletScrSize(); |
|
3247 |
|
3248 iScaleMIDletOnOrientSwitch = |
|
3249 menuHandler->GetScalingParameterScaleMIDletOnOrientSwitch(); |
|
3250 } |
|
3251 |
|
3252 |
|
3253 // --------------------------------------------------------------------------- |
|
3254 // CMIDCanvas::OrientedOrgMIDletScrSize |
|
3255 // Returns original MIDlet screen size with regards to display orientation. |
|
3256 // --------------------------------------------------------------------------- |
|
3257 // |
|
3258 TSize CMIDCanvas::OrientedOrgMIDletScrSize() const |
|
3259 { |
|
3260 // Ensure that scaling and scaling-on-orientation-switch is enabled. |
|
3261 if (iScalingOn && iScaleMIDletOnOrientSwitch) |
|
3262 { |
|
3263 TSize orientedSize; |
|
3264 |
|
3265 // Ensure that original size is defined as portrait. |
|
3266 if (iOrgMIDletScrSize.iWidth < iOrgMIDletScrSize.iHeight) |
|
3267 { |
|
3268 orientedSize = iOrgMIDletScrSize; |
|
3269 } |
|
3270 else |
|
3271 { |
|
3272 orientedSize.iWidth = iOrgMIDletScrSize.iHeight; |
|
3273 orientedSize.iHeight = iOrgMIDletScrSize.iWidth; |
|
3274 } |
|
3275 |
|
3276 // Change original size orientation if actuall display orientation |
|
3277 // is landscape. |
|
3278 if (Layout_Meta_Data::IsLandscapeOrientation()) |
|
3279 { |
|
3280 TInt swap = orientedSize.iWidth; |
|
3281 orientedSize.iWidth = orientedSize.iHeight; |
|
3282 orientedSize.iHeight = swap; |
|
3283 } |
|
3284 |
|
3285 return orientedSize; |
|
3286 } |
|
3287 else |
|
3288 { |
|
3289 return iOrgMIDletScrSize; |
|
3290 } |
|
3291 } |
|
3292 |
|
3293 // --------------------------------------------------------------------------- |
|
3294 // CMIDCanvas::IsNetworkIndicatorEnabledL |
|
3295 // Check if the network indicator should be shown in Canvas. |
|
3296 // --------------------------------------------------------------------------- |
|
3297 // |
|
3298 TBool CMIDCanvas::IsNetworkIndicatorEnabledL() const |
|
3299 { |
|
3300 if (RProcess().SecureId().iId != 0x102033E6) |
|
3301 { |
|
3302 // For standalone type apps we don't show indicator. |
|
3303 return EFalse; |
|
3304 } |
|
3305 TBool enabled = ETrue; // Return ETrue by default. |
|
3306 |
|
3307 std::auto_ptr<java::storage::JavaStorage> js(java::storage::JavaStorage::createInstance()); |
|
3308 java::storage::JavaStorageApplicationEntry_t entries; |
|
3309 try |
|
3310 { |
|
3311 js->open(); |
|
3312 java::util::Uid uid; |
|
3313 TUidToUid(iEnv.MidletSuiteUid(), uid); |
|
3314 js->read(java::storage::MIDP_PACKAGE_TABLE, uid, entries); |
|
3315 js->close(); |
|
3316 } |
|
3317 catch (java::storage::JavaStorageException& ex) |
|
3318 { |
|
3319 DEBUG_INT("CMIDCanvas::IsNetworkIndicatorEnabledL: JavaStorage error: \ |
|
3320 reading MIDP_PACKAGE_TABLE failed, error code = %D", ex.mStatus); |
|
3321 } |
|
3322 java::storage::JavaStorageEntry attribute; |
|
3323 attribute.setEntry(java::storage::SECURITY_DOMAIN_CATEGORY, L""); |
|
3324 java::storage::JavaStorageApplicationEntry_t::const_iterator findIterator = entries.find(attribute); |
|
3325 std::wstring res = L""; |
|
3326 if (findIterator != entries.end()) |
|
3327 { |
|
3328 res = (*findIterator).entryValue(); |
|
3329 } |
|
3330 entries.clear(); |
|
3331 |
|
3332 if (res == MANUFACTURER_DOMAIN_CATEGORY) |
|
3333 { |
|
3334 enabled = EFalse; |
|
3335 } |
|
3336 else if (res == OPERATOR_DOMAIN_CATEGORY) |
|
3337 { |
|
3338 // Read the central repository key to find out if the |
|
3339 // network indicator should be shown for midlets in |
|
3340 // operator domain. |
|
3341 CRepository* repository = NULL; |
|
3342 TRAPD(err, repository = CRepository::NewL(KCRUidMidpLcdui)); |
|
3343 |
|
3344 if (err == KErrNone) |
|
3345 { |
|
3346 err = repository->Get(KShowCanvasNetIndicatorInOperatorDomain, enabled); |
|
3347 if (err != KErrNone) |
|
3348 { |
|
3349 DEBUG_INT("CMIDCanvas::IsNetworkIndicatorEnabledL: \ |
|
3350 reading CenRep key failed, error code = %D", err); |
|
3351 } |
|
3352 } |
|
3353 |
|
3354 delete repository; |
|
3355 repository = NULL; |
|
3356 } |
|
3357 |
|
3358 return enabled; |
|
3359 } |
|
3360 |
|
3361 #ifdef RD_JAVA_NGA_ENABLED |
|
3362 |
|
3363 // --------------------------------------------------------------------------- |
|
3364 // CMIDCanvas::HandleForeground |
|
3365 // Relases resources in graphics HW (=pixel source or EGL resources) |
|
3366 // when going to background. |
|
3367 // --------------------------------------------------------------------------- |
|
3368 // |
|
3369 void CMIDCanvas::HandleForeground(TBool aForeground) |
|
3370 { |
|
3371 DEBUG_INT("CMIDCanvas::HandleForeground(%d) ++", aForeground); |
|
3372 iForeground = aForeground; |
|
3373 |
|
3374 if (!iForeground) |
|
3375 { |
|
3376 if (IsEglAvailable()) |
|
3377 { |
|
3378 if (iEglOccupied) |
|
3379 { |
|
3380 DEBUG("CMIDCanvas::HandleForeground() - egl - pending dispose"); |
|
3381 iEglPendingDispose = ETrue; |
|
3382 } |
|
3383 else |
|
3384 { |
|
3385 CloseEgl(); |
|
3386 } |
|
3387 } |
|
3388 |
|
3389 SuspendPixelSource(); |
|
3390 } |
|
3391 DEBUG("CMIDCanvas::HandleForeground --"); |
|
3392 } |
|
3393 |
|
3394 // --------------------------------------------------------------------------- |
|
3395 // CMIDCanvas::InitPixelSourceL() |
|
3396 // --------------------------------------------------------------------------- |
|
3397 // |
|
3398 void CMIDCanvas::InitPixelSourceL() |
|
3399 { |
|
3400 if (iAlfCompositionPixelSource) |
|
3401 { |
|
3402 return; |
|
3403 } |
|
3404 iPixelSourceSuspended = ETrue; |
|
3405 TBool modeSupported = EFalse; |
|
3406 switch (iFrameBuffer->DisplayMode()) |
|
3407 { |
|
3408 case EColor16MU: |
|
3409 modeSupported = ETrue; |
|
3410 iAlfBufferAttributes.iFormat = |
|
3411 MAlfBufferProvider::ESourceFormatXRGB_8888; |
|
3412 break; |
|
3413 case EColor16MA: |
|
3414 modeSupported = ETrue; |
|
3415 iAlfBufferAttributes.iFormat = |
|
3416 MAlfBufferProvider::ESourceFormatARGB_8888; |
|
3417 break; |
|
3418 case EColor16MAP: |
|
3419 modeSupported = ETrue; |
|
3420 iAlfBufferAttributes.iFormat = |
|
3421 MAlfBufferProvider::ESourceFormatARGB_8888_PRE; |
|
3422 break; |
|
3423 default: |
|
3424 break; |
|
3425 } |
|
3426 |
|
3427 if (modeSupported) |
|
3428 { |
|
3429 iAlfCompositionPixelSource = CAlfCompositionPixelSource::NewL(*this, &Window()); |
|
3430 |
|
3431 iAlfBufferAttributes.iWidth = iContentSize.iWidth; |
|
3432 iAlfBufferAttributes.iHeight = iContentSize.iHeight; |
|
3433 iAlfBufferAttributes.iStride = iAlfBufferAttributes.iWidth * KBytesPerPixel; |
|
3434 iAlfBufferAttributes.iAlignment = 32; |
|
3435 } |
|
3436 } |
|
3437 |
|
3438 // --------------------------------------------------------------------------- |
|
3439 // CMIDCanvas::DisposePixelSource |
|
3440 // --------------------------------------------------------------------------- |
|
3441 // |
|
3442 void CMIDCanvas::DisposePixelSource() |
|
3443 { |
|
3444 DEBUG("CMIDCanvas::DisposePixelSource ++"); |
|
3445 NotifyMonitor(); |
|
3446 if (iAlfCompositionPixelSource) |
|
3447 { |
|
3448 DEBUG("CMIDCanvas::DisposePixelSource - delete alf"); |
|
3449 iAlfCompositionPixelSource->Suspend(); |
|
3450 delete iAlfCompositionPixelSource; |
|
3451 iAlfCompositionPixelSource = NULL; |
|
3452 } |
|
3453 DEBUG("CMIDCanvas::DisposePixelSource --"); |
|
3454 } |
|
3455 |
|
3456 // --------------------------------------------------------------------------- |
|
3457 // CMIDCanvas::ActivatePixelSourceL |
|
3458 // In scaling case need to call SetExtent() again if pixel source was suspended. |
|
3459 // --------------------------------------------------------------------------- |
|
3460 // |
|
3461 void CMIDCanvas::ActivatePixelSourceL() |
|
3462 { |
|
3463 ASSERT(iAlfCompositionPixelSource); |
|
3464 |
|
3465 if (iDirectContents.Count() > 0) |
|
3466 { |
|
3467 return; |
|
3468 } |
|
3469 |
|
3470 iAlfCompositionPixelSource->ActivateSyncL(); |
|
3471 iFrameReady = ETrue; |
|
3472 |
|
3473 if (iPixelSourceSuspended) |
|
3474 { |
|
3475 iPixelSourceSuspended = EFalse; |
|
3476 if (iFullScreen && iScalingOn) |
|
3477 { |
|
3478 iAlfCompositionPixelSource->SetExtent(iViewRect, KPhoneScreen); |
|
3479 } |
|
3480 } |
|
3481 } |
|
3482 |
|
3483 // --------------------------------------------------------------------------- |
|
3484 // CMIDCanvas::SuspendPixelSource |
|
3485 // --------------------------------------------------------------------------- |
|
3486 // |
|
3487 void CMIDCanvas::SuspendPixelSource() |
|
3488 { |
|
3489 NotifyMonitor(); |
|
3490 if (iAlfCompositionPixelSource) |
|
3491 { |
|
3492 iAlfCompositionPixelSource->Suspend(); |
|
3493 iPixelSourceSuspended = ETrue; |
|
3494 } |
|
3495 } |
|
3496 |
|
3497 // --------------------------------------------------------------------------- |
|
3498 // CMIDCanvas::NotifyMonitor |
|
3499 // CMIDCanvas::ProcessL() is asyncronous when CAlfCompositionPixelSource is used. |
|
3500 // This notiCMIDBuffer's monitor so that waiting Java thread is resumed. |
|
3501 // --------------------------------------------------------------------------- |
|
3502 // |
|
3503 void CMIDCanvas::NotifyMonitor() |
|
3504 { |
|
3505 if (iAlfMonitor) |
|
3506 { |
|
3507 iAlfMonitor->notify(); |
|
3508 iAlfMonitor = NULL; |
|
3509 } |
|
3510 iFrameReady = EFalse; |
|
3511 } |
|
3512 |
|
3513 // --------------------------------------------------------------------------- |
|
3514 // From MAlfBufferProvider |
|
3515 // CMIDCanvas::ProduceNewFrameL |
|
3516 // Callback from CAlfCompositionPixelSource. Copy RGB data from framebuffer |
|
3517 // to pixel source's buffer. Return ETrue if we have a frame ready, |
|
3518 // EFalse otherwise. |
|
3519 // --------------------------------------------------------------------------- |
|
3520 // |
|
3521 TBool CMIDCanvas::ProduceNewFrameL(const TRegion& aVisibleRegion, TUint8*& aBuffer) |
|
3522 { |
|
3523 DEBUG_INT("CMIDCanvas::ProduceNewFrameL (thread=%d) ++", RThread().Id().Id()); |
|
3524 TRect bbox(aVisibleRegion.BoundingRect()); |
|
3525 DEBUG_INT4("CMIDCanvas::ProduceNewFrameL - visible region(x=%d, y=%d, w=%d, h=%d) ++", |
|
3526 bbox.iTl.iX, bbox.iTl.iY, bbox.Width(), bbox.Height()); |
|
3527 |
|
3528 // If iDirectContents.Count() > 0, canvas hasn't received |
|
3529 // MdcNotifyContentAdded in LCDUI thread yet. |
|
3530 if (!iFrameReady || iDirectContents.Count() > 0) |
|
3531 { |
|
3532 DEBUG("CMIDCanvas::ProduceNewFrameL - FRAME IS NOT READY --"); |
|
3533 NotifyMonitor(); |
|
3534 return EFalse; |
|
3535 } |
|
3536 |
|
3537 NotifyMonitor(); |
|
3538 |
|
3539 TUint8* from = (TUint8*)iFrameBuffer->DataAddress(); |
|
3540 |
|
3541 TBool downScaling = IsDownScaling(iContentSize, iViewRect); |
|
3542 TInt width = downScaling ? iViewRect.Width() : iContentSize.iWidth; |
|
3543 TInt height = downScaling ? iViewRect.Height() : iContentSize.iHeight; |
|
3544 |
|
3545 TUint bytes = width * KBytesPerPixel; |
|
3546 TInt scanLength = CFbsBitmap::ScanLineLength( |
|
3547 iFrameBuffer->SizeInPixels().iWidth, iFrameBuffer->DisplayMode()); |
|
3548 |
|
3549 for (TInt y = 0; y < height; ++y) |
|
3550 { |
|
3551 Mem::Copy(aBuffer, from, bytes); |
|
3552 aBuffer += iAlfBufferAttributes.iStride; |
|
3553 from += scanLength; |
|
3554 } |
|
3555 |
|
3556 DEBUG("CMIDCanvas::ProduceNewFrameL --"); |
|
3557 return ETrue; |
|
3558 } |
|
3559 |
|
3560 // --------------------------------------------------------------------------- |
|
3561 // From MAlfBufferProvider |
|
3562 // CMIDCanvas::BufferAttributes |
|
3563 // Called by CAlfCompositionPixelSource to get the size of RGB data. |
|
3564 // --------------------------------------------------------------------------- |
|
3565 // |
|
3566 MAlfBufferProvider::TBufferCreationAttributes& CMIDCanvas::BufferAttributes() |
|
3567 { |
|
3568 DEBUG_INT2("CMIDCanvas::BufferAttributes - iContentSize(w=%d, h=%d) ++", |
|
3569 iContentSize.iWidth, iContentSize.iHeight); |
|
3570 |
|
3571 TBool downScaling = IsDownScaling(iContentSize, iViewRect); |
|
3572 iAlfBufferAttributes.iWidth = downScaling ? iViewRect.Width() : iContentSize.iWidth; |
|
3573 iAlfBufferAttributes.iHeight = downScaling ? iViewRect.Height() : iContentSize.iHeight; |
|
3574 |
|
3575 iAlfBufferAttributes.iStride = iAlfBufferAttributes.iWidth * KBytesPerPixel; |
|
3576 return iAlfBufferAttributes; |
|
3577 } |
|
3578 |
|
3579 // --------------------------------------------------------------------------- |
|
3580 // From MAlfBufferProvider |
|
3581 // CMIDCanvas::ContextAboutToSuspend |
|
3582 // Notification from Alf. |
|
3583 // --------------------------------------------------------------------------- |
|
3584 // |
|
3585 void CMIDCanvas::ContextAboutToSuspend() |
|
3586 { |
|
3587 DEBUG("CMIDCanvas::ContextAboutToSuspend() ++"); |
|
3588 NotifyMonitor(); |
|
3589 iPixelSourceSuspended = ETrue; |
|
3590 DEBUG("CMIDCanvas::ContextAboutToSuspend() --"); |
|
3591 } |
|
3592 |
|
3593 // --------------------------------------------------------------------------- |
|
3594 // From MAlfBufferProvider |
|
3595 // CMIDCanvas::OnActivation |
|
3596 // Notification from Alf. |
|
3597 // --------------------------------------------------------------------------- |
|
3598 // |
|
3599 void CMIDCanvas::OnActivation() |
|
3600 { |
|
3601 DEBUG("CMIDCanvas::OnActivation()++--"); |
|
3602 } |
|
3603 |
|
3604 |
|
3605 // --------------------------------------------------------------------------- |
|
3606 // CMIDCanvas::OpenEglL |
|
3607 // Creates EGL window surface and context. Only 32 bit display modes are |
|
3608 // supported. |
|
3609 // --------------------------------------------------------------------------- |
|
3610 // |
|
3611 void CMIDCanvas::OpenEglL() |
|
3612 { |
|
3613 if (IsEglAvailable()) |
|
3614 { |
|
3615 return; |
|
3616 } |
|
3617 |
|
3618 DEBUG("CMIDCanvas::OpenEglL() ++"); |
|
3619 |
|
3620 if (iEglDisplay == EGL_NO_DISPLAY) |
|
3621 { |
|
3622 iEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
|
3623 |
|
3624 // Initializing an already initialized display has no effect. |
|
3625 // eglTerminate is not called in LCDUI side ever, only by M3G |
|
3626 if (eglInitialize(iEglDisplay, NULL, NULL) == EGL_FALSE) |
|
3627 { |
|
3628 ELOG1(EJavaUI, "eglInitialize() failed, eglError=%d", eglGetError()); |
|
3629 User::Leave(KErrNotSupported); |
|
3630 } |
|
3631 } |
|
3632 |
|
3633 RWindow& window = Window(); |
|
3634 // Choose the buffer size based on the Window's display mode. |
|
3635 TDisplayMode displayMode = window.DisplayMode(); |
|
3636 TInt bufferSize = 0; |
|
3637 switch (displayMode) |
|
3638 { |
|
3639 case(EColor16MU): |
|
3640 case(EColor16MA): |
|
3641 case(EColor16MAP): |
|
3642 bufferSize = 32; |
|
3643 break; |
|
3644 default: |
|
3645 ELOG1(EJavaUI, "CMIDCanvas::OpenEglL(): unsupported window display mode %d", |
|
3646 displayMode); |
|
3647 User::Leave(KErrNotSupported); |
|
3648 break; |
|
3649 } |
|
3650 |
|
3651 EGLint surfaceType = EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; |
|
3652 |
|
3653 const EGLint attributeList[] = |
|
3654 { |
|
3655 EGL_SURFACE_TYPE, surfaceType, |
|
3656 EGL_RED_SIZE, 8, |
|
3657 EGL_GREEN_SIZE, 8, |
|
3658 EGL_BLUE_SIZE, 8, |
|
3659 EGL_ALPHA_SIZE, 8, |
|
3660 EGL_BUFFER_SIZE, bufferSize, |
|
3661 EGL_TRANSPARENT_TYPE, EGL_NONE, |
|
3662 EGL_DEPTH_SIZE, 16, |
|
3663 EGL_NONE |
|
3664 }; |
|
3665 |
|
3666 EGLint numConfigs = 0; |
|
3667 |
|
3668 // Choose the best EGLConfig that matches the desired properties. |
|
3669 if ((eglChooseConfig(iEglDisplay, attributeList, &iEglConfig, 1, &numConfigs) == EGL_FALSE) || |
|
3670 numConfigs == 0) |
|
3671 { |
|
3672 ELOG1(EJavaUI, "eglChooseConfig() failed, eglError=%d", eglGetError()); |
|
3673 User::Leave(KErrNotSupported); |
|
3674 } |
|
3675 |
|
3676 // Check that surface content is preserved in swap, otherwise the |
|
3677 // game canvas content cannot be preserved. |
|
3678 eglGetConfigAttrib(iEglDisplay, iEglConfig, EGL_SURFACE_TYPE, &surfaceType); |
|
3679 if (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT == 0) |
|
3680 { |
|
3681 ELOG(EJavaUI, "Egl config does not support EGL_SWAP_BEHAVIOR_PRESERVED_BIT"); |
|
3682 User::Leave(KErrNotSupported); |
|
3683 } |
|
3684 |
|
3685 // Create a window surface where the graphics are blitted. |
|
3686 // Pass the Native Window handle to egl. |
|
3687 iEglWindowSurface = eglCreateWindowSurface(iEglDisplay, iEglConfig, (void*)&window, NULL); |
|
3688 if (iEglWindowSurface == EGL_NO_SURFACE) |
|
3689 { |
|
3690 ELOG1(EJavaUI, "eglCreateWindowSurface() failed, eglError=%d", eglGetError()); |
|
3691 User::Leave(KErrNoMemory); |
|
3692 } |
|
3693 // Need to preserve surface content after swapping |
|
3694 eglSurfaceAttrib(iEglDisplay, iEglWindowSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); |
|
3695 |
|
3696 CreateEglContext(); |
|
3697 ClearEglSurface(EEglWindow); |
|
3698 |
|
3699 // Allocate memory for ARGB->RGBA conversion needed by |
|
3700 // openGL texture |
|
3701 if (!iTexturePixels) |
|
3702 { |
|
3703 iTexturePixels = new(ELeave) TUint8[KMaxBlitSize * KMaxBlitSize * KBytesPerPixel]; |
|
3704 } |
|
3705 glDisable(GL_DEPTH_TEST); |
|
3706 glDisable(GL_LIGHTING); |
|
3707 glEnableClientState(GL_VERTEX_ARRAY); |
|
3708 if (!iVertexArray) |
|
3709 { |
|
3710 iVertexArray = new(ELeave) GLshort[8]; |
|
3711 } |
|
3712 if (!iTriangleStrip) |
|
3713 { |
|
3714 iTriangleStrip = new(ELeave) GLubyte[4]; |
|
3715 iTriangleStrip[0] = 0; |
|
3716 iTriangleStrip[1] = 1; |
|
3717 iTriangleStrip[2] = 3; |
|
3718 iTriangleStrip[3] = 2; |
|
3719 } |
|
3720 DEBUG("CMIDCanvas::OpenEglL() --"); |
|
3721 } |
|
3722 |
|
3723 // --------------------------------------------------------------------------- |
|
3724 // CMIDCanvas::CloseEgl |
|
3725 // Destroys EGL contexts and surfaces. |
|
3726 // --------------------------------------------------------------------------- |
|
3727 // |
|
3728 void CMIDCanvas::CloseEgl() |
|
3729 { |
|
3730 DEBUG("CMIDCanvas::CloseEglL() ++"); |
|
3731 |
|
3732 iM3GContent = EFalse; |
|
3733 iM3GStart = EFalse; |
|
3734 iEglPendingResize = EFalse; |
|
3735 iEglPendingDispose = EFalse; |
|
3736 |
|
3737 if (iEglDisplay == EGL_NO_DISPLAY) |
|
3738 { |
|
3739 return; |
|
3740 } |
|
3741 |
|
3742 // MIDlet might draw only 2D after this => |
|
3743 // need to set frame buffer opaque to be compatible with |
|
3744 // blending methods in Lcdgd. UpdateOffScreenBitmapL() does this |
|
3745 // for GameCanvas. |
|
3746 if (!IsGameCanvas() && iFrameContext) |
|
3747 { |
|
3748 iFrameContext->SetBrushColor(KOpaqueClearColor); |
|
3749 iFrameContext->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); |
|
3750 iFrameContext->Clear(); |
|
3751 } |
|
3752 |
|
3753 // Take a snapshot from window surface to the frame buffer. |
|
3754 TRAPD(err, UpdateOffScreenBitmapL(EFalse)); |
|
3755 if (err != KErrNone) |
|
3756 { |
|
3757 DEBUG("CMIDCanvas::CloseEgl() - UpdateOffScreenBitmapL() failed"); |
|
3758 } |
|
3759 |
|
3760 // make sure the we have no current target |
|
3761 // so that surfaces and contexts are destoyed immediately |
|
3762 SetCurrentEglType(EEglNone); |
|
3763 |
|
3764 // If pbuffer has been created dispose that here |
|
3765 if (iEglPbufferSurfaceContext != EGL_NO_CONTEXT || |
|
3766 iEglPbufferSurface != EGL_NO_SURFACE) |
|
3767 { |
|
3768 DisposePBufferSurface(); |
|
3769 } |
|
3770 |
|
3771 if (iEglWindowSurfaceContext != EGL_NO_CONTEXT) |
|
3772 { |
|
3773 eglDestroyContext(iEglDisplay, iEglWindowSurfaceContext); |
|
3774 iEglWindowSurfaceContext = EGL_NO_CONTEXT; |
|
3775 } |
|
3776 if (iEglWindowSurface != EGL_NO_SURFACE) |
|
3777 { |
|
3778 eglDestroySurface(iEglDisplay, iEglWindowSurface); |
|
3779 iEglWindowSurface = EGL_NO_SURFACE; |
|
3780 } |
|
3781 |
|
3782 DEBUG("CMIDCanvas::CloseEglL() --"); |
|
3783 } |
|
3784 |
|
3785 // --------------------------------------------------------------------------- |
|
3786 // CMIDCanvas::CreateEglContext |
|
3787 // (Re)create EGL context |
|
3788 // --------------------------------------------------------------------------- |
|
3789 // |
|
3790 void CMIDCanvas::CreateEglContext() |
|
3791 { |
|
3792 if (iEglWindowSurfaceContext != EGL_NO_CONTEXT) |
|
3793 { |
|
3794 SetCurrentEglType(EEglNone); |
|
3795 eglDestroyContext(iEglDisplay, iEglWindowSurfaceContext); |
|
3796 iEglWindowSurfaceContext = EGL_NO_CONTEXT; |
|
3797 } |
|
3798 // Create a rendering context |
|
3799 iEglWindowSurfaceContext = eglCreateContext(iEglDisplay, iEglConfig, EGL_NO_CONTEXT, NULL); |
|
3800 if (iEglWindowSurfaceContext == EGL_NO_CONTEXT) |
|
3801 { |
|
3802 ELOG1(EJavaUI, "eglCreateContext() failed, eglError=%d", eglGetError()); |
|
3803 } |
|
3804 } |
|
3805 |
|
3806 // --------------------------------------------------------------------------- |
|
3807 // CMIDCanvas::SetCurrentEglType |
|
3808 // Sets the current EGL context and surface. |
|
3809 // --------------------------------------------------------------------------- |
|
3810 // |
|
3811 TBool CMIDCanvas::SetCurrentEglType(TEglType aType) |
|
3812 { |
|
3813 EGLBoolean res = EGL_TRUE; |
|
3814 if (aType == EEglPbuffer) |
|
3815 { |
|
3816 res = eglMakeCurrent( |
|
3817 iEglDisplay, iEglPbufferSurface, iEglPbufferSurface, iEglPbufferSurfaceContext); |
|
3818 } |
|
3819 else if (aType == EEglWindow) |
|
3820 { |
|
3821 res = eglMakeCurrent( |
|
3822 iEglDisplay, iEglWindowSurface, iEglWindowSurface, iEglWindowSurfaceContext); |
|
3823 } |
|
3824 else |
|
3825 { |
|
3826 res = eglMakeCurrent( |
|
3827 iEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
|
3828 } |
|
3829 if (res == EGL_FALSE) |
|
3830 { |
|
3831 ELOG1(EJavaUI, "eglMakeCurrent() failed, eglError=%s", GetEglError(eglGetError()).Ptr()); |
|
3832 } |
|
3833 return (res == EGL_FALSE ? EFalse : ETrue); |
|
3834 } |
|
3835 |
|
3836 // --------------------------------------------------------------------------- |
|
3837 // CMIDCanvas::GetCurrentEgl |
|
3838 // Gets the current EGL type |
|
3839 // --------------------------------------------------------------------------- |
|
3840 // |
|
3841 CMIDCanvas::TEglType CMIDCanvas::GetCurrentEglType() |
|
3842 { |
|
3843 EGLSurface surface = eglGetCurrentSurface(EGL_READ); |
|
3844 if (surface == EGL_NO_SURFACE) |
|
3845 { |
|
3846 return EEglNone; |
|
3847 } |
|
3848 else if (surface == iEglPbufferSurface) |
|
3849 { |
|
3850 return EEglPbuffer; |
|
3851 } |
|
3852 else |
|
3853 { |
|
3854 return EEglWindow; |
|
3855 } |
|
3856 } |
|
3857 |
|
3858 // --------------------------------------------------------------------------- |
|
3859 // CMIDCanvas::GetEglSurfaceSize |
|
3860 // Returns size of the EGL surface. |
|
3861 // --------------------------------------------------------------------------- |
|
3862 // |
|
3863 TSize CMIDCanvas::GetEglSurfaceSize(EGLSurface aSurface) |
|
3864 { |
|
3865 TSize sz; |
|
3866 if (aSurface == EGL_NO_SURFACE) |
|
3867 { |
|
3868 aSurface = iEglWindowSurface; |
|
3869 if (iScalingOn && iFullScreen) |
|
3870 { |
|
3871 aSurface = iEglPbufferSurface; |
|
3872 } |
|
3873 } |
|
3874 if (!(eglQuerySurface(iEglDisplay, aSurface, EGL_WIDTH, &sz.iWidth) && |
|
3875 eglQuerySurface(iEglDisplay, aSurface, EGL_HEIGHT, &sz.iHeight))) |
|
3876 { |
|
3877 sz.SetSize(0, 0); |
|
3878 } |
|
3879 DEBUG_INT2("CMIDCanvas::GetEglSurfaceSizeL() - w=%d, h=%d", sz.iWidth, sz.iHeight); |
|
3880 return sz; |
|
3881 } |
|
3882 |
|
3883 // --------------------------------------------------------------------------- |
|
3884 // CMIDCanvas::HandleSizeChanged() |
|
3885 // EGL cannot handle window resize upwards and in this case we need to |
|
3886 // recreate the surface. If recreation is needed (and M3G is not using our |
|
3887 // surface) EGL context and surface are destoryed here and recreated in |
|
3888 // next ProcessL() when M3G_CONTENT_START is recieved from Java side. |
|
3889 // --------------------------------------------------------------------------- |
|
3890 // |
|
3891 void CMIDCanvas::HandleSizeChanged() |
|
3892 { |
|
3893 DEBUG("CMIDCanvas::HandleSizeChanged ++"); |
|
3894 |
|
3895 SuspendPixelSource(); |
|
3896 |
|
3897 if (IsEglAvailable()) |
|
3898 { |
|
3899 TSize surfaceSize = GetEglSurfaceSize(iEglWindowSurface); |
|
3900 TSize controlSize = Size(); |
|
3901 if (surfaceSize.iHeight < controlSize.iHeight || |
|
3902 surfaceSize.iWidth < controlSize.iWidth) |
|
3903 { |
|
3904 // Check if egl surface is currently occupied. |
|
3905 if (iEglOccupied) |
|
3906 { |
|
3907 // Delayed resizing. It is done when the ReleaseEglSurface method |
|
3908 // is called. |
|
3909 DEBUG("CMIDCanvas::HandleSizeChanged - egl - resize pending"); |
|
3910 iEglPendingResize = ETrue; |
|
3911 } |
|
3912 else |
|
3913 { |
|
3914 DEBUG("CMIDCanvas::SizeChanged - close egl"); |
|
3915 // Surface recreation is done in next ProcessL() call |
|
3916 CloseEgl(); |
|
3917 } |
|
3918 } |
|
3919 } |
|
3920 DEBUG("CMIDCanvas::HandleSizeChanged --"); |
|
3921 } |
|
3922 |
|
3923 // --------------------------------------------------------------------------- |
|
3924 // From MMIDComponentNgaExtension |
|
3925 // CMIDCanvas::UpdateEglContent |
|
3926 // Renders current 2D content in frame buffer as an OpenGL texture to |
|
3927 // EGL surface. If scaling is on, renders to pbuffer, otherwise to window surface. |
|
3928 // Called from M3G (via CMIDGraphics) when EGL surface needs to be updated with |
|
3929 // 2D content. This will not be called if M3G Background is used for clearing |
|
3930 // entire canvas area. |
|
3931 // --------------------------------------------------------------------------- |
|
3932 // |
|
3933 void CMIDCanvas::UpdateEglContent() |
|
3934 { |
|
3935 if (!IsEglAvailable()) |
|
3936 { |
|
3937 return; |
|
3938 } |
|
3939 |
|
3940 DEBUG("CMIDCanvas::UpdateEglContent() ++"); |
|
3941 |
|
3942 // If scaling update framebuffer to pbuffer, otherwise to windowsurface |
|
3943 if (iScalingOn && iFullScreen) |
|
3944 { |
|
3945 SetCurrentEglType(EEglPbuffer); |
|
3946 } |
|
3947 else |
|
3948 { |
|
3949 SetCurrentEglType(EEglWindow); |
|
3950 } |
|
3951 BlitFrameBufferPixels(); |
|
3952 SetCurrentEglType(EEglNone); |
|
3953 |
|
3954 DEBUG("CMIDCanvas::UpdateEglContent() --"); |
|
3955 } |
|
3956 |
|
3957 // --------------------------------------------------------------------------- |
|
3958 // From MMIDComponentNgaExtension |
|
3959 // CMIDCanvas::IsEglAvailable |
|
3960 // Return ETrue, if EGL based drawing is in use. |
|
3961 // --------------------------------------------------------------------------- |
|
3962 // |
|
3963 TBool CMIDCanvas::IsEglAvailable() |
|
3964 { |
|
3965 return (iEglWindowSurface != EGL_NO_SURFACE); |
|
3966 } |
|
3967 |
|
3968 // --------------------------------------------------------------------------- |
|
3969 // From MMIDComponentNgaExtension |
|
3970 // CMIDCanvas::BindEglSurface |
|
3971 // Called from M3G (via CMIDGraphics) when M3G binds to canvas |
|
3972 // graphics rendering target. |
|
3973 // --------------------------------------------------------------------------- |
|
3974 // |
|
3975 EGLSurface CMIDCanvas::BindEglSurface() |
|
3976 { |
|
3977 if (IsEglAvailable()) |
|
3978 { |
|
3979 iEglOccupied = ETrue; |
|
3980 } |
|
3981 |
|
3982 if (iScalingOn && iFullScreen) |
|
3983 { |
|
3984 return iEglPbufferSurface; |
|
3985 } |
|
3986 return iEglWindowSurface; |
|
3987 } |
|
3988 |
|
3989 // --------------------------------------------------------------------------- |
|
3990 // From MMIDComponentNgaExtension |
|
3991 // CMIDCanvas::ReleaseEglSurface |
|
3992 // Called from M3G (via CMIDGraphics) when M3G releases canvas |
|
3993 // graphics rendering target. |
|
3994 // --------------------------------------------------------------------------- |
|
3995 // |
|
3996 void CMIDCanvas::ReleaseEglSurface() |
|
3997 { |
|
3998 iEglOccupied = EFalse; |
|
3999 if (IsEglAvailable()) |
|
4000 { |
|
4001 // Pending dispose. Egl context must be released. |
|
4002 if (iEglPendingDispose) |
|
4003 { |
|
4004 DEBUG("CMIDCanvas::ReleaseEglSurface() - dispose egl"); |
|
4005 CloseEgl(); |
|
4006 } |
|
4007 else if (iEglPendingResize) |
|
4008 { |
|
4009 DEBUG("CMIDCanvas::ReleaseEglSurface() - pending resize"); |
|
4010 HandleSizeChanged(); |
|
4011 } |
|
4012 ClearFrameBuffer(); |
|
4013 } |
|
4014 } |
|
4015 |
|
4016 // --------------------------------------------------------------------------- |
|
4017 // From MMIDComponentNgaExtension |
|
4018 // CMIDCanvas::UpdateOffScreenBitmap() |
|
4019 // --------------------------------------------------------------------------- |
|
4020 // |
|
4021 void CMIDCanvas::UpdateOffScreenBitmapL(TBool aForced) |
|
4022 { |
|
4023 if (IsEglAvailable() && iFrameContext && (IsGameCanvas() || aForced)) |
|
4024 { |
|
4025 DEBUG("CMIDCanvas::UpdateOffScreenBitmapL() ++"); |
|
4026 |
|
4027 UpdateEglContent(); |
|
4028 |
|
4029 EGLSurface surface = EGL_NO_SURFACE; |
|
4030 TEglType current = GetCurrentEglType(); |
|
4031 |
|
4032 if (iScalingOn && iFullScreen) |
|
4033 { |
|
4034 SetCurrentEglType(EEglPbuffer); |
|
4035 surface = iEglPbufferSurface; |
|
4036 } |
|
4037 else |
|
4038 { |
|
4039 SetCurrentEglType(EEglWindow); |
|
4040 surface = iEglWindowSurface; |
|
4041 } |
|
4042 |
|
4043 CFbsBitmap* bitmap = new(ELeave) CFbsBitmap; |
|
4044 CleanupStack::PushL(bitmap); |
|
4045 User::LeaveIfError(bitmap->Create( |
|
4046 GetEglSurfaceSize(surface), iEnv.DisplayMode())); |
|
4047 |
|
4048 if (EGL_FALSE == eglCopyBuffers(iEglDisplay, surface, bitmap)) |
|
4049 { |
|
4050 ELOG1(EJavaUI, "eglCopyBuffers() failed, eglError=%s", |
|
4051 GetEglError(eglGetError()).Ptr()); |
|
4052 User::Leave(KErrUnknown); |
|
4053 } |
|
4054 |
|
4055 // Make framebuffer opaque |
|
4056 iFrameContext->SetBrushColor(KOpaqueClearColor); |
|
4057 iFrameContext->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); |
|
4058 iFrameContext->Clear(); |
|
4059 |
|
4060 iFrameContext->BitBlt(TPoint(), bitmap); |
|
4061 CleanupStack::PopAndDestroy(); |
|
4062 SetCurrentEglType(current); |
|
4063 |
|
4064 // Make sure that full Canvas area |
|
4065 // is made transparent in next ClearFrameBuffer() call. |
|
4066 // This is needed in case UpdateOffScreenBitmapL is called |
|
4067 // from Nokia UI API |
|
4068 iUpperUpdateRect = TRect(Size()); |
|
4069 |
|
4070 DEBUG("CMIDCanvas::UpdateOffScreenBitmapL() --"); |
|
4071 } |
|
4072 } |
|
4073 |
|
4074 // --------------------------------------------------------------------------- |
|
4075 // From MMIDComponentNgaExtension |
|
4076 // CMIDCanvas::UpdateOffScreenBitmap() |
|
4077 // --------------------------------------------------------------------------- |
|
4078 // |
|
4079 TBool CMIDCanvas::FillEglSurface(const TRect& aRect, const TRgb& aColor) |
|
4080 { |
|
4081 if (!IsEglAvailable() || |
|
4082 !iUpperUpdateRect.IsEmpty() || |
|
4083 !iLowerUpdateRect.IsEmpty()) |
|
4084 { |
|
4085 return EFalse; |
|
4086 } |
|
4087 TSize sz(this->GetEglSurfaceSize()); |
|
4088 if (aRect.Width() >= sz.iWidth && aRect.Height() >= sz.iHeight) |
|
4089 { |
|
4090 return ClearEglSurface(EEglNone, &aColor); |
|
4091 } |
|
4092 TEglType current = GetCurrentEglType(); |
|
4093 if (iScalingOn && iFullScreen) |
|
4094 { |
|
4095 if (current != EEglPbuffer) |
|
4096 { |
|
4097 SetCurrentEglType(EEglPbuffer); |
|
4098 } |
|
4099 } |
|
4100 else if (current != EEglWindow) |
|
4101 { |
|
4102 SetCurrentEglType(EEglWindow); |
|
4103 } |
|
4104 InitOpenGl(ETrue); |
|
4105 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
4106 glVertexPointer(2, GL_SHORT, 0, iVertexArray); |
|
4107 iVertexArray[0] = aRect.iTl.iX; |
|
4108 iVertexArray[1] = aRect.iTl.iY; |
|
4109 |
|
4110 iVertexArray[2] = aRect.iBr.iX; |
|
4111 iVertexArray[3] = aRect.iTl.iY; |
|
4112 |
|
4113 iVertexArray[4] = iVertexArray[2]; |
|
4114 iVertexArray[5] = aRect.iBr.iY; |
|
4115 |
|
4116 iVertexArray[6] = iVertexArray[0]; |
|
4117 iVertexArray[7] = iVertexArray[5]; |
|
4118 |
|
4119 glColor4f( |
|
4120 aColor.Red() / 255.0f, aColor.Green() / 255.0f, |
|
4121 aColor.Blue() / 255.0f, aColor.Alpha() / 255.0f); |
|
4122 |
|
4123 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, iTriangleStrip); |
|
4124 SetCurrentEglType(EEglNone); |
|
4125 return ETrue; |
|
4126 } |
|
4127 |
|
4128 // --------------------------------------------------------------------------- |
|
4129 // From CMIDCanvas |
|
4130 // CMIDCanvas::ClearEglSurface |
|
4131 // --------------------------------------------------------------------------- |
|
4132 // |
|
4133 TBool CMIDCanvas::ClearEglSurface( |
|
4134 CMIDCanvas::TEglType aSurfaceType, const TRgb* aRgba) |
|
4135 { |
|
4136 if (!IsEglAvailable()) |
|
4137 { |
|
4138 return EFalse; |
|
4139 } |
|
4140 TEglType current = GetCurrentEglType(); |
|
4141 if (aSurfaceType == EEglNone || aRgba == NULL) |
|
4142 { |
|
4143 if (iScalingOn && iFullScreen) |
|
4144 { |
|
4145 if (aSurfaceType == EEglNone) |
|
4146 { |
|
4147 aSurfaceType = EEglPbuffer; |
|
4148 } |
|
4149 if (aRgba == NULL) |
|
4150 { |
|
4151 glClearColor(0.f, 0.f, 0.f, 1.f); |
|
4152 } |
|
4153 } |
|
4154 else |
|
4155 { |
|
4156 if (aSurfaceType == EEglNone) |
|
4157 { |
|
4158 aSurfaceType = EEglWindow; |
|
4159 } |
|
4160 if (aRgba == NULL) |
|
4161 { |
|
4162 glClearColor(1.f, 1.f, 1.f, 1.f); |
|
4163 } |
|
4164 } |
|
4165 } |
|
4166 SetCurrentEglType(aSurfaceType); |
|
4167 if (aRgba != NULL) |
|
4168 { |
|
4169 glClearColor( |
|
4170 aRgba->Red() / 255.f, aRgba->Green() / 255.0f, |
|
4171 aRgba->Blue() / 255.0f, aRgba->Alpha() / 255.0f); |
|
4172 } |
|
4173 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
4174 SetCurrentEglType(current); |
|
4175 return ETrue; |
|
4176 } |
|
4177 |
|
4178 // --------------------------------------------------------------------------- |
|
4179 // From MMIDCanvas |
|
4180 // CMIDCanvas::UpdateRect |
|
4181 // Notifies canvas about which areas have been updated with 2D content. |
|
4182 // --------------------------------------------------------------------------- |
|
4183 // |
|
4184 void CMIDCanvas::UpdateRect(const TRect& aRect) |
|
4185 { |
|
4186 if (aRect.IsEmpty()) |
|
4187 { |
|
4188 return; |
|
4189 } |
|
4190 |
|
4191 TRect rect(aRect); |
|
4192 TRect canvasRect = IsDownScaling(iContentSize, iViewRect) ? |
|
4193 TRect(iViewRect.Size()) : TRect(iContentSize); |
|
4194 rect.Intersection(canvasRect); |
|
4195 |
|
4196 // Update the member rects |
|
4197 if (iUpperUpdateRect.Intersects(rect)) |
|
4198 { |
|
4199 iUpperUpdateRect.BoundingRect(rect); |
|
4200 } |
|
4201 else if (iLowerUpdateRect.Intersects(rect)) |
|
4202 { |
|
4203 iLowerUpdateRect.BoundingRect(rect); |
|
4204 } |
|
4205 // If rect is fully in the lower half of canvas, |
|
4206 // merge it with iLowerUpdateRect, otherwise with iUpperUpdateRect |
|
4207 else if (rect.iTl.iY > canvasRect.Height() / 2) |
|
4208 { |
|
4209 if (iLowerUpdateRect.IsEmpty()) |
|
4210 { |
|
4211 iLowerUpdateRect = rect; |
|
4212 } |
|
4213 else |
|
4214 { |
|
4215 iLowerUpdateRect.BoundingRect(rect); |
|
4216 } |
|
4217 } |
|
4218 else |
|
4219 { |
|
4220 if (iUpperUpdateRect.IsEmpty()) |
|
4221 { |
|
4222 iUpperUpdateRect = rect; |
|
4223 } |
|
4224 else |
|
4225 { |
|
4226 iUpperUpdateRect.BoundingRect(rect); |
|
4227 } |
|
4228 } |
|
4229 } |
|
4230 |
|
4231 // --------------------------------------------------------------------------- |
|
4232 // CMIDCanvas::BlitFrameBufferPixels |
|
4233 // Sets up OpenGL state for 2D texture rendering and renders the textures for |
|
4234 // updated frame buffer areas by calling BlitSubRect(). |
|
4235 // --------------------------------------------------------------------------- |
|
4236 // |
|
4237 void CMIDCanvas::BlitFrameBufferPixels() |
|
4238 { |
|
4239 if (iUpperUpdateRect.IsEmpty() && iLowerUpdateRect.IsEmpty()) |
|
4240 { |
|
4241 return; |
|
4242 } |
|
4243 InitOpenGl(); |
|
4244 // Must use this blending function because frame buffer |
|
4245 // content is in pre-multiplied ARGB format. |
|
4246 // See alpha blending in Lcdgd, lcdc16ma.cpp. |
|
4247 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); |
|
4248 |
|
4249 glEnable(GL_ALPHA_TEST); |
|
4250 glAlphaFunc(GL_GREATER, 0.0f); |
|
4251 |
|
4252 // Disable any stray state we don't want |
|
4253 glDisable(GL_CULL_FACE); |
|
4254 glDisableClientState(GL_NORMAL_ARRAY); |
|
4255 glDisableClientState(GL_COLOR_ARRAY); |
|
4256 glDisable(GL_LIGHTING); |
|
4257 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
|
4258 glDepthMask(GL_FALSE); |
|
4259 glDepthFunc(GL_ALWAYS); |
|
4260 |
|
4261 ASSERT_GL(); |
|
4262 |
|
4263 if (iUpperUpdateRect.Intersects(iLowerUpdateRect)) |
|
4264 { |
|
4265 iUpperUpdateRect.BoundingRect(iLowerUpdateRect); |
|
4266 iLowerUpdateRect = TRect(); |
|
4267 BlitSubRect(iUpperUpdateRect); |
|
4268 } |
|
4269 else |
|
4270 { |
|
4271 BlitSubRect(iUpperUpdateRect); |
|
4272 BlitSubRect(iLowerUpdateRect); |
|
4273 } |
|
4274 |
|
4275 ClearFrameBuffer(); |
|
4276 } |
|
4277 |
|
4278 // --------------------------------------------------------------------------- |
|
4279 // CMIDCanvas::InitOpenGl |
|
4280 // Initiazes OpenGL before 2d rendering |
|
4281 // --------------------------------------------------------------------------- |
|
4282 // |
|
4283 TSize CMIDCanvas::InitOpenGl(TBool aTopLeftOrigo, const TRect* aRect) |
|
4284 { |
|
4285 // scaling is on the framebuffer is blitted to pbuffer instead of |
|
4286 // window surface so get the size of appropriate surface for |
|
4287 // setting correct values for viewport, projection etc. |
|
4288 TSize size = GetEglSurfaceSize(); |
|
4289 glViewport(0, 0, size.iWidth, size.iHeight); |
|
4290 if (aRect) |
|
4291 { |
|
4292 glScissor(aRect->iTl.iX, aRect->iTl.iY, aRect->Width(), aRect->Height()); |
|
4293 } |
|
4294 else |
|
4295 { |
|
4296 glScissor(0, 0, size.iWidth, size.iHeight); |
|
4297 } |
|
4298 glEnable(GL_BLEND); |
|
4299 glMatrixMode(GL_PROJECTION); |
|
4300 glLoadIdentity(); |
|
4301 // Checks where the origo should be |
|
4302 if (aTopLeftOrigo) |
|
4303 { |
|
4304 // Top-left |
|
4305 glOrthof(0, TReal32(size.iWidth), TReal32(size.iHeight), 0.f, -1.f, 1.f); |
|
4306 } |
|
4307 else |
|
4308 { |
|
4309 // Bottom-left |
|
4310 glOrthox(0, size.iWidth << 16, 0, size.iHeight << 16, -1 << 16, 1 << 16); |
|
4311 } |
|
4312 glMatrixMode(GL_MODELVIEW); |
|
4313 glLoadIdentity(); |
|
4314 glDisable(GL_DEPTH_TEST); |
|
4315 glEnableClientState(GL_VERTEX_ARRAY); |
|
4316 glDisable(GL_LIGHTING); |
|
4317 glDepthMask(GL_FALSE); |
|
4318 glDepthFunc(GL_ALWAYS); |
|
4319 return size; |
|
4320 } |
|
4321 |
|
4322 // --------------------------------------------------------------------------- |
|
4323 // CMIDCanvas::BlitSubRect |
|
4324 // OpenGL texture dimensions must be powers of 2. Devides aRect into smaller |
|
4325 // areas for texture rendering so that texture dimensions won't exceed |
|
4326 // KMaxBlitSize. |
|
4327 // --------------------------------------------------------------------------- |
|
4328 // |
|
4329 void CMIDCanvas::BlitSubRect(const TRect& aRect) |
|
4330 { |
|
4331 if (aRect.IsEmpty()) |
|
4332 { |
|
4333 return; |
|
4334 } |
|
4335 |
|
4336 // OpenGL coordinate origin is in bottom left corner of screen |
|
4337 TInt yOffset = iContentSize.iHeight - aRect.iBr.iY; |
|
4338 TInt xOffset = aRect.iTl.iX; |
|
4339 TInt width = aRect.Width(); |
|
4340 TInt height = aRect.Height(); |
|
4341 |
|
4342 TInt canvasHeight = iContentSize.iHeight; |
|
4343 |
|
4344 TInt xBlits = (width == KMaxBlitSize) ? 1 : (width / KMaxBlitSize) + 1; |
|
4345 TInt yBlits = (height == KMaxBlitSize) ? 1 : (height / KMaxBlitSize) + 1; |
|
4346 |
|
4347 TInt stride = iFrameBuffer->ScanLineLength( |
|
4348 iFrameBuffer->SizeInPixels().iWidth, iFrameBuffer->DisplayMode()); |
|
4349 |
|
4350 for (TInt yBlit = 0; yBlit < yBlits; ++yBlit) |
|
4351 { |
|
4352 for (TInt xBlit = 0; xBlit < xBlits; ++xBlit) |
|
4353 { |
|
4354 |
|
4355 TInt xStart = xOffset + xBlit * KMaxBlitSize; |
|
4356 TInt yStart = yOffset + yBlit * KMaxBlitSize; |
|
4357 TInt xSize = Min(KMaxBlitSize, width - (xStart - xOffset)); |
|
4358 TInt ySize = Min(KMaxBlitSize, height - (yStart - yOffset)); |
|
4359 |
|
4360 // The first rectangle will be in bottom left corner, |
|
4361 // then rectangle is moved right and upwards. |
|
4362 // OpenGL y-coordinate increases upwards. |
|
4363 TInt srcOffset = (canvasHeight - (yStart + ySize)) * stride + |
|
4364 xStart * KBytesPerPixel; |
|
4365 |
|
4366 BlitSubRectTexture(xStart, yStart, xSize, ySize, stride, |
|
4367 (TUint8*)iFrameBuffer->DataAddress() + srcOffset); |
|
4368 } |
|
4369 } |
|
4370 } |
|
4371 |
|
4372 |
|
4373 // --------------------------------------------------------------------------- |
|
4374 // CMIDCanvas::BlitSubRectTexture |
|
4375 // Creates OpenGL texture from the pixels passed as a parameter and draws |
|
4376 // texture to the current EGL surface. |
|
4377 // --------------------------------------------------------------------------- |
|
4378 // |
|
4379 void CMIDCanvas::BlitSubRectTexture(TInt aXOffset, TInt aYOffset, |
|
4380 TInt aWidth, TInt aHeight, |
|
4381 TInt aStride, const TUint8* aPixels) |
|
4382 { |
|
4383 DEBUG_INT4("BlitSubRectTextureL: aXOffset=%d, aYOffset=%d, aWidth=%d, aHeight=%d", |
|
4384 aXOffset, aYOffset, aWidth, aHeight); |
|
4385 DEBUG_INT("BlitSubRectTextureL: aStride=%d", aStride); |
|
4386 |
|
4387 ASSERT((aWidth > 0) && (aWidth <= 256)); |
|
4388 ASSERT((aHeight > 0) && (aHeight <= 256)); |
|
4389 ASSERT(iTexturePixels); |
|
4390 ASSERT_GL(); |
|
4391 |
|
4392 TInt tileWidth = KMaxBlitSize; |
|
4393 TInt tileHeight = KMaxBlitSize; |
|
4394 |
|
4395 // Tweak tile size to avoid using excessive amounts of memory for |
|
4396 // portions outside the blit area |
|
4397 while (tileWidth >= aWidth * 2) |
|
4398 { |
|
4399 tileWidth >>= 1; |
|
4400 tileHeight <<= 1; |
|
4401 } |
|
4402 |
|
4403 while (tileHeight >= aHeight * 2) |
|
4404 { |
|
4405 tileHeight >>= 1; |
|
4406 } |
|
4407 |
|
4408 glActiveTexture(GL_TEXTURE0); |
|
4409 glEnable(GL_TEXTURE_2D); |
|
4410 |
|
4411 TUint tempTexObj[KTexturesCount]; |
|
4412 glGenTextures(KTexturesCount, tempTexObj); |
|
4413 |
|
4414 glBindTexture(GL_TEXTURE_2D, tempTexObj[0]); |
|
4415 |
|
4416 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
|
4417 |
|
4418 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
4419 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
4420 |
|
4421 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
|
4422 tileWidth, tileHeight, 0, |
|
4423 GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
|
4424 |
|
4425 // Raise out-of-memory if OpenGL ran out of resources |
|
4426 GLint err = glGetError(); |
|
4427 if (err == GL_OUT_OF_MEMORY) |
|
4428 { |
|
4429 glDeleteTextures(KTexturesCount, tempTexObj); |
|
4430 DEBUG("CMIDCanvas::BlitSubRectTexture(): Out of memory when creating OpenGL texture"); |
|
4431 return; |
|
4432 } |
|
4433 else if (err != GL_NO_ERROR) |
|
4434 { |
|
4435 ELOG1(EJavaUI, "CMIDCanvas::BlitSubRectTexture(): GL error after glTexImage2D(): %d", err); |
|
4436 ASSERT(EFalse); |
|
4437 } |
|
4438 |
|
4439 // Set up texture and vertex coordinate arrays for the image tiles |
|
4440 const TUint8 tc[8] = { 0, 0, 0, 1, 1, 0, 1, 1 }; |
|
4441 GLshort pos[8]; |
|
4442 |
|
4443 glClientActiveTexture(GL_TEXTURE0); |
|
4444 glTexCoordPointer(2, GL_BYTE, 0, tc); |
|
4445 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
4446 glVertexPointer(2, GL_SHORT, 0, pos); |
|
4447 glEnableClientState(GL_VERTEX_ARRAY); |
|
4448 glMatrixMode(GL_TEXTURE); |
|
4449 glLoadIdentity(); |
|
4450 glMatrixMode(GL_MODELVIEW); |
|
4451 |
|
4452 ASSERT_GL(); |
|
4453 |
|
4454 glBindTexture(GL_TEXTURE_2D, tempTexObj[0]); |
|
4455 TUint8* dst = iTexturePixels; |
|
4456 const TUint8* src = aPixels; |
|
4457 |
|
4458 TInt h = aHeight; |
|
4459 |
|
4460 if (tileWidth > aWidth || |
|
4461 tileHeight > aHeight) |
|
4462 { |
|
4463 // Clear the pixel data with transparent for case where |
|
4464 // actual texture data does not cover the full tile. |
|
4465 // This should be actually done with glClear(). |
|
4466 Mem::FillZ(dst, tileWidth * tileHeight * KBytesPerPixel); |
|
4467 dst += tileWidth * (tileHeight - aHeight) * KBytesPerPixel; |
|
4468 } |
|
4469 |
|
4470 while (h-- > 0) |
|
4471 { |
|
4472 ConvertPixels((TUint32*)src, dst, aWidth); |
|
4473 src += aStride; |
|
4474 dst += tileWidth * KBytesPerPixel; |
|
4475 } |
|
4476 |
|
4477 glTexSubImage2D(GL_TEXTURE_2D, 0, |
|
4478 0, 0, |
|
4479 tileWidth, tileHeight, |
|
4480 GL_RGBA, GL_UNSIGNED_BYTE, iTexturePixels); |
|
4481 |
|
4482 // If scaling is on and pbuffer is used, the framebuffer contents |
|
4483 // must be positioned to the top part of the puffer as m3g renders |
|
4484 // there as well, thus 2D and 3D content are correctly on top of each other |
|
4485 if (iScalingOn && iFullScreen) |
|
4486 { |
|
4487 TSize pbufferSize = GetEglSurfaceSize(iEglPbufferSurface); |
|
4488 TInt offset = pbufferSize.iHeight - iContentSize.iHeight; |
|
4489 |
|
4490 pos[0] = (GLshort)aXOffset; |
|
4491 pos[1] = (GLshort)(tileHeight + aYOffset + offset); |
|
4492 pos[2] = pos[0]; |
|
4493 pos[3] = (GLshort)aYOffset + offset; |
|
4494 pos[4] = (GLshort)(tileWidth + aXOffset); |
|
4495 pos[5] = pos[1]; |
|
4496 pos[6] = pos[4]; |
|
4497 pos[7] = pos[3]; |
|
4498 } |
|
4499 else |
|
4500 { |
|
4501 pos[0] = (GLshort)aXOffset; |
|
4502 pos[1] = (GLshort)(tileHeight + aYOffset); |
|
4503 pos[2] = pos[0]; |
|
4504 pos[3] = (GLshort)aYOffset; |
|
4505 pos[4] = (GLshort)(tileWidth + aXOffset); |
|
4506 pos[5] = pos[1]; |
|
4507 pos[6] = pos[4]; |
|
4508 pos[7] = pos[3]; |
|
4509 } |
|
4510 |
|
4511 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
|
4512 |
|
4513 // release resources |
|
4514 glDeleteTextures(KTexturesCount, tempTexObj); |
|
4515 ASSERT_GL(); |
|
4516 } |
|
4517 |
|
4518 // --------------------------------------------------------------------------- |
|
4519 // CMIDCanvas::CreatePBufferSurfaceL |
|
4520 // Create EGL pbuffer to be used in scaling case. |
|
4521 // --------------------------------------------------------------------------- |
|
4522 // |
|
4523 void CMIDCanvas::CreatePBufferSurfaceL() |
|
4524 { |
|
4525 DEBUG("CMIDCanvas::CreatePBufferSurface() ++"); |
|
4526 ASSERT(iEglDisplay != EGL_NO_DISPLAY); |
|
4527 |
|
4528 RWindow& window = Window(); |
|
4529 |
|
4530 // Choose the buffer size based on the Window's display mode. |
|
4531 TDisplayMode displayMode = window.DisplayMode(); |
|
4532 TInt bufferSize = 0; |
|
4533 switch (displayMode) |
|
4534 { |
|
4535 case(EColor16MU): |
|
4536 case(EColor16MA): |
|
4537 case(EColor16MAP): |
|
4538 bufferSize = 32; |
|
4539 break; |
|
4540 default: |
|
4541 ELOG1(EJavaUI, "CMIDCanvas::OpenEglL(): unsupported window display mode %d", |
|
4542 displayMode); |
|
4543 User::Leave(KErrNotSupported); |
|
4544 break; |
|
4545 } |
|
4546 |
|
4547 // Set the desired properties for the EGLSurface |
|
4548 const EGLint attributeList[] = |
|
4549 { |
|
4550 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
|
4551 EGL_RED_SIZE, 8, |
|
4552 EGL_GREEN_SIZE, 8, |
|
4553 EGL_BLUE_SIZE, 8, |
|
4554 EGL_ALPHA_SIZE, 8, |
|
4555 EGL_BUFFER_SIZE, bufferSize, |
|
4556 EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE, |
|
4557 EGL_TRANSPARENT_TYPE, EGL_NONE, |
|
4558 EGL_DEPTH_SIZE, 16, |
|
4559 EGL_NONE |
|
4560 }; |
|
4561 |
|
4562 EGLConfig bestConfig; |
|
4563 EGLint numConfigs = 0; |
|
4564 |
|
4565 // Choose the best EGLConfig that matches the desired properties. |
|
4566 if (!eglChooseConfig(iEglDisplay, attributeList, &bestConfig, 1, &numConfigs) || |
|
4567 numConfigs == 0) |
|
4568 { |
|
4569 ELOG1(EJavaUI, "eglChooseConfig() for pbuffer failed, eglError=%d", eglGetError()); |
|
4570 User::Leave(KErrNotSupported); |
|
4571 } |
|
4572 |
|
4573 // find buffer size based on the framebuffer size |
|
4574 // pbuffer size must be power of two so that it can be bound |
|
4575 // as texture image |
|
4576 TInt width = 2; |
|
4577 TInt height = 2; |
|
4578 |
|
4579 while (width < iContentSize.iWidth) |
|
4580 { |
|
4581 width <<= 1; |
|
4582 } |
|
4583 while (height < iContentSize.iHeight) |
|
4584 { |
|
4585 height <<= 1; |
|
4586 } |
|
4587 |
|
4588 DEBUG_INT4("CMIDCanvas::CreatePBufferSurface - pbuffer size resolved as (width=%d, height=%d), contentSize(%d, %d)", |
|
4589 width, height, iContentSize.iWidth, iContentSize.iHeight); |
|
4590 |
|
4591 // Special attributes in order for binding this surface as texture image |
|
4592 EGLint attrib[] = |
|
4593 { |
|
4594 EGL_WIDTH, width, |
|
4595 EGL_HEIGHT, height, |
|
4596 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, |
|
4597 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, |
|
4598 EGL_MIPMAP_TEXTURE, EGL_TRUE, |
|
4599 EGL_NONE |
|
4600 }; |
|
4601 |
|
4602 iEglPbufferSurface = eglCreatePbufferSurface(iEglDisplay, bestConfig, attrib); |
|
4603 if (iEglPbufferSurface == EGL_NO_SURFACE) |
|
4604 { |
|
4605 ELOG1(EJavaUI, "eglCreatePbufferSurface() failed, eglError=%d", eglGetError()); |
|
4606 User::Leave(KErrNoMemory); |
|
4607 } |
|
4608 |
|
4609 // Create a rendering context |
|
4610 iEglPbufferSurfaceContext = eglCreateContext(iEglDisplay, bestConfig, NULL, NULL); |
|
4611 if (iEglPbufferSurfaceContext == EGL_NO_CONTEXT) |
|
4612 { |
|
4613 ELOG1(EJavaUI, "eglCreateContext() for pbuffer failed, eglError=%d", eglGetError()); |
|
4614 User::Leave(KErrNoMemory); |
|
4615 } |
|
4616 |
|
4617 DEBUG("CMIDCanvas::CreatePBufferSurface() --"); |
|
4618 } |
|
4619 |
|
4620 // --------------------------------------------------------------------------- |
|
4621 // CMIDCanvas::DisposePBufferSurface |
|
4622 // Destroys EGL pbuffer surface and context. |
|
4623 // --------------------------------------------------------------------------- |
|
4624 // |
|
4625 void CMIDCanvas::DisposePBufferSurface() |
|
4626 { |
|
4627 if (iEglPbufferSurfaceContext != EGL_NO_CONTEXT) |
|
4628 { |
|
4629 eglDestroyContext(iEglDisplay, iEglPbufferSurfaceContext); |
|
4630 iEglPbufferSurfaceContext = EGL_NO_CONTEXT; |
|
4631 |
|
4632 // textures are destoyed along with the context so it's safe |
|
4633 // set texture name to zero |
|
4634 iPbufferTexture = 0; |
|
4635 } |
|
4636 if (iEglPbufferSurface != EGL_NO_SURFACE) |
|
4637 { |
|
4638 eglDestroySurface(iEglDisplay, iEglPbufferSurface); |
|
4639 iEglPbufferSurface = EGL_NO_SURFACE; |
|
4640 } |
|
4641 } |
|
4642 |
|
4643 // --------------------------------------------------------------------------- |
|
4644 // CMIDCanvas::BlitPBufferScaledToWindowSurface |
|
4645 // In scaling case renders and scales pbuffer content (=canvas 2D + 3D |
|
4646 // content in orig size) to EGL window surface. |
|
4647 // --------------------------------------------------------------------------- |
|
4648 // |
|
4649 void CMIDCanvas::BlitPBufferScaledToWindowSurface() |
|
4650 { |
|
4651 DEBUG("CMIDCanvas::BlitPBufferScaledToWindowSurface() ++"); |
|
4652 |
|
4653 // Get screen size for setting clips and |
|
4654 // parallel projection correctly |
|
4655 TRect screenRect = Rect(); |
|
4656 TInt width = screenRect.Width(); |
|
4657 TInt height = screenRect.Height(); |
|
4658 |
|
4659 glScissor(0, 0, width, height); |
|
4660 glViewport(0, 0, width, height); |
|
4661 glMatrixMode(GL_PROJECTION); |
|
4662 glLoadIdentity(); |
|
4663 |
|
4664 glOrthox(0, width << 16, |
|
4665 0, height << 16, |
|
4666 -1 << 16, 1 << 16); |
|
4667 |
|
4668 glMatrixMode(GL_MODELVIEW); |
|
4669 glLoadIdentity(); |
|
4670 |
|
4671 glActiveTexture(GL_TEXTURE0); |
|
4672 glEnable(GL_TEXTURE_2D); |
|
4673 |
|
4674 // generate texture name if not already generated |
|
4675 if (glIsTexture(iPbufferTexture) == GL_FALSE) |
|
4676 { |
|
4677 glGenTextures(1, &iPbufferTexture); |
|
4678 } |
|
4679 |
|
4680 glBindTexture(GL_TEXTURE_2D, iPbufferTexture); |
|
4681 if (eglBindTexImage(iEglDisplay, iEglPbufferSurface, EGL_BACK_BUFFER) == EGL_FALSE) |
|
4682 { |
|
4683 ELOG1(EJavaUI, "eglBindTexImage() failed, eglError=%d", eglGetError()); |
|
4684 ASSERT(EFalse); |
|
4685 } |
|
4686 |
|
4687 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
|
4688 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
4689 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
4690 |
|
4691 // calculate texture coordinates, i.e. the area in pbuffer |
|
4692 // that has the actual frame content |
|
4693 GLfloat contentWidth = iContentSize.iWidth; |
|
4694 GLfloat contentHeight = iContentSize.iHeight; |
|
4695 TSize bufferSize = GetEglSurfaceSize(iEglPbufferSurface); |
|
4696 GLfloat horRatio = contentWidth / bufferSize.iWidth; |
|
4697 GLfloat yoffset = (bufferSize.iHeight - contentHeight) / bufferSize.iHeight; |
|
4698 GLfloat tc[8] = { 0.0f, 1.0f, 0.0f, yoffset, horRatio, 1.0f, horRatio, yoffset}; |
|
4699 |
|
4700 GLshort pos[8]; |
|
4701 |
|
4702 ASSERT_GL(); |
|
4703 |
|
4704 glClientActiveTexture(GL_TEXTURE0); |
|
4705 glTexCoordPointer(2, GL_FLOAT, 0, tc); |
|
4706 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
4707 glVertexPointer(2, GL_SHORT, 0, pos); |
|
4708 glEnableClientState(GL_VERTEX_ARRAY); |
|
4709 glMatrixMode(GL_TEXTURE); |
|
4710 glLoadIdentity(); |
|
4711 |
|
4712 // position texture screen coordinates |
|
4713 pos[0] = (GLshort)iViewRect.iTl.iX; |
|
4714 pos[1] = (GLshort)iViewRect.Height() + (height - iViewRect.iBr.iY); |
|
4715 pos[2] = pos[0]; |
|
4716 pos[3] = (GLshort)height - iViewRect.iBr.iY; |
|
4717 pos[4] = (GLshort)iViewRect.iBr.iX; |
|
4718 pos[5] = pos[1]; |
|
4719 pos[6] = pos[4]; |
|
4720 pos[7] = pos[3]; |
|
4721 |
|
4722 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
|
4723 |
|
4724 // release pbuffer from texture |
|
4725 eglReleaseTexImage(iEglDisplay, iEglPbufferSurface, EGL_BACK_BUFFER); |
|
4726 |
|
4727 DEBUG("CMIDCanvas::BlitPBufferScaledToWindowSurface() --"); |
|
4728 } |
|
4729 |
|
4730 |
|
4731 // --------------------------------------------------------------------------- |
|
4732 // CMIDCanvas::ClearFrameBuffer |
|
4733 // Clears the frame buffer with fully transparent color. Rendering canvas 2D |
|
4734 // content as an OpenGL texture requires that texture is transparent in |
|
4735 // the areas where no 2D content has been drawn. |
|
4736 // --------------------------------------------------------------------------- |
|
4737 // |
|
4738 void CMIDCanvas::ClearFrameBuffer() |
|
4739 { |
|
4740 if (!iM3GStart && iUpperUpdateRect.IsEmpty() && iLowerUpdateRect.IsEmpty()) |
|
4741 { |
|
4742 return; |
|
4743 } |
|
4744 // Clear the frame buffer |
|
4745 iFrameContext->SetBrushColor(KTransparentClearColor); |
|
4746 iFrameContext->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); |
|
4747 |
|
4748 iFrameContext->Clear(iUpperUpdateRect); |
|
4749 iFrameContext->Clear(iLowerUpdateRect); |
|
4750 |
|
4751 // Reset members |
|
4752 iUpperUpdateRect.SetRect(0,0,0,0); |
|
4753 iLowerUpdateRect.SetRect(0,0,0,0); |
|
4754 } |
|
4755 |
|
4756 |
|
4757 // --------------------------------------------------------------------------- |
|
4758 // CMIDCanvas::AssertGL |
|
4759 // Check for OpenGL ES errors. Only for debug builds. |
|
4760 // --------------------------------------------------------------------------- |
|
4761 // |
|
4762 void CMIDCanvas::AssertGL() |
|
4763 { |
|
4764 GLint err = glGetError(); |
|
4765 if (err == GL_NO_ERROR) |
|
4766 { |
|
4767 return; |
|
4768 } |
|
4769 else |
|
4770 { |
|
4771 ELOG1(EJavaUI, "OpenGL ES error=%d", err); |
|
4772 ASSERT(EFalse); |
|
4773 } |
|
4774 } |
|
4775 |
|
4776 // --------------------------------------------------------------------------- |
|
4777 // CMIDCanvas::AssertGL |
|
4778 // Check for OpenGL ES errors. Only for debug builds. |
|
4779 // --------------------------------------------------------------------------- |
|
4780 // |
|
4781 const TDesC8& CMIDCanvas::GetEglError(EGLint aErr) |
|
4782 { |
|
4783 _LIT8(KEglSuccess, "EGL_SUCCESS"); |
|
4784 _LIT8(KEglNotInitialized, "EGL_NOT_INITIALIZED"); |
|
4785 _LIT8(KEglBadAccess, "EGL_BAD_ACCESS"); |
|
4786 _LIT8(KEglBadAlloc, "EGL_BAD_ALLOC"); |
|
4787 _LIT8(KEglBadAttribute, "EGL_BAD_ATTRIBUTE"); |
|
4788 _LIT8(KEglBadContext, "EGL_BAD_CONTEXT"); |
|
4789 _LIT8(KEglBadConfig, "EGL_BAD_CONFIG"); |
|
4790 _LIT8(KEglBadCurrentSurface, "EGL_BAD_CURRENT_SURFACE"); |
|
4791 _LIT8(KEglBadDisplay, "EGL_BAD_DISPLAY"); |
|
4792 _LIT8(KEglBadSurface, "EGL_BAD_SURFACE"); |
|
4793 _LIT8(KEglBadMatch, "EGL_BAD_MATCH"); |
|
4794 _LIT8(KEglBadParameter, "EGL_BAD_PARAMETER"); |
|
4795 _LIT8(KEglBadNativePixmap, "EGL_BAD_NATIVE_PIXMAP"); |
|
4796 _LIT8(KEglBadNativeWindow, "EGL_BAD_NATIVE_WINDOW"); |
|
4797 switch (aErr) |
|
4798 { |
|
4799 case EGL_NOT_INITIALIZED: |
|
4800 return KEglNotInitialized; |
|
4801 case EGL_BAD_ACCESS: |
|
4802 return KEglBadAccess; |
|
4803 case EGL_BAD_ALLOC: |
|
4804 return KEglBadAlloc; |
|
4805 case EGL_BAD_ATTRIBUTE: |
|
4806 return KEglBadAttribute; |
|
4807 case EGL_BAD_CONTEXT: |
|
4808 return KEglBadContext; |
|
4809 case EGL_BAD_CONFIG: |
|
4810 return KEglBadConfig; |
|
4811 case EGL_BAD_CURRENT_SURFACE: |
|
4812 return KEglBadCurrentSurface; |
|
4813 case EGL_BAD_DISPLAY: |
|
4814 return KEglBadDisplay; |
|
4815 case EGL_BAD_SURFACE: |
|
4816 return KEglBadSurface; |
|
4817 case EGL_BAD_MATCH: |
|
4818 return KEglBadMatch; |
|
4819 case EGL_BAD_PARAMETER: |
|
4820 return KEglBadParameter; |
|
4821 case EGL_BAD_NATIVE_PIXMAP: |
|
4822 return KEglBadNativePixmap; |
|
4823 case EGL_BAD_NATIVE_WINDOW: |
|
4824 return KEglBadNativeWindow; |
|
4825 } |
|
4826 return KEglSuccess; |
|
4827 } |
|
4828 |
|
4829 |
|
4830 #endif // RD_JAVA_NGA_ENABLED |
|
4831 // End of File. |