|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Client window functions |
|
15 // |
|
16 // |
|
17 |
|
18 #include "W32CLICK.H" |
|
19 #include <graphics/wselement.h> |
|
20 #include "server.h" |
|
21 #include "cliwin.h" |
|
22 #include "gc.h" |
|
23 #include "rootwin.h" |
|
24 #include "windowgroup.h" |
|
25 #include "walkwindowtree.h" |
|
26 #include "ScrDev.H" |
|
27 #include "wstop.h" |
|
28 #include "EVQUEUE.H" |
|
29 #include "KEYCLICK.H" |
|
30 #include "panics.h" |
|
31 #include "password.h" |
|
32 #include "pointer.h" |
|
33 #include "EVENT.H" |
|
34 #include "backedupwindow.h" |
|
35 #include "redrawmsgwindow.h" |
|
36 #include "windowelementset.h" |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 TBool CWsClientWindow::iAbsoluteFading = EFalse; |
|
42 |
|
43 const TPoint corner1[1]={TPoint(1,1)}; |
|
44 const TPoint corner2[2]={TPoint(2,1),TPoint(1,1)}; |
|
45 const TPoint corner3[2]={TPoint(3,1),TPoint(1,2)}; |
|
46 const TPoint corner5[4]={TPoint(5,1),TPoint(3,1),TPoint(2,1),TPoint(1,2)}; |
|
47 |
|
48 /*CWsClientWindow*/ |
|
49 |
|
50 CWsClientWindow::CWsClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsWindow(aOwner,WS_HANDLE_WINDOW,aScreen) |
|
51 { |
|
52 iWinType=EWinTypeClient; |
|
53 } |
|
54 |
|
55 void CWsClientWindow::ConstructL(const TWsClCmdCreateWindow &aCmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid) |
|
56 { |
|
57 CWsWindow::Construct(); |
|
58 NewObjL(); |
|
59 if (aCmd.clientHandle==NULL) |
|
60 OwnerPanic(EWservPanicNullHandle); |
|
61 #if defined(_DEBUG) |
|
62 if (IsClientHandleInUse(aCmd.clientHandle)) |
|
63 OwnerPanic(EWservPanicDuplicateHandle); |
|
64 #endif |
|
65 iPointerFilter=EPointerFilterEnterExit|EPointerFilterMove|EPointerFilterDrag; |
|
66 iClientHandle=aCmd.clientHandle; |
|
67 CWsWindow* inherit=static_cast<CWsWindow *>(aParent); |
|
68 if (aParent->WinType()==EWinTypeGroup) |
|
69 inherit=RootWindow(); |
|
70 SetPointerCursor(aParent->PointerCursor()); |
|
71 iAbs=inherit->Abs(); |
|
72 iOrigin=aParent->Origin(); |
|
73 iRel.iBr.iX=inherit->Rel().iBr.iX-inherit->Rel().iTl.iX; |
|
74 iRel.iBr.iY=inherit->Rel().iBr.iY-inherit->Rel().iTl.iY; |
|
75 switch(aCmd.type) |
|
76 { |
|
77 case EWinRedraw: |
|
78 iRedraw=new(ELeave) CWsRedrawMsgWindow(this); |
|
79 break; |
|
80 case EWinBackedUp: |
|
81 iRedraw=new(ELeave) CWsBackedUpWindow(this, aCmd.displayMode); |
|
82 iAbs.iBr=iAbs.iTl; |
|
83 iRel.iBr=iRel.iTl; |
|
84 break; |
|
85 case EWinBlank: |
|
86 iRedraw=new(ELeave) CWsBlankWindow(this); |
|
87 break; |
|
88 default: |
|
89 OwnerPanic(EWservPanicRedrawType); |
|
90 } |
|
91 ResetHiddenFlag(); |
|
92 SetCornerTypeL(EWindowCornerSquare,0,NULL,EFalse); |
|
93 CWsWindowBase::ConstructL(aParent); |
|
94 if (aScreenDeviceIsInvalid) |
|
95 { |
|
96 iFlags|=EFlagScreenDeviceInvalid; |
|
97 ResetHiddenFlag(); |
|
98 } |
|
99 iRedraw->ConstructL(); |
|
100 } |
|
101 |
|
102 void CWsClientWindow::GetBaseAreaOfNode(RWsRegion &aRegion) const |
|
103 { |
|
104 if (iBaseArea) |
|
105 { |
|
106 aRegion.Copy(*iBaseArea); |
|
107 } |
|
108 aRegion.ClipRect(iAbs); |
|
109 } |
|
110 |
|
111 void CWsClientWindow::ClipRegionToBaseArea(RWsRegion &aRegion) const |
|
112 { |
|
113 if (iBaseArea) |
|
114 { |
|
115 aRegion.Intersect(*iBaseArea); |
|
116 } |
|
117 aRegion.ClipRect(iAbs); |
|
118 } |
|
119 |
|
120 void CWsClientWindow::GetClippedBaseArea(RWsRegion &aRegion) const |
|
121 { |
|
122 const CWsWindowBase* ancestor = BaseParent(); |
|
123 GetBaseAreaOfNode(aRegion); |
|
124 while (ancestor && ancestor->WinType() == EWinTypeClient) |
|
125 { |
|
126 static_cast<const CWsClientWindow*>(ancestor)->ClipRegionToBaseArea(aRegion); |
|
127 ancestor = ancestor->BaseParent(); |
|
128 } |
|
129 } |
|
130 |
|
131 void CWsClientWindow::GetOpaqueBaseAreaOfNode(RWsRegion &aRegion) const |
|
132 { |
|
133 if (IsTranslucent()) |
|
134 { |
|
135 if (iUserDefinedOpaqueRegion) |
|
136 { |
|
137 aRegion.Copy(*iUserDefinedOpaqueRegion); |
|
138 aRegion.ClipRect(iAbs); |
|
139 } |
|
140 else |
|
141 { |
|
142 aRegion.Clear(); |
|
143 } |
|
144 } |
|
145 else |
|
146 { |
|
147 GetBaseAreaOfNode(aRegion); |
|
148 } |
|
149 } |
|
150 |
|
151 void CWsClientWindow::ClipRegionToOpaqueBaseArea(RWsRegion& aRegion) const |
|
152 { |
|
153 if (IsTranslucent()) |
|
154 { |
|
155 if (iUserDefinedOpaqueRegion) |
|
156 { |
|
157 aRegion.Intersect(*iUserDefinedOpaqueRegion); |
|
158 aRegion.ClipRect(iAbs); |
|
159 } |
|
160 else |
|
161 { |
|
162 aRegion.Clear(); |
|
163 } |
|
164 } |
|
165 else |
|
166 { |
|
167 ClipRegionToBaseArea(aRegion); |
|
168 } |
|
169 } |
|
170 |
|
171 void CWsClientWindow::GetOpaqueClippedBaseArea(RWsRegion &aRegion) const |
|
172 { |
|
173 const CWsWindowBase* ancestor = BaseParent(); |
|
174 GetOpaqueBaseAreaOfNode(aRegion); |
|
175 while (ancestor && ancestor->WinType() == EWinTypeClient) |
|
176 { |
|
177 static_cast<const CWsClientWindow*>(ancestor)->ClipRegionToOpaqueBaseArea(aRegion); |
|
178 ancestor = ancestor->BaseParent(); |
|
179 } |
|
180 } |
|
181 |
|
182 TInt CWsClientWindow::GetNonOpaqueBaseAreaOfNode(RWsRegion &aRegion) const |
|
183 { |
|
184 aRegion.Clear(); |
|
185 if (IsTranslucent()) |
|
186 { |
|
187 if(iUserDefinedTransparentRegion) |
|
188 { |
|
189 aRegion.Copy(*iUserDefinedTransparentRegion); |
|
190 aRegion.ClipRect(iAbs); |
|
191 return KErrNone; |
|
192 } |
|
193 } |
|
194 return KErrNotFound; |
|
195 } |
|
196 |
|
197 void CWsClientWindow::ResetHiddenFlag() |
|
198 // |
|
199 // Reset the status of the hidden flag based on the current states of the active and invisible flags |
|
200 // |
|
201 { |
|
202 CWsClientWindow *parent=static_cast<CWsClientWindow*>(iParent); |
|
203 |
|
204 TBool wasHidden = iFlags&EFlagHidden; |
|
205 TBool nowHidden = (parent==NULL || |
|
206 (parent->WinType()==EWinTypeClient && !parent->IsVisible()) || |
|
207 !(iFlags&EFlagActive) || |
|
208 (iFlags&EFlagInvisible) || |
|
209 (iFlags&EFlagScreenDeviceInvalid)); |
|
210 |
|
211 if (nowHidden) |
|
212 { |
|
213 iFlags|=EFlagHidden; |
|
214 iFlags&=~EFlagDrawnToScreen; |
|
215 } |
|
216 else |
|
217 { |
|
218 iFlags&=~EFlagHidden; |
|
219 } |
|
220 if ((!nowHidden) != (!wasHidden)) |
|
221 { |
|
222 // intentionally call the screen directly |
|
223 iScreen->ScheduleRegionUpdate(&iVisibleRegion); |
|
224 |
|
225 WS_ASSERT_DEBUG(!iDirtyWindowRegion.CheckError(),EWsPanicErrorInRegion); |
|
226 WS_ASSERT_DEBUG(!iDirtySpriteRegion.CheckError(),EWsPanicErrorInRegion); |
|
227 // WS_ASSERT_DEBUG(!InvalidArea().CheckError(),EWsPanicErrorInRegion); //error flag in invalid area may be set in OOM cases |
|
228 //thus the assert statement is caused to fail |
|
229 if (wasHidden && iScreen->ChangeTracking() && |
|
230 (!iDirtyWindowRegion.IsEmpty() || !iDirtySpriteRegion.IsEmpty() || !InvalidArea().IsEmpty())) |
|
231 { |
|
232 // Window has just become visible, schedule it |
|
233 iScreen->ScheduleWindow(this); |
|
234 } |
|
235 } |
|
236 } |
|
237 |
|
238 void CWsClientWindow::ResetHiddenFlags() |
|
239 { |
|
240 CWsClientWindow *win=this; |
|
241 FOREVER |
|
242 { |
|
243 TUint oldHiddenFlag=win->iFlags&EFlagHidden; |
|
244 win->ResetHiddenFlag(); |
|
245 if ((win->iFlags&EFlagHidden)!=oldHiddenFlag) // If hidden status hasn't changed nothing to do |
|
246 { |
|
247 win->SetElementOpacity(IsVisible() ? 0xFF : 0x00); // Update element visibility |
|
248 if (win->Child()) |
|
249 { |
|
250 win=win->Child(); |
|
251 continue; |
|
252 } |
|
253 } |
|
254 if (win==this) |
|
255 return; |
|
256 while(!win->NextSibling()) |
|
257 { |
|
258 win=(CWsClientWindow *)win->BaseParent(); |
|
259 if (win==this) |
|
260 return; |
|
261 } |
|
262 win=win->NextSibling(); |
|
263 } // for loop ends |
|
264 } |
|
265 |
|
266 void CWsClientWindow::OffsetBaseArea(const TPoint &aOffset) |
|
267 { |
|
268 iBaseArea->Offset(aOffset); |
|
269 //If the given window's position changes, then update. |
|
270 if (aOffset.iX || aOffset.iY) |
|
271 { |
|
272 UpdateElementExtent(&aOffset); |
|
273 } |
|
274 } |
|
275 |
|
276 void CWsClientWindow::CalcBaseArea() |
|
277 // |
|
278 // The windows basic area before any clipping is done |
|
279 // |
|
280 { |
|
281 TInt cornerType=iCornerData&ECornerTypeMask; |
|
282 if (cornerType==EWindowCornerRegion) |
|
283 iBaseArea->ClipRect(FullRect()); |
|
284 else |
|
285 { |
|
286 TSize size=Size(); |
|
287 iBaseArea->Clear(); |
|
288 const TPoint *corners=NULL; |
|
289 TInt count=0; |
|
290 switch(cornerType) |
|
291 { |
|
292 case EWindowCorner1: |
|
293 count=sizeof(corner1)/sizeof(TPoint); |
|
294 corners=corner1; |
|
295 break; |
|
296 case EWindowCorner2: |
|
297 count=sizeof(corner2)/sizeof(TPoint); |
|
298 corners=corner2; |
|
299 break; |
|
300 case EWindowCorner3: |
|
301 count=sizeof(corner3)/sizeof(TPoint); |
|
302 corners=corner3; |
|
303 break; |
|
304 case EWindowCorner5: |
|
305 count=sizeof(corner5)/sizeof(TPoint); |
|
306 corners=corner5; |
|
307 break; |
|
308 default: |
|
309 break; |
|
310 } |
|
311 TInt top=0; |
|
312 TInt bot=size.iHeight; |
|
313 for(TInt index=0;index<count;index++) |
|
314 { |
|
315 TInt xadjust=corners[index].iX; |
|
316 TInt yadjust=corners[index].iY; |
|
317 if ((iCornerData&(EWindowCornerNotTL|EWindowCornerNotTR))!=(EWindowCornerNotTL|EWindowCornerNotTR)) |
|
318 { |
|
319 iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotTL?0:xadjust,top, |
|
320 size.iWidth-(iCornerData&EWindowCornerNotTR?0:xadjust),top+yadjust)); |
|
321 top+=yadjust; |
|
322 } |
|
323 if ((iCornerData&(EWindowCornerNotBL|EWindowCornerNotBR))!=(EWindowCornerNotBL|EWindowCornerNotBR)) |
|
324 { |
|
325 iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotBL?0:xadjust,bot-yadjust, |
|
326 size.iWidth-(iCornerData&EWindowCornerNotBR?0:xadjust),bot)); |
|
327 bot-=yadjust; |
|
328 } |
|
329 } |
|
330 iBaseArea->AddRect(TRect(0,top,size.iWidth,bot)); |
|
331 iBaseArea->Offset(Origin()); |
|
332 iBaseArea->ClipRect(FullRect()); |
|
333 iBaseArea->Sort(); |
|
334 } |
|
335 } |
|
336 |
|
337 void CWsClientWindow::GenerateArea(RWsRegion &aArea, TBool aClipTranslucent) const |
|
338 // |
|
339 // Create the window area list. |
|
340 // |
|
341 { |
|
342 aArea.Clear(); |
|
343 if (IsVisible()) |
|
344 { |
|
345 aArea.Copy(*iBaseArea); |
|
346 aArea.ClipRect(iAbs); |
|
347 const CWsClientWindow *win=this; |
|
348 FOREVER |
|
349 { |
|
350 if (win->IsTopClientWindow()) |
|
351 break; |
|
352 ClipWindows(aArea,(CWsClientWindow *)win->BaseParent()->BaseChild(),win,aClipTranslucent); |
|
353 win=(CWsClientWindow *)win->iParent; |
|
354 } |
|
355 TInt tidyCount=0; |
|
356 for(const CWsTopClientWindow *cwin=RootWindow()->FirstTopClientWindow();aArea.Count() && cwin!=win;cwin=cwin->NextSiblingMultiParent()) |
|
357 { |
|
358 if (!tidyCount--) |
|
359 { |
|
360 aArea.Tidy(); |
|
361 tidyCount=ETidyCountSetting; // Tidy every ETidyCountSetting times around |
|
362 } |
|
363 if (cwin->IsVisible()) |
|
364 { |
|
365 if (cwin->IsTranslucent() && !aClipTranslucent) |
|
366 { |
|
367 if (cwin->iUserDefinedOpaqueRegion) |
|
368 { |
|
369 aArea.SubRegion(*cwin->iUserDefinedOpaqueRegion); |
|
370 } |
|
371 } |
|
372 else |
|
373 { |
|
374 aArea.SubRegion(*cwin->iBaseArea); |
|
375 } |
|
376 } |
|
377 } |
|
378 aArea.Tidy(); |
|
379 } |
|
380 } |
|
381 |
|
382 void CWsClientWindow::ClipWindows(TRegion ®ion,const CWsClientWindow *start, const CWsClientWindow *end, TBool aClipTranslucent) |
|
383 // |
|
384 // Remove out of the region the opaque part of the abs rect of all the windows starting from 'start' |
|
385 // along the sibling list to (and not including) the end window. |
|
386 // |
|
387 { |
|
388 for(const CWsClientWindow *win=start;region.Count() && win!=end;win=win->NextSibling()) |
|
389 { |
|
390 if (win->IsVisible()) |
|
391 { |
|
392 if (win->IsTranslucent() && !aClipTranslucent) |
|
393 { |
|
394 if (win->iUserDefinedOpaqueRegion) |
|
395 { |
|
396 region.SubRegion(*win->iUserDefinedOpaqueRegion); |
|
397 } |
|
398 } |
|
399 else |
|
400 { |
|
401 region.SubRegion(*win->iBaseArea); |
|
402 } |
|
403 } |
|
404 } |
|
405 } |
|
406 |
|
407 void CWsClientWindow::GenerateTopRegion(RWsRegion& aRegion) const |
|
408 { |
|
409 GenerateArea(aRegion,ETrue); |
|
410 if (iChild) |
|
411 ClipWindows(aRegion,Child(),NULL,ETrue); |
|
412 } |
|
413 |
|
414 void CWsClientWindow::GenerateWindowRegion(RWsRegion &aRegion) const |
|
415 // |
|
416 // Calculate the windows clipping region without using the usual stored iArea or iRegion fields |
|
417 // this function is used by the screen backup code to calculate "what if" regions to work out |
|
418 // whether something would be visible if the backed up window didn't exist, on this basis we |
|
419 // don't want to modify the existing copies of iArea & iRegion. |
|
420 // |
|
421 { |
|
422 GenerateArea(aRegion,EFalse); |
|
423 if (iChild) |
|
424 ClipWindows(aRegion,Child(),NULL,EFalse); |
|
425 } |
|
426 |
|
427 const TRegion *CWsClientWindow::DrawingRegion() |
|
428 { |
|
429 return (&iRedraw->BaseDrawRegion()); |
|
430 } |
|
431 |
|
432 void CWsClientWindow::RecalcChildAbs(const TPoint *aOffset) |
|
433 { |
|
434 CWsClientWindow *win=this; |
|
435 FOREVER |
|
436 { |
|
437 FOREVER |
|
438 { |
|
439 win->SetAbsFromRel(); |
|
440 if (aOffset) |
|
441 win->OffsetBaseArea(*aOffset); |
|
442 if (win->Child()==NULL) |
|
443 break; |
|
444 win=win->Child(); |
|
445 } |
|
446 FOREVER |
|
447 { |
|
448 if (win==this) |
|
449 return; |
|
450 if (win->NextSibling()!=NULL) |
|
451 { |
|
452 win=win->NextSibling(); |
|
453 break; |
|
454 } |
|
455 win=(CWsClientWindow *)win->iParent; // The cast is safe as the loop is aborted when win==this |
|
456 } |
|
457 } |
|
458 } |
|
459 |
|
460 void CWsClientWindow::SetAbsFromRel() |
|
461 { |
|
462 iOrigin=iRel.iTl+iParent->Origin(); |
|
463 iAbs=iRel; |
|
464 iAbs.Move(iParent->Origin()); |
|
465 iAbs.Intersection(iParent->AbsRect()); |
|
466 } |
|
467 |
|
468 void CWsClientWindow::SetExtentL(const TPoint *aPos,const TSize *aSize) |
|
469 { |
|
470 if (iParent==NULL) |
|
471 OwnerPanic(EWservPanicParentDeleted); |
|
472 TPoint offset = TPoint(0,0); |
|
473 TSize oldSize; |
|
474 TSize newSize; |
|
475 TBool sizeChanged = EFalse; |
|
476 TBool posChanged = EFalse; |
|
477 |
|
478 if (aPos) |
|
479 { |
|
480 offset = *aPos+iParent->Origin()-iOrigin; |
|
481 if (offset.iX != 0 || offset.iY != 0) |
|
482 { |
|
483 posChanged = ETrue; |
|
484 } |
|
485 } |
|
486 |
|
487 if (posChanged) |
|
488 { |
|
489 TWalkWindowTreeScheduleRedraws wwt; |
|
490 WalkWindowTree(wwt, EWalkChildren); |
|
491 } |
|
492 |
|
493 if (aSize) |
|
494 { |
|
495 newSize=*aSize; |
|
496 if (newSize.iWidth<0) |
|
497 newSize.iWidth=0; |
|
498 if (newSize.iHeight<0) |
|
499 newSize.iHeight=0; |
|
500 // This should be the only part of resizing that can fail |
|
501 // and it can only fail for backedup windows. |
|
502 iRedraw->PrepareForResizeL(newSize,oldSize); |
|
503 sizeChanged = *aSize != iRel.Size(); |
|
504 } |
|
505 |
|
506 if (posChanged) |
|
507 { |
|
508 iRel.Move(offset); |
|
509 RecalcChildAbs(&offset); // Also calls UpdateElementExtent(offset) |
|
510 TWalkWindowTreeOffsetTransparentRegions offsetTransparent(offset); |
|
511 WalkWindowTree(offsetTransparent, EWalkChildren); |
|
512 } |
|
513 |
|
514 if (sizeChanged) |
|
515 { |
|
516 iRel.SetSize(newSize); |
|
517 RecalcChildAbs(NULL); |
|
518 CalcBaseArea(); |
|
519 iRedraw->Resize(newSize,oldSize); |
|
520 if (Redraw()->HasElement()) |
|
521 UpdateElementExtent(); |
|
522 } |
|
523 |
|
524 if ((posChanged || sizeChanged) && Redraw()->HasElement()) |
|
525 { |
|
526 TRect interSection(iParent->Origin(), iParent->Size()); |
|
527 interSection.Intersection(FullRect()); |
|
528 if (interSection == FullRect()) |
|
529 { |
|
530 // There is no any clipping in this case |
|
531 interSection = TRect(); |
|
532 } |
|
533 // Get the corresponding source rectangle for the element |
|
534 if (!iOriginalSrcElementRect.IsEmpty() && !iOriginalDestElementRect.IsEmpty() && !iAbs.IsEmpty()) |
|
535 { |
|
536 MWsElement* element = Screen()->WindowElements().GetElementFromWindow(*this); |
|
537 if (element) |
|
538 { |
|
539 element->SetDestinationClippingRect(interSection); |
|
540 } |
|
541 } |
|
542 } |
|
543 |
|
544 if (posChanged || sizeChanged) |
|
545 { |
|
546 iRedraw->ClipInvalidRegion(TRect(iRel.Size())); |
|
547 iRedraw->Moved(); |
|
548 ScheduleRegionUpdate(NULL); |
|
549 TWalkWindowTreeRecalcOpaque recalcOpaque; |
|
550 WalkWindowTree(recalcOpaque, EWalkChildren); |
|
551 |
|
552 MWsWindowTreeObserver* windowTreeObserver = Screen()->WindowTreeObserver(); |
|
553 if (windowTreeObserver) |
|
554 { |
|
555 windowTreeObserver->NodeExtentChanged(*this, FullRect()); |
|
556 } |
|
557 } |
|
558 } |
|
559 |
|
560 |
|
561 void CWsClientWindow::GetElementFlipAndRotation(TBool& aElemetFlip, MWsElement::TElementRotation& aElemenetRotation) |
|
562 { |
|
563 MWsElement* element = Screen()->WindowElements().GetElementFromWindow(*this); |
|
564 if (element) |
|
565 { |
|
566 aElemetFlip = element->SourceFlipping(); |
|
567 aElemenetRotation = element->SourceRotation(); |
|
568 } |
|
569 } |
|
570 |
|
571 void CWsClientWindow::Scroll(const TRect &aClipRect, const TPoint &aOffset, const TRect &aRect) |
|
572 { |
|
573 if (iParent==NULL) |
|
574 OwnerPanic(EWservPanicParentDeleted); |
|
575 |
|
576 // |
|
577 iRedraw->Scroll(aClipRect, aOffset,aRect); |
|
578 // |
|
579 CWsTop::TriggerRedraws(RootWindow()); |
|
580 } |
|
581 |
|
582 void CWsClientWindow::DeleteBaseArea() |
|
583 { |
|
584 WS_ASSERT_DEBUG(iBaseArea!=&nullRegion, EWsPanicRegionNull); |
|
585 if ((iCornerData&ECornerTypeMask)==EWindowCornerRegion) |
|
586 ((RWsRegion *)iBaseArea)->Destroy(); |
|
587 else |
|
588 { |
|
589 delete iBaseArea; |
|
590 } |
|
591 iBaseArea=NULL; |
|
592 } |
|
593 |
|
594 CWsClientWindow::~CWsClientWindow() |
|
595 { |
|
596 while(iVisibleRegionTrackingCounter>0) |
|
597 { |
|
598 SetupVisibleRegionTracking(EFalse); |
|
599 } |
|
600 if (iBaseWinFlags&EBaseWinNodeCreated) |
|
601 { |
|
602 MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver(); |
|
603 if (windowTreeObserver) |
|
604 { |
|
605 windowTreeObserver->NodeReleased(*this); |
|
606 iBaseWinFlags &= ~EBaseWinNodeCreated; |
|
607 } |
|
608 } |
|
609 Shutdown(); |
|
610 SetUserTransparentRegion(0); |
|
611 CWsPassword::WindowDestroyed(this); |
|
612 } |
|
613 |
|
614 void CWsClientWindow::Shutdown() |
|
615 // |
|
616 // Destroy a window, disconnects from the window tree and destroys all it's child windows |
|
617 // |
|
618 { |
|
619 iFlags|=EFlagShutDownInProgress; |
|
620 if (CClick::IsHandler()) |
|
621 { |
|
622 TWindowCloseData params; |
|
623 params.iClientHandle=iClientHandle; |
|
624 //if parent already shutdown (or disconnected) send 0 |
|
625 params.iWindowGroupId = (iParent) ? WinGroup()->Identifier() : 0; |
|
626 CClick::OtherEvent(EEventWindowClose,¶ms); |
|
627 } |
|
628 |
|
629 RemoveAllKeyRects(); |
|
630 while(iWinGcList) |
|
631 iWinGcList->Deactivate(); |
|
632 // |
|
633 iFlags|=EFlagInvisible; // First make it invisble |
|
634 if (iParent) // In case window wasn't fully constructed |
|
635 ResetHiddenFlags(); |
|
636 // |
|
637 CWsWindow::Shutdown(); |
|
638 DeleteBaseArea(); |
|
639 CWsPointerBuffer::Disconnect(this); |
|
640 iFlags&=~EFlagShutDownInProgress; |
|
641 } |
|
642 |
|
643 void CWsClientWindow::Activate() |
|
644 { |
|
645 if (iFlags&EFlagActive) |
|
646 OwnerPanic(EWservPanicWindowActive); |
|
647 iFlags|=EFlagActive; |
|
648 |
|
649 ResetHiddenFlags(); |
|
650 |
|
651 MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver(); |
|
652 if (windowTreeObserver) |
|
653 { |
|
654 windowTreeObserver->NodeExtentChanged(*this, FullRect()); |
|
655 windowTreeObserver->NodeActivated(*this); |
|
656 } |
|
657 } |
|
658 |
|
659 TBool CWsClientWindow::IsActivated() const |
|
660 { |
|
661 return (iFlags&EFlagActive)!=EFalse; |
|
662 } |
|
663 |
|
664 void CWsClientWindow::SetCornerTypeL(TCornerType aCornerType, TInt aCornerFlags, TRegion *aNewBaseArea, TBool aNotifyShapeChanged) |
|
665 { |
|
666 TRegion *baseArea=NULL; |
|
667 if (aCornerFlags&ECornerTypeMask) |
|
668 OwnerPanic(EWservPanicCornerParams); |
|
669 |
|
670 switch (aCornerType) |
|
671 { |
|
672 case EWindowCornerSquare: |
|
673 baseArea=new(ELeave) TRegionFix<1>(); |
|
674 break; |
|
675 case EWindowCorner1: |
|
676 baseArea=new(ELeave) TRegionFix<3>(); |
|
677 break; |
|
678 case EWindowCorner2: |
|
679 case EWindowCorner3: |
|
680 baseArea=new(ELeave) TRegionFix<5>(); |
|
681 break; |
|
682 case EWindowCorner5: |
|
683 baseArea=new(ELeave) TRegionFix<9>(); |
|
684 break; |
|
685 case EWindowCornerRegion: |
|
686 User::LeaveIfNull(baseArea=aNewBaseArea); |
|
687 baseArea->Offset(Origin()); |
|
688 break; |
|
689 default: |
|
690 OwnerPanic(EWservPanicCornerParams); |
|
691 } |
|
692 DeleteBaseArea(); |
|
693 iCornerData=aCornerType; |
|
694 iCornerData|=aCornerFlags; |
|
695 iBaseArea=baseArea; |
|
696 CalcBaseArea(); |
|
697 ScheduleRegionUpdate(NULL); |
|
698 |
|
699 if ( aNotifyShapeChanged ) |
|
700 { |
|
701 MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver(); |
|
702 if (windowTreeObserver) |
|
703 { |
|
704 windowTreeObserver->AttributeChanged(*this, MWsWindowTreeObserver::EWindowShape); |
|
705 } |
|
706 } |
|
707 } |
|
708 |
|
709 void CWsClientWindow::SetVisible(TBool aState) |
|
710 { |
|
711 if (aState) |
|
712 { |
|
713 if (iParent==NULL) |
|
714 OwnerPanic(EWservPanicParentDeleted); |
|
715 if (!(iFlags&EFlagInvisible)) // Already visible |
|
716 return; |
|
717 iFlags&=~EFlagInvisible; |
|
718 ResetHiddenFlags(); |
|
719 } |
|
720 else |
|
721 { |
|
722 if (iFlags&EFlagInvisible || !iParent) // Already invisible or parent has been deleted |
|
723 return; |
|
724 TWalkWindowTreePurgeEvents wwt; |
|
725 WalkWindowTree(wwt,EWalkChildren); // Destroy all events on this and all children |
|
726 iFlags|=EFlagInvisible; |
|
727 ResetHiddenFlags(); |
|
728 } |
|
729 |
|
730 MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver(); |
|
731 if (windowTreeObserver) |
|
732 { |
|
733 windowTreeObserver->FlagChanged(*this, MWsWindowTreeObserver::EVisible, aState); |
|
734 } |
|
735 } |
|
736 |
|
737 void CWsClientWindow::CommandL(TInt aOpcode, const TAny *aCmdData) |
|
738 { |
|
739 #ifdef _DEBUG |
|
740 // Save root window for performing CheckTree at the end of this func. |
|
741 // When aOpcode is EWsWinOpFree, this object would've been destroyed |
|
742 // and a call to RootWindow() in that case would be impossible |
|
743 CWsRootWindow* rootWindow=RootWindow(); |
|
744 #endif |
|
745 TWsWinCmdUnion pData; |
|
746 pData.any=aCmdData; |
|
747 if (CWsWindowBase::CommandL(aOpcode,pData)==EFalse) |
|
748 { |
|
749 switch(aOpcode) |
|
750 { |
|
751 case EWsWinOpActivate: |
|
752 Activate(); |
|
753 break; |
|
754 case EWsWinOpSetPos: |
|
755 SetExtentL(pData.pos,NULL); |
|
756 break; |
|
757 case EWsWinOpSetExtent: |
|
758 case EWsWinOpSetExtentErr: |
|
759 SetExtentL(&pData.SetEx->pos,&pData.SetEx->size); |
|
760 break; |
|
761 case EWsWinOpSetSize: |
|
762 case EWsWinOpSetSizeErr: |
|
763 SetExtentL(NULL,pData.size); |
|
764 break; |
|
765 case EWsWinOpInquireOffset: |
|
766 CWsClient::ReplyPoint(InquireOffset(*pData.UInt)); |
|
767 break; |
|
768 case EWsWinOpPosition: |
|
769 CWsClient::ReplyPoint(iRel.iTl); |
|
770 break; |
|
771 case EWsWinOpAbsPosition: |
|
772 CWsClient::ReplyPoint(iOrigin); |
|
773 break; |
|
774 case EWsWinOpSize: |
|
775 CWsClient::ReplySize(iRel.Size()); |
|
776 break; |
|
777 case EWsWinOpTestInvariant: |
|
778 SetReply(EFalse); |
|
779 break; |
|
780 case EWsWinOpPointerFilter: |
|
781 { |
|
782 TUint old=iPointerFilter; |
|
783 iPointerFilter&=~pData.PointerFilter->mask; |
|
784 iPointerFilter|=pData.PointerFilter->mask&pData.PointerFilter->flags; |
|
785 if (old&EPointerFilterEnterExit) |
|
786 TWsPointer::ReLogWindow(this); |
|
787 } |
|
788 break; |
|
789 case EWsWinOpSetPointerGrab: |
|
790 if (*pData.Bool==EFalse) |
|
791 iFlags&=~EFlagPointerGrab; |
|
792 else |
|
793 iFlags|=EFlagPointerGrab; |
|
794 break; |
|
795 case EWsWinOpClaimPointerGrab: |
|
796 { |
|
797 if (!iParent) |
|
798 OwnerPanic(EWservPanicParentDeleted); |
|
799 |
|
800 TInt errNo = TWsPointer::ClaimGrab(this,*pData.GrabControl); |
|
801 if(TWsWinCmdGrabControl::ESendReply & pData.GrabControl->flags) |
|
802 { |
|
803 // To avoid the reply-generated-flush, only do this for the new APIs, not the old ones. |
|
804 SetReply(errNo); |
|
805 } |
|
806 } |
|
807 break; |
|
808 case EWsWinOpSetPointerCapture: |
|
809 iFlags&=~(EFlagPointerCaptured|EFlagPointerCaptureDragDrop|EFlagPointerCaptureAllGroups); |
|
810 if ((*pData.UInt)&RWindowBase::TCaptureFlagEnabled) |
|
811 { |
|
812 iFlags|=EFlagPointerCaptured; |
|
813 if ((*pData.UInt)&RWindowBase::TCaptureFlagDragDrop) |
|
814 iFlags|=EFlagPointerCaptureDragDrop; |
|
815 if ((*pData.UInt)&RWindowBase::TCaptureFlagAllGroups) |
|
816 iFlags|=EFlagPointerCaptureAllGroups; |
|
817 |
|
818 } |
|
819 TWsPointer::ReLogPointersCurrentWindows(); |
|
820 break; |
|
821 case EWsWinOpSetPointerCapturePriority: |
|
822 iPointerCapturePriority=*pData.Int; |
|
823 break; |
|
824 case EWsWinOpGetPointerCapturePriority: |
|
825 SetReply(iPointerCapturePriority); |
|
826 break; |
|
827 case EWsWinOpSetVisible: |
|
828 SetVisible(*pData.Bool); |
|
829 break; |
|
830 case EWsWinOpScroll: |
|
831 { |
|
832 TPoint origin(0,0); |
|
833 TRect src(TRect(origin,iRel.Size())); |
|
834 src.Move(-pData.ScrollRect->offset); |
|
835 Scroll(TRect(origin,iRel.Size()),pData.ScrollRect->offset,src); |
|
836 } |
|
837 break; |
|
838 case EWsWinOpScrollClip: |
|
839 { |
|
840 TPoint origin(0,0); |
|
841 TRect src(TRect(origin,iRel.Size())); |
|
842 src.Move(-pData.ScrollRect->offset); |
|
843 TRect clip(pData.ScrollRect->clip); |
|
844 Scroll(clip,pData.ScrollRect->offset,src); |
|
845 } |
|
846 break; |
|
847 case EWsWinOpScrollRect: |
|
848 { |
|
849 TRect src(pData.ScrollRect->rect); |
|
850 Scroll(TRect(TPoint(0,0),iRel.Size()),pData.ScrollRect->offset,src); |
|
851 } |
|
852 break; |
|
853 case EWsWinOpScrollClipRect: |
|
854 { |
|
855 TRect src(pData.ScrollRect->rect); |
|
856 TRect clip(pData.ScrollRect->clip); |
|
857 Scroll(clip, pData.ScrollRect->offset,src); |
|
858 } |
|
859 break; |
|
860 case EWsWinOpSetOrdinalPositionPri: |
|
861 iOrdinalPriority=pData.OrdinalPos->ordinalPriority; |
|
862 SetOrdinalPosition(pData.OrdinalPos->pos); |
|
863 break; |
|
864 case EWsWinOpSetShadowHeight: |
|
865 OwnerPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client |
|
866 break; |
|
867 case EWsWinOpShadowDisabled: |
|
868 OwnerPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client |
|
869 break; |
|
870 case EWsWinOpRequiredDisplayMode: |
|
871 if (Backup()!=NULL) |
|
872 OwnerPanic(EWservPanicBackupDisplayMode); |
|
873 SetReply(SetRequiredDisplayModeL(*pData.DisplayMode)); |
|
874 break; |
|
875 case EWsWinOpGetDisplayMode: |
|
876 SetReply(DisplayMode()); |
|
877 break; |
|
878 case EWsWinOpRequestPointerRepeatEvent: |
|
879 { |
|
880 if (!iParent) |
|
881 OwnerPanic(EWservPanicParentDeleted); |
|
882 TInt errNo = TWsPointer::RequestPointerRepeatEvent(this,*pData.RequestPointerRepeatEvent); |
|
883 if(TWsWinCmdRequestPointerRepeatEvent::ERepeatFlagsSendReply & pData.RequestPointerRepeatEvent->repeatFlags) |
|
884 { |
|
885 SetReply(errNo); |
|
886 } |
|
887 } |
|
888 break; |
|
889 case EWsWinOpCancelPointerRepeatEventRequest: |
|
890 { |
|
891 TInt errNo = TWsPointer::CancelPointerRepeatEventRequest(*pData.CancelPointerRepeatEventRequest); |
|
892 if(TWsWinCmdCancelPointerRepeatEventRequest::ECancelRepeatFlagsSendReply & pData.RequestPointerRepeatEvent->repeatFlags) |
|
893 { |
|
894 SetReply(errNo); |
|
895 } |
|
896 } |
|
897 break; |
|
898 case EWsWinOpAllocPointerMoveBuffer: |
|
899 CWsPointerBuffer::ConnectL(this,pData.AllocPointerMoveBuffer->maxNumPoints,pData.AllocPointerMoveBuffer->flags); |
|
900 iFlags|=EFlagUsingPointerBuffer|EFlagHasPointerBuffer; |
|
901 break; |
|
902 case EWsWinOpFreePointerMoveBuffer: |
|
903 CWsPointerBuffer::Disconnect(this); |
|
904 iFlags&=~(EFlagUsingPointerBuffer|EFlagHasPointerBuffer); |
|
905 break; |
|
906 case EWsWinOpRetrievePointerMoveBuffer: |
|
907 CWsPointerBuffer::RetrievePointerMoveBuffer(this,*pData.Int); |
|
908 break; |
|
909 case EWsWinOpEnablePointerMoveBuffer: |
|
910 if (!(iFlags&EFlagHasPointerBuffer)) |
|
911 OwnerPanic(EWservPanicNoPointerBuffer); |
|
912 iFlags|=EFlagUsingPointerBuffer; |
|
913 break; |
|
914 case EWsWinOpDisablePointerMoveBuffer: |
|
915 iFlags&=~EFlagUsingPointerBuffer; |
|
916 /*Fall Through*/ |
|
917 case EWsWinOpDiscardPointerMoveBuffer: |
|
918 CWsPointerBuffer::DiscardPointerMoveBuffer(this); |
|
919 break; |
|
920 case EWsWinOpAddKeyRect: |
|
921 AddKeyRectL(pData.AddKeyRect->rect, pData.AddKeyRect->scanCode, pData.AddKeyRect->activatedByPointerSwitchOn); |
|
922 break; |
|
923 case EWsWinOpRemoveAllKeyRects: |
|
924 RemoveAllKeyRects(); |
|
925 break; |
|
926 case EWsWinOpPasswordWindow: |
|
927 if (!iParent) |
|
928 OwnerPanic(EWservPanicParentDeleted); |
|
929 CWsPassword::SetPasswordWindowL(this, *pData.PasswordMode); |
|
930 break; |
|
931 case EWsWinOpEnableBackup: |
|
932 if (!iParent) |
|
933 OwnerPanic(EWservPanicParentDeleted); |
|
934 if (*pData.UInt==0) |
|
935 iBackupsRequested|=EWindowBackupAreaBehind; //For backwards compatibility |
|
936 else |
|
937 iBackupsRequested|=*pData.UInt; |
|
938 break; |
|
939 case EWsWinOpFadeBehind: |
|
940 { |
|
941 if (!iParent) |
|
942 OwnerPanic(EWservPanicParentDeleted); |
|
943 |
|
944 TUint8 blackMap; |
|
945 TUint8 whiteMap; |
|
946 iScreen->GetFadingParams(blackMap,whiteMap); |
|
947 SetFadeBehind(*pData.Bool); |
|
948 TWalkWindowTreeSetFaded wwt(*pData.Bool,this,blackMap,whiteMap); |
|
949 WalkWindowTree(wwt,EWalkBehind); |
|
950 } |
|
951 break; |
|
952 case EWsWinOpGetIsFaded: |
|
953 SetReply(iFadeCount); |
|
954 break; |
|
955 case EWsWinOpGetIsNonFading: |
|
956 SetReply(iFlags&EFlagNonFadingWindow); |
|
957 break; |
|
958 case EWsWinOpMoveToGroup: |
|
959 if (!iParent) |
|
960 OwnerPanic(EWservPanicParentDeleted); |
|
961 if (iParent->WinType()!=EWinTypeGroup) |
|
962 OwnerPanic(EWservPanicNotTopClient); |
|
963 ((CWsTopClientWindow*)this)->DoMoveWindowL(*pData.Int); |
|
964 break; |
|
965 case EWsWinOpTestLowPriorityRedraw: |
|
966 { |
|
967 // This is purely for testing purposes |
|
968 // Returns the redraw priority |
|
969 TUint priority=0; |
|
970 TPckgBuf<TUint> priBuf; |
|
971 priority=WsOwner()->RedrawQueue()->RedrawPriority((CWsWindowRedraw*)this->iRedraw); |
|
972 priBuf()=priority; |
|
973 CWsClient::ReplyBuf(priBuf); |
|
974 } |
|
975 break; |
|
976 case EWsWinOpEnableVisibilityChangeEvents: |
|
977 iFlags |= EFlagGeneratesVisibilityEvents; |
|
978 SetupVisibleRegionTracking(ETrue); |
|
979 if (iFlags&EFlagActive) |
|
980 { |
|
981 iScreen->DoRedrawNow(); |
|
982 PossibleVisibilityChangedEvent(ETrue); |
|
983 } |
|
984 break; |
|
985 case EWsWinOpDisableVisibilityChangeEvents: |
|
986 iFlags &= ~EFlagGeneratesVisibilityEvents; |
|
987 SetupVisibleRegionTracking(EFalse); |
|
988 break; |
|
989 case EWsWinOpSetTransparentRegion: |
|
990 { |
|
991 if (IsTranslucent()) |
|
992 { |
|
993 TInt recs=*pData.Int; |
|
994 RWsRegion* reg=recs>0? GetRegionFromClientL(iWsOwner,recs) : new(ELeave) RWsRegion; |
|
995 SetUserTransparentRegion(reg); |
|
996 SetReply(KErrNone); |
|
997 } |
|
998 else |
|
999 { |
|
1000 OwnerPanic(EWservPanicTransparencyObjNotCreated); |
|
1001 } |
|
1002 } |
|
1003 break; |
|
1004 case EWsWinOpSetTransparencyPolicy: |
|
1005 { |
|
1006 if (IsTranslucent()) |
|
1007 SetReply(KErrNone); |
|
1008 else |
|
1009 OwnerPanic(EWservPanicTransparencyObjNotCreated); |
|
1010 } |
|
1011 break; |
|
1012 case EWsWinOpSetTransparencyAlphaChannel: |
|
1013 { |
|
1014 iFlags |= static_cast<TUint>(EFlagHasAlpha); |
|
1015 SetReply(KErrNone); |
|
1016 |
|
1017 MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver(); |
|
1018 if (windowTreeObserver) |
|
1019 { |
|
1020 windowTreeObserver->FlagChanged(*this, MWsWindowTreeObserver::EAlphaChannelTransparencyEnabled, ETrue); |
|
1021 } |
|
1022 break; |
|
1023 } |
|
1024 default: |
|
1025 if (iRedraw->CommandL(aOpcode,pData)==EFalse) |
|
1026 { |
|
1027 OwnerPanic(EWservPanicOpcode); |
|
1028 } |
|
1029 } |
|
1030 } |
|
1031 #if defined(_DEBUG) |
|
1032 rootWindow->CheckTree(); |
|
1033 #endif |
|
1034 } |
|
1035 |
|
1036 void CWsClientWindow::GcActivated(CWsGc *aGc) |
|
1037 { |
|
1038 aGc->SetNextWinGc(iWinGcList); |
|
1039 iWinGcList=aGc; |
|
1040 } |
|
1041 |
|
1042 void CWsClientWindow::GcDeactivated(CWsGc *aGc) |
|
1043 { |
|
1044 if (aGc==iWinGcList) |
|
1045 iWinGcList=aGc->NextWinGc(); |
|
1046 else |
|
1047 { |
|
1048 CWsGc *gc=iWinGcList; |
|
1049 CWsGc *next; |
|
1050 FOREVER |
|
1051 { |
|
1052 next=gc->NextWinGc(); |
|
1053 WS_ASSERT_DEBUG(next!=NULL, EWsPanicBadActiveGcList); |
|
1054 if (next==aGc) |
|
1055 { |
|
1056 gc->SetNextWinGc(next->NextWinGc()); |
|
1057 break; |
|
1058 } |
|
1059 gc=next; |
|
1060 } |
|
1061 } |
|
1062 aGc->SetNextWinGc(NULL); |
|
1063 } |
|
1064 |
|
1065 void CWsClientWindow::ReactivateGcs() |
|
1066 { |
|
1067 for (CWsGc * gc = iWinGcList; gc; gc = gc->NextWinGc()) |
|
1068 { |
|
1069 gc->Reactivate(); |
|
1070 } |
|
1071 } |
|
1072 |
|
1073 void CWsClientWindow::OffsetUserTransparentRegion(const TPoint& aOffset) |
|
1074 { |
|
1075 if (iUserDefinedTransparentRegion) |
|
1076 { |
|
1077 iUserDefinedTransparentRegion->Offset(aOffset); |
|
1078 } |
|
1079 } |
|
1080 |
|
1081 void CWsClientWindow::SetUserTransparentRegion(RWsRegion* aRegion) |
|
1082 { |
|
1083 if (iUserDefinedTransparentRegion) |
|
1084 { |
|
1085 iUserDefinedTransparentRegion->Close(); |
|
1086 delete iUserDefinedTransparentRegion; |
|
1087 iUserDefinedTransparentRegion = 0; |
|
1088 } |
|
1089 |
|
1090 if (aRegion) |
|
1091 { |
|
1092 aRegion->Offset(iOrigin); |
|
1093 iUserDefinedTransparentRegion=aRegion; |
|
1094 } |
|
1095 |
|
1096 SetUserOpaqueRegion(); |
|
1097 } |
|
1098 |
|
1099 void CWsClientWindow::SetUserOpaqueRegion() |
|
1100 { |
|
1101 if (iUserDefinedOpaqueRegion) |
|
1102 { |
|
1103 iUserDefinedOpaqueRegion->Close(); |
|
1104 delete iUserDefinedOpaqueRegion; |
|
1105 iUserDefinedOpaqueRegion = 0; |
|
1106 } |
|
1107 if (iUserDefinedTransparentRegion) |
|
1108 { |
|
1109 iUserDefinedOpaqueRegion=new RWsRegion; |
|
1110 if (iUserDefinedOpaqueRegion) |
|
1111 { |
|
1112 iUserDefinedOpaqueRegion->Copy(*iBaseArea); |
|
1113 iUserDefinedOpaqueRegion->SubRegion(*iUserDefinedTransparentRegion); |
|
1114 if (iUserDefinedOpaqueRegion->CheckError() || iUserDefinedOpaqueRegion->Count() == 0) |
|
1115 { |
|
1116 iUserDefinedOpaqueRegion->Close(); |
|
1117 delete iUserDefinedOpaqueRegion; |
|
1118 iUserDefinedOpaqueRegion = 0; |
|
1119 } |
|
1120 } |
|
1121 // Intentionally not sending this notification during destruction (when SetUserTransparentRegion is called from d'tor) |
|
1122 MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver(); |
|
1123 if (windowTreeObserver) |
|
1124 { |
|
1125 windowTreeObserver->TransparentRegionChanged(*this, *iUserDefinedTransparentRegion, iUserDefinedOpaqueRegion); |
|
1126 } |
|
1127 } |
|
1128 } |
|
1129 |
|
1130 /** Checks whether this window is in front of aWin. |
|
1131 |
|
1132 @param aWin A window. |
|
1133 @return EFalse if aWin is the same or is in front of this, ETrue otherwise. |
|
1134 @internalComponent |
|
1135 * released |
|
1136 */ |
|
1137 TBool CWsClientWindow::IsInfrontOf(const CWsWindowBase* aWin) const |
|
1138 { |
|
1139 TInt thisDepth=Depth(); |
|
1140 TInt otherDepth=aWin->Depth(); |
|
1141 const CWsWindowBase *thisWin=this; |
|
1142 const CWsWindowBase *otherWin=aWin; |
|
1143 if (thisDepth>otherDepth) |
|
1144 { |
|
1145 for (TInt count=thisDepth-otherDepth;count>0;count--) |
|
1146 thisWin=thisWin->BaseParent(); |
|
1147 } |
|
1148 else |
|
1149 { |
|
1150 for (TInt count=otherDepth-thisDepth;count>0;count--) |
|
1151 otherWin=otherWin->BaseParent(); |
|
1152 } |
|
1153 if (thisWin==otherWin) |
|
1154 return thisDepth>otherDepth; |
|
1155 while(thisWin->BaseParent()!=otherWin->BaseParent()) |
|
1156 { |
|
1157 thisWin=thisWin->BaseParent(); |
|
1158 otherWin=otherWin->BaseParent(); |
|
1159 } |
|
1160 const CWsWindowBase *win=thisWin->BaseParent()->BaseChild(); |
|
1161 FOREVER |
|
1162 { |
|
1163 if (win==otherWin) |
|
1164 { |
|
1165 return EFalse; |
|
1166 } |
|
1167 if (win==thisWin) |
|
1168 return ETrue; |
|
1169 win=win->NextSibling(); |
|
1170 } |
|
1171 } |
|
1172 |
|
1173 CWsTopClientWindow* CWsClientWindow::TopClientWindow() |
|
1174 { |
|
1175 if (iParent==NULL) |
|
1176 OwnerPanic(EWservPanicParentDeleted); |
|
1177 CWsWindowBase* win=this; |
|
1178 while(win->BaseParent()->WinType()!=EWinTypeGroup) |
|
1179 win=win->BaseParent(); |
|
1180 return static_cast<CWsTopClientWindow*>(win); |
|
1181 } |
|
1182 |
|
1183 const TRegion &CWsClientWindow::InvalidArea() const |
|
1184 { |
|
1185 return(iRedraw->InvalidArea()); |
|
1186 } |
|
1187 |
|
1188 |
|
1189 TUint CWsClientWindow::RedrawPriority(TInt *aShift) const |
|
1190 { |
|
1191 TUint ordinalPos=OrdinalPosition(EFalse)+1; |
|
1192 if (ordinalPos>15) // Algorithm only works upto 15 , make all windows after 15 equal in priority |
|
1193 ordinalPos=15; |
|
1194 TInt shift; |
|
1195 TUint parent=((CWsClientWindow *)iParent)->RedrawPriority(&shift); |
|
1196 if (shift>0) |
|
1197 shift--; |
|
1198 if (aShift) |
|
1199 *aShift=shift; |
|
1200 return(parent+(ordinalPos<<(shift*KWinRedrawPriBitsPerLevel))); |
|
1201 } |
|
1202 |
|
1203 TDblQue<TPointerKeyList> *CWsClientWindow::PointerKeyList() const |
|
1204 { |
|
1205 return(iPointerKeyList); |
|
1206 } |
|
1207 |
|
1208 void CWsClientWindow::AddKeyRectL(const TRect &aRect, TInt aScanCode, TBool aActivatedByPointerSwitchOn) |
|
1209 { |
|
1210 if (!iPointerKeyList) |
|
1211 iPointerKeyList=new(ELeave) TDblQue<TPointerKeyList>(_FOFF(TPointerKeyList,iQue)); |
|
1212 TPointerKeyList *pkl=new(ELeave) TPointerKeyList(); |
|
1213 iPointerKeyList->AddLast(*pkl); |
|
1214 pkl->iRect=aRect; |
|
1215 pkl->iScanCode=aScanCode; |
|
1216 pkl->iActivatedByPointerSwitchOn=aActivatedByPointerSwitchOn; |
|
1217 } |
|
1218 |
|
1219 void CWsClientWindow::RemoveAllKeyRects() |
|
1220 { |
|
1221 if (iPointerKeyList) |
|
1222 { |
|
1223 TPointerKeyList *pkl=NULL; |
|
1224 for(TDblQueIter<TPointerKeyList> iter(*iPointerKeyList);(pkl=iter++)!=NULL;) |
|
1225 { |
|
1226 pkl->iQue.Deque(); |
|
1227 delete pkl; |
|
1228 } |
|
1229 delete iPointerKeyList; |
|
1230 iPointerKeyList=NULL; |
|
1231 } |
|
1232 } |
|
1233 |
|
1234 TBool CWsClientWindow::IsHidden() |
|
1235 { |
|
1236 return (!IsVisible()) || VisibleRegion().IsEmpty(); |
|
1237 } |
|
1238 |
|
1239 void CWsClientWindow::SetFaded(TBool aFade, TUint8 aBlackMap, TUint8 aWhiteMap, TBool aNotifyObserver) |
|
1240 { |
|
1241 TBool stateChanged; |
|
1242 SetFaded(aFade, aBlackMap, aWhiteMap, aNotifyObserver, stateChanged); |
|
1243 } |
|
1244 |
|
1245 void CWsClientWindow::SetFaded(TBool aFade, TUint8 aBlackMap, TUint8 aWhiteMap, TBool aNotifyObserver, TBool& aStateChanged) |
|
1246 { |
|
1247 iBlackMap=aBlackMap; |
|
1248 iWhiteMap=aWhiteMap; |
|
1249 const TBool mapAltered = (iBlackMap != aBlackMap) || (iWhiteMap != aWhiteMap); |
|
1250 const TInt oldFadeCount = iFadeCount; |
|
1251 |
|
1252 if (iAbsoluteFading) |
|
1253 { |
|
1254 if (aFade) |
|
1255 { |
|
1256 iFadeCount = 1; |
|
1257 } |
|
1258 else |
|
1259 { |
|
1260 iFadeCount = 0; |
|
1261 } |
|
1262 } |
|
1263 else |
|
1264 { |
|
1265 if (aFade) |
|
1266 { |
|
1267 ++iFadeCount; |
|
1268 } |
|
1269 else if (iFadeCount > 0) |
|
1270 { |
|
1271 --iFadeCount; |
|
1272 } |
|
1273 } |
|
1274 |
|
1275 //Fade state only changes when iFadeCount transitions from 0 to 1 or from 1 to 0. |
|
1276 aStateChanged = (iFadeCount==0 || oldFadeCount==0) && (oldFadeCount != iFadeCount); |
|
1277 if (!Screen()->ChangeTracking() && CWsTop::IsFadeEnabled() && (aStateChanged || mapAltered) ) |
|
1278 { |
|
1279 Screen()->AcceptFadeRequest(this, (iFadeCount > 0)); |
|
1280 } |
|
1281 |
|
1282 const TBool doNotify = iAbsoluteFading ? aStateChanged : (oldFadeCount != iFadeCount); |
|
1283 MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver(); |
|
1284 if (windowTreeObserver && aNotifyObserver && doNotify) |
|
1285 { |
|
1286 windowTreeObserver->FadeCountChanged(*this, iFadeCount); |
|
1287 } |
|
1288 } |
|
1289 |
|
1290 void CWsClientWindow::ResetHiddenFlagsInParentAndChildren() |
|
1291 { |
|
1292 ResetHiddenFlag(); |
|
1293 SetElementOpacity(IsVisible() ? 0xFF : 0x00); // Update element visibility |
|
1294 for(CWsClientWindow* child=Child();child;child=child->NextSibling()) |
|
1295 { |
|
1296 child->ResetHiddenFlagsInParentAndChildren(); |
|
1297 } |
|
1298 } |
|
1299 |
|
1300 const TRegion& CWsClientWindow::WindowArea() const |
|
1301 { |
|
1302 WS_ASSERT_DEBUG(iBaseArea, EWsPanicRegionNull); |
|
1303 return *iBaseArea; |
|
1304 } |
|
1305 |
|
1306 void CWsClientWindow::Invalidate(const TRect * aRect) |
|
1307 { |
|
1308 iRedraw->Invalidate(aRect); |
|
1309 } |
|
1310 |
|
1311 void CWsClientWindow::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty) |
|
1312 { |
|
1313 if (IsVisible()) |
|
1314 { |
|
1315 iScreen->ScheduleRegionUpdate(aDefinitelyDirty); |
|
1316 } |
|
1317 } |
|
1318 |
|
1319 void CWsClientWindow::AddRedrawRegion(const TRegion& aRegion, TBool aSchedule, TRedrawDepth aDepth) |
|
1320 { |
|
1321 if (!IsHidden()) |
|
1322 { |
|
1323 iScreen->AddRedrawRegion(aRegion, aSchedule, aDepth); |
|
1324 } |
|
1325 } |
|
1326 |
|
1327 void CWsClientWindow::SendState(MWsWindowTreeObserver& aWindowTreeObserver) const |
|
1328 { |
|
1329 CWsWindow::SendState(aWindowTreeObserver); |
|
1330 |
|
1331 if(iFadeCount > 0) |
|
1332 { |
|
1333 aWindowTreeObserver.FadeCountChanged(*this, iFadeCount); |
|
1334 } |
|
1335 |
|
1336 if(iUserDefinedTransparentRegion) |
|
1337 { |
|
1338 aWindowTreeObserver.TransparentRegionChanged(*this, *iUserDefinedTransparentRegion, iUserDefinedOpaqueRegion); |
|
1339 } |
|
1340 |
|
1341 if(HasElement()) |
|
1342 { |
|
1343 CWindowElementSet& windowElementSet = Screen()->WindowElements(); |
|
1344 const TBackgroundAttributes *bElementAttr; |
|
1345 const RArray<TPlacedAttributes> *pElementsAttr; |
|
1346 |
|
1347 TInt ret = windowElementSet.FindElements(*this, bElementAttr, pElementsAttr); |
|
1348 if(ret == KErrNone) |
|
1349 { |
|
1350 MWsElement* element = bElementAttr->iElement; |
|
1351 if (element) |
|
1352 aWindowTreeObserver.ElementAdded(*this, *element); |
|
1353 } |
|
1354 } |
|
1355 |
|
1356 } |
|
1357 |
|
1358 TBool CWsClientWindow::IsDSAHost() const |
|
1359 { |
|
1360 TBool res = CWsWindow::IsDSAHost(); |
|
1361 if ( !res ) |
|
1362 { // check for grace period when DSA is being restarted (after aborting but before client started DSA again) |
|
1363 res = Screen()->IsDSAClientWindow( this ); |
|
1364 } |
|
1365 return res; |
|
1366 } |
|
1367 |
|
1368 void CWsClientWindow::UpdateElementExtent(const TPoint* aOffset) |
|
1369 { |
|
1370 if (Redraw()->HasElement()) |
|
1371 { |
|
1372 Screen()->WindowElements().UpdateElementExtent(*this, aOffset); |
|
1373 } |
|
1374 } |
|
1375 |
|
1376 void CWsClientWindow::SetElementOpacity(TInt aOpacity) |
|
1377 { |
|
1378 if (Redraw()->HasElement()) |
|
1379 { |
|
1380 Screen()->WindowElements().SetElementOpacity(*this,aOpacity); |
|
1381 |
|
1382 } |
|
1383 } |
|
1384 |
|
1385 TRect CWsClientWindow::GetOriginalSrcElementRect() const |
|
1386 { |
|
1387 return iOriginalSrcElementRect; |
|
1388 } |
|
1389 TRect CWsClientWindow::GetOriginalDestElementRect() const |
|
1390 { |
|
1391 return iOriginalDestElementRect; |
|
1392 } |
|
1393 |
|
1394 // |
|
1395 // Code for CWsTopClientWindow, a client window that connects to a group window // |
|
1396 // |
|
1397 |
|
1398 CWsTopClientWindow::CWsTopClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsClientWindow(aOwner, aScreen) |
|
1399 { |
|
1400 } |
|
1401 |
|
1402 void CWsTopClientWindow::ConstructL(const TWsClCmdCreateWindow &cmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid) |
|
1403 { |
|
1404 iFlags|=EFlagIsTopClientWindow; |
|
1405 CWsClientWindow::ConstructL(cmd, aParent, aScreenDeviceIsInvalid); |
|
1406 } |
|
1407 |
|
1408 void CWsTopClientWindow::SetInactive() |
|
1409 { |
|
1410 iFlags&=~EFlagActive; |
|
1411 ResetHiddenFlags(); |
|
1412 } |
|
1413 |
|
1414 void CWsTopClientWindow::SetScreenDeviceValidState(TBool aState) |
|
1415 { |
|
1416 if (SetScreenDeviceValidStateFlag(aState)) |
|
1417 ResetHiddenFlags(); |
|
1418 } |
|
1419 |
|
1420 TBool CWsTopClientWindow::SetScreenDeviceValidStateFlag(TBool aState) |
|
1421 { |
|
1422 TBool isSet=iFlags&EFlagScreenDeviceInvalid; |
|
1423 if (!isSet==!aState) |
|
1424 { |
|
1425 if (aState) |
|
1426 iFlags&=~EFlagScreenDeviceInvalid; |
|
1427 else |
|
1428 iFlags|=EFlagScreenDeviceInvalid; |
|
1429 return ETrue; |
|
1430 } |
|
1431 return EFalse; |
|
1432 } |
|
1433 |
|
1434 void CWsTopClientWindow::SetOrdinalPosition(TInt aPos) |
|
1435 { |
|
1436 if (!iParent) |
|
1437 { |
|
1438 OwnerPanic(EWservPanicParentDeleted); |
|
1439 } |
|
1440 if (CheckOrdinalPositionChange(aPos)) |
|
1441 { |
|
1442 CWsWindowBase::SetOrdinalPosition(aPos); |
|
1443 CWsTop::TriggerRedraws(RootWindow()); |
|
1444 } |
|
1445 } |
|
1446 |
|
1447 void CWsTopClientWindow::DoMoveWindowL(TInt aIdentifier) |
|
1448 { |
|
1449 CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(aIdentifier); |
|
1450 if (group==iParent) |
|
1451 return; |
|
1452 if (group->WsOwner()!=WsOwner()) |
|
1453 User::Leave(KErrNotFound); |
|
1454 ChangeWindowPosition(0, group); |
|
1455 CWsTop::TriggerRedraws(RootWindow()); |
|
1456 } |
|
1457 |
|
1458 TUint CWsTopClientWindow::RedrawPriority(TInt *aShift) const |
|
1459 { |
|
1460 TUint ordinalPos=OrdinalPosition(EFalse); |
|
1461 if (ordinalPos>KWinRedrawPriMaxOrdinal) // Algorithm only works for upto KWinRedrawPriMaxOrdinal windows, |
|
1462 ordinalPos=KWinRedrawPriMaxOrdinal; // make all windows after this equal in priority |
|
1463 if (aShift) |
|
1464 *aShift=KWinRedrawPriMaxLevel; |
|
1465 return(ordinalPos<<(KWinRedrawPriMaxLevel*KWinRedrawPriBitsPerLevel)); |
|
1466 } |
|
1467 |