|
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 "server.h" |
|
20 #include "cliwin.h" |
|
21 #include "gc.h" |
|
22 #include "rootwin.h" |
|
23 #include "windowgroup.h" |
|
24 #include "walkwindowtree.h" |
|
25 #include "ScrDev.H" |
|
26 #include "wstop.h" |
|
27 #include "EVQUEUE.H" |
|
28 #include "KEYCLICK.H" |
|
29 #include "panics.h" |
|
30 #include "password.h" |
|
31 #include "pointer.h" |
|
32 #include "EVENT.H" |
|
33 #include "backedupwindow.h" |
|
34 #include "redrawmsgwindow.h" |
|
35 |
|
36 TBool CWsClientWindow::iAbsoluteFading = EFalse; |
|
37 |
|
38 const TPoint corner1[1]={TPoint(1,1)}; |
|
39 const TPoint corner2[2]={TPoint(2,1),TPoint(1,1)}; |
|
40 const TPoint corner3[2]={TPoint(3,1),TPoint(1,2)}; |
|
41 const TPoint corner5[4]={TPoint(5,1),TPoint(3,1),TPoint(2,1),TPoint(1,2)}; |
|
42 |
|
43 /*CWsClientWindow*/ |
|
44 |
|
45 CWsClientWindow::CWsClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsWindow(aOwner,WS_HANDLE_WINDOW,aScreen) |
|
46 { |
|
47 iWinType=EWinTypeClient; |
|
48 } |
|
49 |
|
50 void CWsClientWindow::ConstructL(const TWsClCmdCreateWindow &aCmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid) |
|
51 { |
|
52 CWsWindow::Construct(); |
|
53 NewObjL(); |
|
54 if (aCmd.clientHandle==NULL) |
|
55 OwnerPanic(EWservPanicNullHandle); |
|
56 #if defined(_DEBUG) |
|
57 if (IsClientHandleInUse(aCmd.clientHandle)) |
|
58 OwnerPanic(EWservPanicDuplicateHandle); |
|
59 #endif |
|
60 iPointerFilter=EPointerFilterEnterExit|EPointerFilterMove|EPointerFilterDrag; |
|
61 iClientHandle=aCmd.clientHandle; |
|
62 CWsWindow* inherit=static_cast<CWsWindow *>(aParent); |
|
63 if (aParent->WinType()==EWinTypeGroup) |
|
64 inherit=RootWindow(); |
|
65 SetPointerCursor(aParent->PointerCursor()); |
|
66 iAbs=inherit->Abs(); |
|
67 iOrigin=aParent->Origin(); |
|
68 iRel.iBr.iX=inherit->Rel().iBr.iX-inherit->Rel().iTl.iX; |
|
69 iRel.iBr.iY=inherit->Rel().iBr.iY-inherit->Rel().iTl.iY; |
|
70 switch(aCmd.type) |
|
71 { |
|
72 case EWinRedraw: |
|
73 iRedraw=new(ELeave) CWsRedrawMsgWindow(this); |
|
74 break; |
|
75 case EWinBackedUp: |
|
76 iRedraw=new(ELeave) CWsBackedUpWindow(this, aCmd.displayMode); |
|
77 iAbs.iBr=iAbs.iTl; |
|
78 iRel.iBr=iRel.iTl; |
|
79 break; |
|
80 case EWinBlank: |
|
81 iRedraw=new(ELeave) CWsBlankWindow(this); |
|
82 break; |
|
83 default: |
|
84 OwnerPanic(EWservPanicRedrawType); |
|
85 } |
|
86 ResetHiddenFlag(); |
|
87 CWsWindowBase::ConstructL(aParent); |
|
88 if (aScreenDeviceIsInvalid) |
|
89 { |
|
90 iFlags|=EFlagScreenDeviceInvalid; |
|
91 ResetHiddenFlag(); |
|
92 } |
|
93 SetCornerTypeL(EWindowCornerSquare,0); |
|
94 iRedraw->ConstructL(); |
|
95 } |
|
96 |
|
97 void CWsClientWindow::SetClippedBaseArea(RWsRegion &aRegion) const |
|
98 { |
|
99 if(iBaseArea) |
|
100 { |
|
101 aRegion.Copy(*iBaseArea); |
|
102 } |
|
103 aRegion.ClipRect(iAbs); |
|
104 } |
|
105 |
|
106 void CWsClientWindow::SetOpaqueClippedBaseArea(RWsRegion &aRegion) const |
|
107 { |
|
108 if (IsTranslucent()) |
|
109 { |
|
110 if (iUserDefinedOpaqueRegion) |
|
111 { |
|
112 aRegion.Copy(*iUserDefinedOpaqueRegion); |
|
113 aRegion.ClipRect(iAbs); |
|
114 } |
|
115 else |
|
116 { |
|
117 aRegion.Clear(); |
|
118 } |
|
119 } |
|
120 else |
|
121 { |
|
122 SetClippedBaseArea(aRegion); |
|
123 } |
|
124 } |
|
125 |
|
126 void CWsClientWindow::ResetHiddenFlag() |
|
127 // |
|
128 // Reset the status of the hidden flag based on the current states of the active and invisible flags |
|
129 // |
|
130 { |
|
131 CWsClientWindow *parent=static_cast<CWsClientWindow*>(iParent); |
|
132 |
|
133 TBool wasHidden = iFlags&EFlagHidden; |
|
134 TBool nowHidden = (parent==NULL || |
|
135 (parent->WinType()==EWinTypeClient && !parent->IsVisible()) || |
|
136 !(iFlags&EFlagActive) || |
|
137 (iFlags&EFlagInvisible) || |
|
138 (iFlags&EFlagScreenDeviceInvalid)); |
|
139 |
|
140 if (nowHidden) |
|
141 { |
|
142 iFlags|=EFlagHidden; |
|
143 iFlags&=~EFlagDrawnToScreen; |
|
144 } |
|
145 else |
|
146 { |
|
147 iFlags&=~EFlagHidden; |
|
148 } |
|
149 if ((!nowHidden) != (!wasHidden)) |
|
150 { |
|
151 // intentionally call the screen directly |
|
152 iScreen->ScheduleRegionUpdate(&iVisibleRegion); |
|
153 } |
|
154 } |
|
155 |
|
156 void CWsClientWindow::ResetHiddenFlags() |
|
157 { |
|
158 CWsClientWindow *win=this; |
|
159 FOREVER |
|
160 { |
|
161 TUint oldHiddenFlag=win->iFlags&EFlagHidden; |
|
162 win->ResetHiddenFlag(); |
|
163 if ((win->iFlags&EFlagHidden)!=oldHiddenFlag) // If hidden status hasn't changed nothing to do |
|
164 { |
|
165 if (win->Child()) |
|
166 { |
|
167 win=win->Child(); |
|
168 continue; |
|
169 } |
|
170 } |
|
171 if (win==this) |
|
172 return; |
|
173 while(!win->NextSibling()) |
|
174 { |
|
175 win=(CWsClientWindow *)win->BaseParent(); |
|
176 if (win==this) |
|
177 return; |
|
178 } |
|
179 win=win->NextSibling(); |
|
180 } |
|
181 } |
|
182 |
|
183 void CWsClientWindow::OffsetBaseArea(const TPoint &aOffset) |
|
184 { |
|
185 iBaseArea->Offset(aOffset); |
|
186 } |
|
187 |
|
188 void CWsClientWindow::CalcBaseArea() |
|
189 // |
|
190 // The windows basic area before any clipping is done |
|
191 // |
|
192 { |
|
193 TInt cornerType=iCornerData&ECornerTypeMask; |
|
194 if (cornerType==EWindowCornerRegion) |
|
195 iBaseArea->ClipRect(FullRect()); |
|
196 else |
|
197 { |
|
198 TSize size=Size(); |
|
199 iBaseArea->Clear(); |
|
200 const TPoint *corners=NULL; |
|
201 TInt count=0; |
|
202 switch(cornerType) |
|
203 { |
|
204 case EWindowCorner1: |
|
205 count=sizeof(corner1)/sizeof(TPoint); |
|
206 corners=corner1; |
|
207 break; |
|
208 case EWindowCorner2: |
|
209 count=sizeof(corner2)/sizeof(TPoint); |
|
210 corners=corner2; |
|
211 break; |
|
212 case EWindowCorner3: |
|
213 count=sizeof(corner3)/sizeof(TPoint); |
|
214 corners=corner3; |
|
215 break; |
|
216 case EWindowCorner5: |
|
217 count=sizeof(corner5)/sizeof(TPoint); |
|
218 corners=corner5; |
|
219 break; |
|
220 default: |
|
221 break; |
|
222 } |
|
223 TInt top=0; |
|
224 TInt bot=size.iHeight; |
|
225 for(TInt index=0;index<count;index++) |
|
226 { |
|
227 TInt xadjust=corners[index].iX; |
|
228 TInt yadjust=corners[index].iY; |
|
229 if ((iCornerData&(EWindowCornerNotTL|EWindowCornerNotTR))!=(EWindowCornerNotTL|EWindowCornerNotTR)) |
|
230 { |
|
231 iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotTL?0:xadjust,top, |
|
232 size.iWidth-(iCornerData&EWindowCornerNotTR?0:xadjust),top+yadjust)); |
|
233 top+=yadjust; |
|
234 } |
|
235 if ((iCornerData&(EWindowCornerNotBL|EWindowCornerNotBR))!=(EWindowCornerNotBL|EWindowCornerNotBR)) |
|
236 { |
|
237 iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotBL?0:xadjust,bot-yadjust, |
|
238 size.iWidth-(iCornerData&EWindowCornerNotBR?0:xadjust),bot)); |
|
239 bot-=yadjust; |
|
240 } |
|
241 } |
|
242 iBaseArea->AddRect(TRect(0,top,size.iWidth,bot)); |
|
243 iBaseArea->Offset(Origin()); |
|
244 iBaseArea->ClipRect(FullRect()); |
|
245 iBaseArea->Sort(); |
|
246 } |
|
247 } |
|
248 |
|
249 void CWsClientWindow::GenerateArea(RWsRegion &aArea, TBool aClipTranslucent) const |
|
250 // |
|
251 // Create the window area list. |
|
252 // |
|
253 { |
|
254 aArea.Clear(); |
|
255 if (IsVisible()) |
|
256 { |
|
257 aArea.Copy(*iBaseArea); |
|
258 aArea.ClipRect(iAbs); |
|
259 const CWsClientWindow *win=this; |
|
260 FOREVER |
|
261 { |
|
262 if (win->IsTopClientWindow()) |
|
263 break; |
|
264 ClipWindows(aArea,(CWsClientWindow *)win->BaseParent()->BaseChild(),win,aClipTranslucent); |
|
265 win=(CWsClientWindow *)win->iParent; |
|
266 } |
|
267 TInt tidyCount=0; |
|
268 for(const CWsClientWindow *cwin=RootWindow()->FirstTopClientWindow();aArea.Count() && cwin!=win;cwin=cwin->NextSiblingMultiParent()) |
|
269 { |
|
270 if (!tidyCount--) |
|
271 { |
|
272 aArea.Tidy(); |
|
273 tidyCount=ETidyCountSetting; // Tidy every ETidyCountSetting times around |
|
274 } |
|
275 if (cwin->IsVisible()) |
|
276 { |
|
277 if (cwin->IsTranslucent() && !aClipTranslucent) |
|
278 { |
|
279 if (cwin->iUserDefinedOpaqueRegion) |
|
280 { |
|
281 aArea.SubRegion(*cwin->iUserDefinedOpaqueRegion); |
|
282 } |
|
283 } |
|
284 else |
|
285 { |
|
286 aArea.SubRegion(*cwin->iBaseArea); |
|
287 } |
|
288 } |
|
289 } |
|
290 aArea.Tidy(); |
|
291 } |
|
292 } |
|
293 |
|
294 void CWsClientWindow::ClipWindows(TRegion ®ion,const CWsClientWindow *start, const CWsClientWindow *end, TBool aClipTranslucent) |
|
295 // |
|
296 // Remove out of the region the opaque part of the abs rect of all the windows starting from 'start' |
|
297 // along the sibling list to (and not including) the end window. |
|
298 // |
|
299 { |
|
300 for(const CWsClientWindow *win=start;region.Count() && win!=end;win=win->NextSibling()) |
|
301 { |
|
302 if (win->IsVisible()) |
|
303 { |
|
304 if (win->IsTranslucent() && !aClipTranslucent) |
|
305 { |
|
306 if (win->iUserDefinedOpaqueRegion) |
|
307 { |
|
308 region.SubRegion(*win->iUserDefinedOpaqueRegion); |
|
309 } |
|
310 } |
|
311 else |
|
312 { |
|
313 region.SubRegion(*win->iBaseArea); |
|
314 } |
|
315 } |
|
316 } |
|
317 } |
|
318 |
|
319 void CWsClientWindow::GenerateTopRegion(RWsRegion& aRegion) const |
|
320 { |
|
321 GenerateArea(aRegion,ETrue); |
|
322 if (iChild) |
|
323 ClipWindows(aRegion,Child(),NULL,ETrue); |
|
324 } |
|
325 |
|
326 void CWsClientWindow::GenerateWindowRegion(RWsRegion &aRegion) const |
|
327 // |
|
328 // Calculate the windows clipping region without using the usual stored iArea or iRegion fields |
|
329 // this function is used by the screen backup code to calculate "what if" regions to work out |
|
330 // whether something would be visible if the backed up window didn't exist, on this basis we |
|
331 // don't want to modify the existing copies of iArea & iRegion. |
|
332 // |
|
333 { |
|
334 GenerateArea(aRegion,EFalse); |
|
335 if (iChild) |
|
336 ClipWindows(aRegion,Child(),NULL,EFalse); |
|
337 } |
|
338 |
|
339 void CWsClientWindow::RecalcChildAbs(const TPoint *aOffset) |
|
340 { |
|
341 CWsClientWindow *win=this; |
|
342 FOREVER |
|
343 { |
|
344 FOREVER |
|
345 { |
|
346 win->SetAbsFromRel(); |
|
347 if (aOffset) |
|
348 win->OffsetBaseArea(*aOffset); |
|
349 if (win->Child()==NULL) |
|
350 break; |
|
351 win=win->Child(); |
|
352 } |
|
353 FOREVER |
|
354 { |
|
355 if (win==this) |
|
356 return; |
|
357 if (win->NextSibling()!=NULL) |
|
358 { |
|
359 win=win->NextSibling(); |
|
360 break; |
|
361 } |
|
362 win=(CWsClientWindow *)win->iParent; // The cast is safe as the loop is aborted when win==this |
|
363 } |
|
364 } |
|
365 } |
|
366 |
|
367 void CWsClientWindow::SetAbsFromRel() |
|
368 { |
|
369 iOrigin=iRel.iTl+iParent->Origin(); |
|
370 iAbs=iRel; |
|
371 iAbs.Move(iParent->Origin()); |
|
372 iAbs.Intersection(iParent->AbsRect()); |
|
373 } |
|
374 |
|
375 void CWsClientWindow::SetExtentL(const TPoint *aPos,const TSize *aSize) |
|
376 { |
|
377 if (iParent==NULL) |
|
378 OwnerPanic(EWservPanicParentDeleted); |
|
379 TPoint offset = TPoint(0,0); |
|
380 TSize oldSize; |
|
381 TSize newSize; |
|
382 TBool sizeChanged = EFalse; |
|
383 TBool posChanged = EFalse; |
|
384 |
|
385 if (aPos) |
|
386 { |
|
387 offset = *aPos+iParent->Origin()-iOrigin; |
|
388 if (offset.iX != 0 || offset.iY != 0) |
|
389 { |
|
390 posChanged = ETrue; |
|
391 } |
|
392 } |
|
393 |
|
394 if (posChanged) |
|
395 { |
|
396 TWalkWindowTreeScheduleRedraws wwt; |
|
397 WalkWindowTree(wwt, EWalkChildren); |
|
398 } |
|
399 |
|
400 if (aSize) |
|
401 { |
|
402 newSize=*aSize; |
|
403 if (newSize.iWidth<0) |
|
404 newSize.iWidth=0; |
|
405 if (newSize.iHeight<0) |
|
406 newSize.iHeight=0; |
|
407 // This should be the only part of resizing that can fail |
|
408 // and it can only fail for backedup windows. |
|
409 iRedraw->PrepareForResizeL(newSize,oldSize); |
|
410 sizeChanged = *aSize != iRel.Size(); |
|
411 } |
|
412 |
|
413 if (posChanged) |
|
414 { |
|
415 iRel.Move(offset); |
|
416 RecalcChildAbs(&offset); |
|
417 TWalkWindowTreeOffsetTransparentRegions offsetTransparent(offset); |
|
418 WalkWindowTree(offsetTransparent, EWalkChildren); |
|
419 } |
|
420 |
|
421 if (sizeChanged) |
|
422 { |
|
423 iRel.SetSize(newSize); |
|
424 RecalcChildAbs(NULL); |
|
425 CalcBaseArea(); |
|
426 iRedraw->Resize(newSize,oldSize); |
|
427 } |
|
428 |
|
429 if (posChanged || sizeChanged) |
|
430 { |
|
431 iRedraw->ClipInvalidRegion(TRect(iRel.Size())); |
|
432 iRedraw->Moved(); |
|
433 ScheduleRegionUpdate(NULL); |
|
434 TWalkWindowTreeRecalcOpaque recalcOpaque; |
|
435 WalkWindowTree(recalcOpaque, EWalkChildren); |
|
436 } |
|
437 } |
|
438 |
|
439 void CWsClientWindow::Scroll(const TRect &aClipRect, const TPoint &aOffset, const TRect &aRect) |
|
440 { |
|
441 if (iParent==NULL) |
|
442 OwnerPanic(EWservPanicParentDeleted); |
|
443 // |
|
444 iRedraw->Scroll(aClipRect, aOffset,aRect); |
|
445 // |
|
446 CWsTop::TriggerRedraws(RootWindow()); |
|
447 } |
|
448 |
|
449 void CWsClientWindow::DeleteBaseArea() |
|
450 { |
|
451 WS_ASSERT_DEBUG(iBaseArea!=&nullRegion, EWsPanicRegionNull); |
|
452 if ((iCornerData&ECornerTypeMask)==EWindowCornerRegion) |
|
453 ((RWsRegion *)iBaseArea)->Destroy(); |
|
454 else |
|
455 delete iBaseArea; |
|
456 } |
|
457 |
|
458 CWsClientWindow::~CWsClientWindow() |
|
459 { |
|
460 iFlags|=EFlagShutDownInProgress; |
|
461 if (CClick::IsHandler()) |
|
462 { |
|
463 TWindowCloseData params; |
|
464 params.iClientHandle=iClientHandle; |
|
465 //if parent already shutdown (or disconnected) send 0 |
|
466 params.iWindowGroupId=iParent ? WinGroup()->Identifier():0; |
|
467 CClick::OtherEvent(EEventWindowClose,¶ms); |
|
468 } |
|
469 RemoveAllKeyRects(); |
|
470 while(iWinGcList) |
|
471 iWinGcList->Deactivate(); |
|
472 // |
|
473 iFlags|=EFlagInvisible; // First make it invisble |
|
474 if (iParent) // In case window wasn't fully constructed |
|
475 ResetHiddenFlags(); |
|
476 // |
|
477 CWsWindow::Shutdown(); // Two phase destruction |
|
478 |
|
479 DeleteBaseArea(); |
|
480 CWsPointerBuffer::Disconnect(this); |
|
481 iFlags&=~EFlagShutDownInProgress; |
|
482 SetUserTransparentRegion(0); |
|
483 CWsPassword::WindowDestroyed(this); |
|
484 } |
|
485 |
|
486 void CWsClientWindow::Activate() |
|
487 { |
|
488 if (iFlags&EFlagActive) |
|
489 OwnerPanic(EWservPanicWindowActive); |
|
490 iFlags|=EFlagActive; |
|
491 |
|
492 ResetHiddenFlags(); |
|
493 } |
|
494 |
|
495 void CWsClientWindow::SetCornerTypeL(TCornerType aCornerType, TInt aCornerFlags, TRegion *aNewBaseArea) |
|
496 { |
|
497 TRegion *baseArea=NULL; |
|
498 if (aCornerFlags&ECornerTypeMask) |
|
499 OwnerPanic(EWservPanicCornerParams); |
|
500 switch (aCornerType) |
|
501 { |
|
502 case EWindowCornerSquare: |
|
503 baseArea=new(ELeave) TRegionFix<1>(); |
|
504 break; |
|
505 case EWindowCorner1: |
|
506 baseArea=new(ELeave) TRegionFix<3>(); |
|
507 break; |
|
508 case EWindowCorner2: |
|
509 case EWindowCorner3: |
|
510 baseArea=new(ELeave) TRegionFix<5>(); |
|
511 break; |
|
512 case EWindowCorner5: |
|
513 baseArea=new(ELeave) TRegionFix<9>(); |
|
514 break; |
|
515 case EWindowCornerRegion: |
|
516 User::LeaveIfNull(baseArea=aNewBaseArea); |
|
517 baseArea->Offset(Origin()); |
|
518 break; |
|
519 default: |
|
520 OwnerPanic(EWservPanicCornerParams); |
|
521 } |
|
522 DeleteBaseArea(); |
|
523 iCornerData=aCornerType; |
|
524 iCornerData|=aCornerFlags; |
|
525 iBaseArea=baseArea; |
|
526 CalcBaseArea(); |
|
527 ScheduleRegionUpdate(NULL); |
|
528 } |
|
529 |
|
530 void CWsClientWindow::SetVisible(TBool aState) |
|
531 { |
|
532 if (aState) |
|
533 { |
|
534 if (iParent==NULL) |
|
535 OwnerPanic(EWservPanicParentDeleted); |
|
536 if (!(iFlags&EFlagInvisible)) // Already visible |
|
537 return; |
|
538 iFlags&=~EFlagInvisible; |
|
539 ResetHiddenFlags(); |
|
540 } |
|
541 else |
|
542 { |
|
543 if (iFlags&EFlagInvisible || !iParent) // Already invisible or parent has been deleted |
|
544 return; |
|
545 TWalkWindowTreePurgeEvents wwt; |
|
546 WalkWindowTree(wwt,EWalkChildren); // Destroy all events on this and all children |
|
547 iFlags|=EFlagInvisible; |
|
548 ResetHiddenFlags(); |
|
549 } |
|
550 } |
|
551 |
|
552 void CWsClientWindow::CommandL(TInt aOpcode, const TAny *aCmdData) |
|
553 { |
|
554 #ifdef _DEBUG |
|
555 // Save root window for performing CheckTree at the end of this func. |
|
556 // When aOpcode is EWsWinOpFree, this object would've been destroyed |
|
557 // and a call to RootWindow() in that case would be impossible |
|
558 CWsRootWindow* rootWindow=RootWindow(); |
|
559 #endif |
|
560 TWsWinCmdUnion pData; |
|
561 pData.any=aCmdData; |
|
562 if (CWsWindowBase::CommandL(aOpcode,pData)==EFalse) |
|
563 { |
|
564 switch(aOpcode) |
|
565 { |
|
566 case EWsWinOpActivate: |
|
567 Activate(); |
|
568 break; |
|
569 case EWsWinOpSetPos: |
|
570 SetExtentL(pData.pos,NULL); |
|
571 break; |
|
572 case EWsWinOpSetExtent: |
|
573 case EWsWinOpSetExtentErr: |
|
574 SetExtentL(&pData.SetEx->pos,&pData.SetEx->size); |
|
575 break; |
|
576 case EWsWinOpSetSize: |
|
577 case EWsWinOpSetSizeErr: |
|
578 SetExtentL(NULL,pData.size); |
|
579 break; |
|
580 case EWsWinOpInquireOffset: |
|
581 CWsClient::ReplyPoint(InquireOffset(*pData.UInt)); |
|
582 break; |
|
583 case EWsWinOpPosition: |
|
584 CWsClient::ReplyPoint(iRel.iTl); |
|
585 break; |
|
586 case EWsWinOpAbsPosition: |
|
587 CWsClient::ReplyPoint(iOrigin); |
|
588 break; |
|
589 case EWsWinOpSize: |
|
590 CWsClient::ReplySize(iRel.Size()); |
|
591 break; |
|
592 case EWsWinOpTestInvariant: |
|
593 SetReply(EFalse); |
|
594 break; |
|
595 case EWsWinOpPointerFilter: |
|
596 { |
|
597 TUint old=iPointerFilter; |
|
598 iPointerFilter&=~pData.PointerFilter->mask; |
|
599 iPointerFilter|=pData.PointerFilter->mask&pData.PointerFilter->flags; |
|
600 if (old&EPointerFilterEnterExit) |
|
601 WsPointer::ReLogWindow(this); |
|
602 } |
|
603 break; |
|
604 case EWsWinOpSetPointerGrab: |
|
605 if (*pData.Bool==EFalse) |
|
606 iFlags&=~EFlagPointerGrab; |
|
607 else |
|
608 iFlags|=EFlagPointerGrab; |
|
609 break; |
|
610 case EWsWinOpClaimPointerGrab: |
|
611 if (!iParent) |
|
612 OwnerPanic(EWservPanicParentDeleted); |
|
613 WsPointer::ClaimGrab(this,*pData.Bool); |
|
614 break; |
|
615 case EWsWinOpSetPointerCapture: |
|
616 iFlags&=~(EFlagPointerCaptured|EFlagPointerCaptureDragDrop|EFlagPointerCaptureAllGroups); |
|
617 if ((*pData.UInt)&RWindowBase::TCaptureFlagEnabled) |
|
618 { |
|
619 iFlags|=EFlagPointerCaptured; |
|
620 if ((*pData.UInt)&RWindowBase::TCaptureFlagDragDrop) |
|
621 iFlags|=EFlagPointerCaptureDragDrop; |
|
622 if ((*pData.UInt)&RWindowBase::TCaptureFlagAllGroups) |
|
623 iFlags|=EFlagPointerCaptureAllGroups; |
|
624 |
|
625 } |
|
626 WsPointer::ReLogCurrentWindow(); |
|
627 break; |
|
628 case EWsWinOpSetPointerCapturePriority: |
|
629 iPointerCapturePriority=*pData.Int; |
|
630 break; |
|
631 case EWsWinOpGetPointerCapturePriority: |
|
632 SetReply(iPointerCapturePriority); |
|
633 break; |
|
634 case EWsWinOpSetVisible: |
|
635 SetVisible(*pData.Bool); |
|
636 break; |
|
637 case EWsWinOpScroll: |
|
638 { |
|
639 TPoint origin(0,0); |
|
640 TRect src(TRect(origin,iRel.Size())); |
|
641 src.Move(-pData.ScrollRect->offset); |
|
642 Scroll(TRect(TPoint(0,0),iRel.Size()),pData.ScrollRect->offset,src); |
|
643 } |
|
644 break; |
|
645 case EWsWinOpScrollClip: |
|
646 { |
|
647 TPoint origin(0,0); |
|
648 TRect src(TRect(origin,iRel.Size())); |
|
649 src.Move(-pData.ScrollRect->offset); |
|
650 TRect clip(pData.ScrollRect->clip); |
|
651 Scroll(clip,pData.ScrollRect->offset,src); |
|
652 } |
|
653 break; |
|
654 case EWsWinOpScrollRect: |
|
655 { |
|
656 TRect src(pData.ScrollRect->rect); |
|
657 Scroll(TRect(TPoint(0,0),iRel.Size()),pData.ScrollRect->offset,src); |
|
658 } |
|
659 break; |
|
660 case EWsWinOpScrollClipRect: |
|
661 { |
|
662 TRect src(pData.ScrollRect->rect); |
|
663 TRect clip(pData.ScrollRect->clip); |
|
664 Scroll(clip, pData.ScrollRect->offset,src); |
|
665 } |
|
666 break; |
|
667 case EWsWinOpSetOrdinalPositionPri: |
|
668 iOrdinalPriority=pData.OrdinalPos->ordinalPriority; |
|
669 SetOrdinalPosition(pData.OrdinalPos->pos); |
|
670 break; |
|
671 case EWsWinOpSetShadowHeight: |
|
672 if ((*pData.Int)<0) |
|
673 OwnerPanic(EWservPanicNegativeShadowHeight); |
|
674 break; |
|
675 case EWsWinOpShadowDisabled: |
|
676 break; |
|
677 case EWsWinOpSetCornerType: |
|
678 SetCornerTypeL(pData.SetCornerType->type, pData.SetCornerType->flags); |
|
679 break; |
|
680 case EWsWinOpSetShape: |
|
681 SetCornerTypeL(EWindowCornerRegion,0,GetRegionFromClientL(iWsOwner, *pData.Int)); |
|
682 break; |
|
683 case EWsWinOpRequiredDisplayMode: |
|
684 if (Backup()!=NULL) |
|
685 OwnerPanic(EWservPanicBackupDisplayMode); |
|
686 SetReply(DisplayMode()); |
|
687 break; |
|
688 case EWsWinOpGetDisplayMode: |
|
689 SetReply(DisplayMode()); |
|
690 break; |
|
691 case EWsWinOpRequestPointerRepeatEvent: |
|
692 if (!iParent) |
|
693 OwnerPanic(EWservPanicParentDeleted); |
|
694 WsPointer::RequestPointerRepeatEvent(this,pData.RequestPointerRepeatEvent->time,pData.RequestPointerRepeatEvent->rect); |
|
695 break; |
|
696 case EWsWinOpCancelPointerRepeatEventRequest: |
|
697 WsPointer::CancelPointerRepeatEventRequest(); |
|
698 break; |
|
699 case EWsWinOpAllocPointerMoveBuffer: |
|
700 CWsPointerBuffer::ConnectL(this,pData.AllocPointerMoveBuffer->maxNumPoints,pData.AllocPointerMoveBuffer->flags); |
|
701 iFlags|=EFlagUsingPointerBuffer|EFlagHasPointerBuffer; |
|
702 break; |
|
703 case EWsWinOpFreePointerMoveBuffer: |
|
704 CWsPointerBuffer::Disconnect(this); |
|
705 iFlags&=~(EFlagUsingPointerBuffer|EFlagHasPointerBuffer); |
|
706 break; |
|
707 case EWsWinOpRetrievePointerMoveBuffer: |
|
708 CWsPointerBuffer::RetrievePointerMoveBuffer(this,*pData.Int); |
|
709 break; |
|
710 case EWsWinOpEnablePointerMoveBuffer: |
|
711 if (!(iFlags&EFlagHasPointerBuffer)) |
|
712 OwnerPanic(EWservPanicNoPointerBuffer); |
|
713 iFlags|=EFlagUsingPointerBuffer; |
|
714 break; |
|
715 case EWsWinOpDisablePointerMoveBuffer: |
|
716 iFlags&=~EFlagUsingPointerBuffer; |
|
717 /*Fall Through*/ |
|
718 case EWsWinOpDiscardPointerMoveBuffer: |
|
719 CWsPointerBuffer::DiscardPointerMoveBuffer(this); |
|
720 break; |
|
721 case EWsWinOpAddKeyRect: |
|
722 AddKeyRectL(pData.AddKeyRect->rect, pData.AddKeyRect->scanCode, pData.AddKeyRect->activatedByPointerSwitchOn); |
|
723 break; |
|
724 case EWsWinOpRemoveAllKeyRects: |
|
725 RemoveAllKeyRects(); |
|
726 break; |
|
727 case EWsWinOpPasswordWindow: |
|
728 if (!iParent) |
|
729 OwnerPanic(EWservPanicParentDeleted); |
|
730 CWsPassword::SetPasswordWindowL(this, *pData.PasswordMode); |
|
731 break; |
|
732 case EWsWinOpEnableBackup: |
|
733 if (!iParent) |
|
734 OwnerPanic(EWservPanicParentDeleted); |
|
735 if (*pData.UInt==0) |
|
736 iBackupsRequested|=EWindowBackupAreaBehind; //For backwards compatibility |
|
737 else |
|
738 iBackupsRequested|=*pData.UInt; |
|
739 break; |
|
740 case EWsWinOpFadeBehind: |
|
741 { |
|
742 if (!iParent) |
|
743 OwnerPanic(EWservPanicParentDeleted); |
|
744 TUint8 blackMap; |
|
745 TUint8 whiteMap; |
|
746 iScreen->GetFadingParams(blackMap,whiteMap); |
|
747 SetFadeBehind(*pData.Bool); |
|
748 TWalkWindowTreeSetFaded wwt(*pData.Bool,this,blackMap,whiteMap); |
|
749 WalkWindowTree(wwt,EWalkBehind); |
|
750 if (CWsTop::IsFadeEnabled()) |
|
751 { |
|
752 Screen()->AcceptFadeRequest( this, *pData.Bool, ETrue, EFalse ); |
|
753 } |
|
754 } |
|
755 break; |
|
756 case EWsWinOpGetIsFaded: |
|
757 SetReply(iFadeCount); |
|
758 break; |
|
759 case EWsWinOpGetIsNonFading: |
|
760 SetReply(iFlags&EFlagNonFadingWindow); |
|
761 break; |
|
762 case EWsWinOpMoveToGroup: |
|
763 if (!iParent) |
|
764 OwnerPanic(EWservPanicParentDeleted); |
|
765 if (iParent->WinType()!=EWinTypeGroup) |
|
766 OwnerPanic(EWservPanicNotTopClient); |
|
767 DoMoveWindowToGroupL(*pData.Int); |
|
768 break; |
|
769 case EWsWinOpTestLowPriorityRedraw: |
|
770 { |
|
771 // This is purely for testing purposes |
|
772 // Returns the redraw priority |
|
773 TUint priority=0; |
|
774 TPckgBuf<TUint> priBuf; |
|
775 priority=WsOwner()->RedrawQueue()->RedrawPriority((CWsWindowRedraw*)this->iRedraw); |
|
776 priBuf()=priority; |
|
777 CWsClient::ReplyBuf(priBuf); |
|
778 } |
|
779 break; |
|
780 case EWsWinOpEnableVisibilityChangeEvents: |
|
781 iFlags |= EFlagGeneratesVisibilityEvents; |
|
782 if (iFlags&EFlagActive) |
|
783 { |
|
784 iScreen->DoRedrawNow(); |
|
785 PossibleVisibilityChangedEvent(ETrue); |
|
786 } |
|
787 break; |
|
788 case EWsWinOpDisableVisibilityChangeEvents: |
|
789 iFlags &= ~EFlagGeneratesVisibilityEvents; |
|
790 break; |
|
791 case EWsWinOpSetTransparentRegion: |
|
792 { |
|
793 if (IsTranslucent()) |
|
794 { |
|
795 TInt recs=*pData.Int; |
|
796 RWsRegion* reg=recs>0? GetRegionFromClientL(iWsOwner,recs) : new(ELeave) RWsRegion; |
|
797 SetUserTransparentRegion(reg); |
|
798 SetReply(KErrNone); |
|
799 } |
|
800 else |
|
801 { |
|
802 OwnerPanic(EWservPanicTransparencyObjNotCreated); |
|
803 } |
|
804 } |
|
805 break; |
|
806 case EWsWinOpSetTransparencyPolicy: |
|
807 { |
|
808 if (IsTranslucent()) |
|
809 SetReply(KErrNone); |
|
810 else |
|
811 OwnerPanic(EWservPanicTransparencyObjNotCreated); |
|
812 } |
|
813 break; |
|
814 case EWsWinOpSetTransparencyAlphaChannel: |
|
815 { |
|
816 iFlags |= static_cast<TUint>(EFlagHasAlpha); |
|
817 SetReply(KErrNone); |
|
818 break; |
|
819 } |
|
820 default: |
|
821 if (iRedraw->CommandL(aOpcode,pData)==EFalse) |
|
822 { |
|
823 OwnerPanic(EWservPanicOpcode); |
|
824 } |
|
825 } |
|
826 } |
|
827 #if defined(_DEBUG) |
|
828 rootWindow->CheckTree(); |
|
829 #endif |
|
830 } |
|
831 |
|
832 void CWsClientWindow::GcActivated(CWsGc *aGc) |
|
833 { |
|
834 aGc->SetNextWinGc(iWinGcList); |
|
835 iWinGcList=aGc; |
|
836 } |
|
837 |
|
838 void CWsClientWindow::GcDeactivated(CWsGc *aGc) |
|
839 { |
|
840 if (aGc==iWinGcList) |
|
841 iWinGcList=aGc->NextWinGc(); |
|
842 else |
|
843 { |
|
844 CWsGc *gc=iWinGcList; |
|
845 CWsGc *next; |
|
846 FOREVER |
|
847 { |
|
848 next=gc->NextWinGc(); |
|
849 WS_ASSERT_DEBUG(next!=NULL, EWsPanicBadActiveGcList); |
|
850 if (next==aGc) |
|
851 { |
|
852 gc->SetNextWinGc(next->NextWinGc()); |
|
853 break; |
|
854 } |
|
855 gc=next; |
|
856 } |
|
857 } |
|
858 aGc->SetNextWinGc(NULL); |
|
859 } |
|
860 |
|
861 void CWsClientWindow::ReactivateGcs() |
|
862 { |
|
863 for (CWsGc * gc = iWinGcList; gc; gc = gc->NextWinGc()) |
|
864 { |
|
865 gc->Reactivate(); |
|
866 } |
|
867 } |
|
868 |
|
869 void CWsClientWindow::OffsetUserTransparentRegion(const TPoint& aOffset) |
|
870 { |
|
871 if (iUserDefinedTransparentRegion) |
|
872 { |
|
873 iUserDefinedTransparentRegion->Offset(aOffset); |
|
874 } |
|
875 } |
|
876 |
|
877 void CWsClientWindow::SetUserTransparentRegion(RWsRegion* aRegion) |
|
878 { |
|
879 if (iUserDefinedTransparentRegion) |
|
880 { |
|
881 iUserDefinedTransparentRegion->Close(); |
|
882 delete iUserDefinedTransparentRegion; |
|
883 iUserDefinedTransparentRegion = 0; |
|
884 } |
|
885 |
|
886 if (aRegion) |
|
887 { |
|
888 aRegion->Offset(iOrigin); |
|
889 iUserDefinedTransparentRegion=aRegion; |
|
890 } |
|
891 |
|
892 SetUserOpaqueRegion(); |
|
893 } |
|
894 |
|
895 void CWsClientWindow::SetUserOpaqueRegion() |
|
896 { |
|
897 if (iUserDefinedOpaqueRegion) |
|
898 { |
|
899 iUserDefinedOpaqueRegion->Close(); |
|
900 delete iUserDefinedOpaqueRegion; |
|
901 iUserDefinedOpaqueRegion = 0; |
|
902 } |
|
903 if (iUserDefinedTransparentRegion) |
|
904 { |
|
905 iUserDefinedOpaqueRegion=new RWsRegion; |
|
906 if (iUserDefinedOpaqueRegion) |
|
907 { |
|
908 iUserDefinedOpaqueRegion->Copy(*iBaseArea); |
|
909 iUserDefinedOpaqueRegion->SubRegion(*iUserDefinedTransparentRegion); |
|
910 if (iUserDefinedOpaqueRegion->CheckError() || iUserDefinedOpaqueRegion->Count() == 0) |
|
911 { |
|
912 iUserDefinedOpaqueRegion->Close(); |
|
913 delete iUserDefinedOpaqueRegion; |
|
914 iUserDefinedOpaqueRegion = 0; |
|
915 } |
|
916 } |
|
917 } |
|
918 } |
|
919 |
|
920 TUint CWsClientWindow::RedrawPriority(TInt *aShift) const |
|
921 { |
|
922 if (IsTopClientWindow()) |
|
923 { |
|
924 TUint ordinalPos=OrdinalPosition(EFalse); |
|
925 if (ordinalPos>KWinRedrawPriMaxOrdinal) // Algorithm only works for upto KWinRedrawPriMaxOrdinal windows, |
|
926 ordinalPos=KWinRedrawPriMaxOrdinal; // make all windows after this equal in priority |
|
927 if (aShift) |
|
928 *aShift=KWinRedrawPriMaxLevel; |
|
929 return(ordinalPos<<(KWinRedrawPriMaxLevel*KWinRedrawPriBitsPerLevel)); |
|
930 } |
|
931 else |
|
932 { |
|
933 TUint ordinalPos=OrdinalPosition(EFalse)+1; |
|
934 if (ordinalPos>KWinRedrawPriMaxOrdinal) // Algorithm only works upto 15 , make all windows after 15 equal in priority |
|
935 ordinalPos=KWinRedrawPriMaxOrdinal; |
|
936 TInt shift; |
|
937 TUint parent=((CWsClientWindow *)iParent)->RedrawPriority(&shift); |
|
938 if (shift>0) |
|
939 shift--; |
|
940 if (aShift) |
|
941 *aShift=shift; |
|
942 return(parent+(ordinalPos<<(shift*KWinRedrawPriBitsPerLevel))); |
|
943 } |
|
944 } |
|
945 |
|
946 TDblQue<TPointerKeyList> *CWsClientWindow::PointerKeyList() const |
|
947 { |
|
948 return(iPointerKeyList); |
|
949 } |
|
950 |
|
951 void CWsClientWindow::AddKeyRectL(const TRect &aRect, TInt aScanCode, TBool aActivatedByPointerSwitchOn) |
|
952 { |
|
953 if (!iPointerKeyList) |
|
954 iPointerKeyList=new(ELeave) TDblQue<TPointerKeyList>(_FOFF(TPointerKeyList,iQue)); |
|
955 TPointerKeyList *pkl=new(ELeave) TPointerKeyList(); |
|
956 iPointerKeyList->AddLast(*pkl); |
|
957 pkl->iRect=aRect; |
|
958 pkl->iScanCode=aScanCode; |
|
959 pkl->iActivatedByPointerSwitchOn=aActivatedByPointerSwitchOn; |
|
960 } |
|
961 |
|
962 void CWsClientWindow::RemoveAllKeyRects() |
|
963 { |
|
964 if (iPointerKeyList) |
|
965 { |
|
966 TPointerKeyList *pkl=NULL; |
|
967 for(TDblQueIter<TPointerKeyList> iter(*iPointerKeyList);(pkl=iter++)!=NULL;) |
|
968 { |
|
969 pkl->iQue.Deque(); |
|
970 delete pkl; |
|
971 } |
|
972 delete iPointerKeyList; |
|
973 iPointerKeyList=NULL; |
|
974 } |
|
975 } |
|
976 |
|
977 TBool CWsClientWindow::IsHidden() |
|
978 { |
|
979 return (!IsVisible()) || VisibleRegion().IsEmpty(); |
|
980 } |
|
981 |
|
982 void CWsClientWindow::SetFaded(TBool aFade,TUint8 aBlackMap,TUint8 aWhiteMap) |
|
983 { |
|
984 iBlackMap=aBlackMap; |
|
985 iWhiteMap=aWhiteMap; |
|
986 if (iAbsoluteFading) |
|
987 { |
|
988 if (aFade) |
|
989 { |
|
990 iFadeCount = 1; |
|
991 } |
|
992 else |
|
993 { |
|
994 iFadeCount = 0; |
|
995 } |
|
996 } |
|
997 else |
|
998 { |
|
999 if (aFade) |
|
1000 { |
|
1001 ++iFadeCount; |
|
1002 } |
|
1003 else if (iFadeCount > 0) |
|
1004 { |
|
1005 --iFadeCount; |
|
1006 } |
|
1007 } |
|
1008 } |
|
1009 |
|
1010 void CWsClientWindow::ResetHiddenFlagsInParentAndChildren() |
|
1011 { |
|
1012 ResetHiddenFlag(); |
|
1013 for(CWsClientWindow* child=Child();child;child=child->NextSibling()) |
|
1014 { |
|
1015 child->ResetHiddenFlagsInParentAndChildren(); |
|
1016 } |
|
1017 } |
|
1018 |
|
1019 const TRegion& CWsClientWindow::WindowArea() const |
|
1020 { |
|
1021 return *iBaseArea; |
|
1022 } |
|
1023 |
|
1024 void CWsClientWindow::Invalidate(const TRect * aRect) |
|
1025 { |
|
1026 iRedraw->Invalidate(aRect); |
|
1027 } |
|
1028 |
|
1029 void CWsClientWindow::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty) |
|
1030 { |
|
1031 if (IsVisible()) |
|
1032 { |
|
1033 iScreen->ScheduleRegionUpdate(aDefinitelyDirty); |
|
1034 } |
|
1035 } |
|
1036 |
|
1037 TBool CWsClientWindow::IsDSAHost() const |
|
1038 { |
|
1039 TBool res = CWsWindow::IsDSAHost(); |
|
1040 if ( !res ) |
|
1041 { // check for grace period when DSA is being restarted (after aborting but before client started DSA again) |
|
1042 res = Screen()->IsDSAClientWindow( this ); |
|
1043 } |
|
1044 return res; |
|
1045 } |
|
1046 void CWsClientWindow::SetScreenDeviceValidState(TBool aState) |
|
1047 { |
|
1048 if (SetScreenDeviceValidStateFlag(aState)) |
|
1049 ResetHiddenFlags(); |
|
1050 } |
|
1051 |
|
1052 TBool CWsClientWindow::SetScreenDeviceValidStateFlag(TBool aState) |
|
1053 { |
|
1054 TBool isSet=iFlags&EFlagScreenDeviceInvalid; |
|
1055 if (!isSet==!aState) |
|
1056 { |
|
1057 if (aState) |
|
1058 iFlags&=~EFlagScreenDeviceInvalid; |
|
1059 else |
|
1060 iFlags|=EFlagScreenDeviceInvalid; |
|
1061 return ETrue; |
|
1062 } |
|
1063 return EFalse; |
|
1064 } |
|
1065 |
|
1066 void CWsClientWindow::DoMoveWindowToGroupL(TInt aIdentifier) |
|
1067 { |
|
1068 CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(aIdentifier); |
|
1069 if (group==iParent) |
|
1070 return; |
|
1071 if (group->WsOwner()!=WsOwner()) |
|
1072 User::Leave(KErrNotFound); |
|
1073 ChangeWindowPosition(0, group); |
|
1074 CWsTop::TriggerRedraws(RootWindow()); |
|
1075 } |
|
1076 |
|
1077 void CWsClientWindow::SetInactive() |
|
1078 { |
|
1079 iFlags&=~EFlagActive; |
|
1080 ResetHiddenFlags(); |
|
1081 } |
|
1082 |