|
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 the License "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 // e32\ewsrv\ws_win.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include "ws_std.h" |
|
19 #include <e32hal.h> |
|
20 #include <hal.h> |
|
21 #include <domainmanager.h> |
|
22 |
|
23 #ifdef __VC32__ |
|
24 #pragma setlocale("english") |
|
25 #endif |
|
26 |
|
27 //#define __CHARACTERPOINTER |
|
28 |
|
29 GLREF_D CKeyTranslator *KeyTranslator; |
|
30 GLREF_D CKeyRepeat *KeyRepeat; |
|
31 |
|
32 const TInt KTabSize=4; |
|
33 |
|
34 #if defined(_UNICODE) // K.K |
|
35 #define FONTWIDTH 8 |
|
36 |
|
37 TBool CWsWindow::IsHankaku(const TText aCode) |
|
38 { |
|
39 if (aCode >= 0xff61 && aCode <= 0xff9f) |
|
40 return ETrue; // HANKAKU KATAKANA code |
|
41 if (aCode >= 0x2550 && aCode <= 0x259f) |
|
42 return ETrue; // HANKAKU Graphics code |
|
43 if (aCode < 0x100) |
|
44 return ETrue; // Alphanumeric codes means HANKAKU |
|
45 return EFalse; |
|
46 } |
|
47 |
|
48 TInt CWsWindow::FitInWidth(TText* aDest,TInt aWidth,TInt aAsciiCol,TText aCode) |
|
49 { |
|
50 TInt pixel=aAsciiCol*FONTWIDTH; |
|
51 TInt aJpnCol=0; |
|
52 TInt jw=0; |
|
53 TInt width; |
|
54 while (pixel>0) |
|
55 { |
|
56 TInt width=IsHankaku(aDest[aJpnCol++]) ? FONTWIDTH : FONTWIDTH*2; |
|
57 pixel-=width; |
|
58 jw+=width; |
|
59 } |
|
60 width=IsHankaku(aCode) ? FONTWIDTH : FONTWIDTH*2; |
|
61 TInt w=jw+width-aWidth*FONTWIDTH; |
|
62 while (w > 0) |
|
63 w-=IsHankaku(aDest[aJpnCol-- - 1]) ? FONTWIDTH : FONTWIDTH*2; |
|
64 aDest[aJpnCol]=aCode; |
|
65 return aJpnCol; |
|
66 } |
|
67 |
|
68 TInt CWsWindow::OffsetHZa(const TText* aDest,const TPoint& aPosition,const TSize& aSize,TInt& aX) |
|
69 { |
|
70 TInt i=aPosition.iY*aSize.iWidth; |
|
71 TInt j=0; |
|
72 TInt x=aPosition.iX*FONTWIDTH; |
|
73 while (x>0) |
|
74 x-=IsHankaku(aDest[i+j++]) ? FONTWIDTH : FONTWIDTH * 2; |
|
75 if (x<0) --j; |
|
76 aX=j; |
|
77 return(i+j); |
|
78 } |
|
79 |
|
80 TInt CWsWindow::OffsetHZwP(const TText* aDest,const TPoint& aPosition,const TSize& aSize,TPoint& aP) |
|
81 { |
|
82 aP=aPosition; |
|
83 TInt x; |
|
84 TInt offset=OffsetHZa(aDest,aPosition,aSize,x); |
|
85 aP.iX=x; |
|
86 return offset; |
|
87 } |
|
88 |
|
89 TInt CWsWindow::OffsetHZ(const TText* aDest,const TPoint& aPosition,const TSize& aSize) |
|
90 { |
|
91 TInt x; |
|
92 return OffsetHZa(aDest, aPosition, aSize, x); |
|
93 } |
|
94 |
|
95 TText CWsWindow::GetCharFromOffset(const TText* aDest,const TPoint& aPosition,const TSize& aSize) |
|
96 { |
|
97 return aDest[OffsetHZ(aDest, aPosition, aSize)]; |
|
98 } |
|
99 |
|
100 TText* CWsWindow::GetCpFromOffset(const TText* aDest,const TPoint& aPosition,const TSize& aSize) |
|
101 { |
|
102 return (TText * )(& aDest[OffsetHZ(aDest, aPosition, aSize)]); |
|
103 } |
|
104 #endif |
|
105 |
|
106 typedef CScreenDriver* (*TScreenDriverCreate)(); |
|
107 |
|
108 void CWsWindow::New() |
|
109 // |
|
110 // Acquire resources needed to run window system |
|
111 // |
|
112 { |
|
113 // Load EDISP.DLL from Z:\SYSTEM\LIBS and invoke ordinal 1 to |
|
114 // create the screen driver. This is because EDISP.DLL is hardware dependent. |
|
115 RLibrary edisp; |
|
116 ScreenDriver=NULL; |
|
117 TInt r=edisp.Load(_L("EDISP.DLL"), KNullDesC); |
|
118 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
119 Fault(EWindowsInitialisation); |
|
120 TScreenDriverCreate f=(TScreenDriverCreate)edisp.Lookup(1); |
|
121 if (f) |
|
122 ScreenDriver=(*f)(); |
|
123 __ASSERT_ALWAYS(ScreenDriver!=NULL,Fault(EWindowsInitialisation)); |
|
124 ScreenDriver->Init(ScreenSize,FontSize); |
|
125 ScreenDriver->SetMode(EMono); |
|
126 // Set up data |
|
127 ScreenColor=IndexOf[ETextAttributeNormal+1]; |
|
128 BorderColor=IndexOf[ETextAttributeNormal]; |
|
129 WindowBgColor=IndexOf[ETextAttributeNormal+1]; |
|
130 ScreenDriver->GetAttributeColors(IndexOf); |
|
131 CursorPeriodic=CPeriodic::New(ECursorPeriodicPriority); |
|
132 __ASSERT_ALWAYS(CursorPeriodic!=NULL,Fault(EWindowsInitialisation)); |
|
133 CursorPeriodic->Start(500000,500000,TCallBack(CWsWindow::FlashCursor,NULL)); |
|
134 Numbers=CBitMapAllocator::New(EMaxOpenWindows); |
|
135 __ASSERT_ALWAYS(Numbers!=NULL,Fault(EWindowsInitialisation)); |
|
136 Numbers->AllocAt(EBackgroundNumber); |
|
137 VisibilityMap=(TInt8 *)User::Alloc(ScreenSize.iWidth*ScreenSize.iHeight); |
|
138 __ASSERT_ALWAYS(VisibilityMap!=NULL,Fault(EWindowsInitialisation)); |
|
139 Mem::Fill(VisibilityMap,ScreenSize.iWidth*ScreenSize.iHeight,0); |
|
140 BlankLineText=(TText *)User::Alloc(sizeof(TText)*ScreenSize.iWidth); |
|
141 __ASSERT_ALWAYS(BlankLineText!=NULL,Fault(EWindowsInitialisation)); |
|
142 BlankLineAttributes=(ColorInformation *)User::Alloc(ScreenSize.iWidth*sizeof(ColorInformation)); |
|
143 __ASSERT_ALWAYS(BlankLineAttributes!=NULL,Fault(EWindowsInitialisation)); |
|
144 TextFill(BlankLineText,ScreenSize.iWidth,_S(" ")); |
|
145 Mem::Fill(BlankLineAttributes,ScreenSize.iWidth*sizeof(ColorInformation),ScreenColor); |
|
146 TInt err=MouseMutex.CreateLocal(); |
|
147 __ASSERT_ALWAYS(err==KErrNone,Fault(EWindowsInitialisation)); |
|
148 err=ServiceMutex.CreateLocal(); |
|
149 __ASSERT_ALWAYS(err==KErrNone,Fault(EWindowsInitialisation)); |
|
150 SetMode(EMono); |
|
151 } |
|
152 |
|
153 void CWsWindow::Delete() |
|
154 // |
|
155 // Release resources needed to run window system |
|
156 // |
|
157 { |
|
158 |
|
159 delete ScreenDriver; |
|
160 delete CursorPeriodic; |
|
161 delete Numbers; |
|
162 User::Free(VisibilityMap); |
|
163 User::Free(BlankLineText); |
|
164 User::Free(BlankLineAttributes); |
|
165 MouseMutex.Close(); |
|
166 ServiceMutex.Close(); |
|
167 } |
|
168 |
|
169 void CWsWindow::TextFill(TText *aBuffer,TInt aLength,const TText *aValue) |
|
170 // |
|
171 // This helper function provided because no UNICODE compatible fill function exists in User:: |
|
172 // |
|
173 { |
|
174 |
|
175 TPtr(aBuffer,aLength).Fill(*aValue,aLength); |
|
176 } |
|
177 |
|
178 TInt CWsWindow::Offset(const TPoint &aPosition,const TSize &aSize) |
|
179 // |
|
180 // Finds the offset of aPosition within an area of aSize dimensions |
|
181 // |
|
182 { |
|
183 |
|
184 return(aPosition.iY*aSize.iWidth+aPosition.iX); |
|
185 } |
|
186 |
|
187 TInt8 CWsWindow::NewNumberL() |
|
188 // |
|
189 // Issue a unique window id |
|
190 // |
|
191 { |
|
192 |
|
193 TInt8 n=(TInt8)Numbers->Alloc(); |
|
194 if (n<0) |
|
195 User::Leave(ETooManyWindowsOpen); |
|
196 return(n); |
|
197 } |
|
198 |
|
199 void CWsWindow::ReleaseNumber(TInt8 aNumber) |
|
200 // |
|
201 // Return unique window id back to the pool for future issuing |
|
202 // |
|
203 { |
|
204 |
|
205 Numbers->Free((TUint)aNumber); |
|
206 } |
|
207 |
|
208 TInt CWsWindow::FlashCursor(TAny* /*aParameter*/) |
|
209 // |
|
210 // Flash the cursor if it is on |
|
211 // |
|
212 { |
|
213 |
|
214 CWsWindow *pT=TopWindow(); |
|
215 if (pT) |
|
216 { |
|
217 BeginUpdateScreen(); |
|
218 if (pT->iCursorIsOn) |
|
219 { |
|
220 TPoint p=pT->iCursorPos-pT->iCurrentOffset; |
|
221 if (pT->IsInClippedTextArea(p) && p+pT->iViewOrigin!=MousePos) |
|
222 { |
|
223 //#if defined(_UNICODE) // K.K |
|
224 // TPoint sp; // K.K |
|
225 // TInt offset=pT->OffsetHZwP(pT->iTextBuffer, pT->iCursorPos, pT->iCurrentSize, sp); //K.K |
|
226 // const TText c = pT->iTextBuffer[offset]; // K.K |
|
227 // sp= sp - pT->iCurrentOffset; // K.K |
|
228 // ScreenDriver->Blit(&c, 1, sp+pT->iViewOrigin); // K.K |
|
229 //#else // K.K |
|
230 TInt i=Offset(pT->iCursorPos,pT->iCurrentSize); |
|
231 const TText c=pT->iTextBuffer[i]; |
|
232 ScreenDriver->SetForegroundColor(pT->iAttributeBuffer[i].iFg); |
|
233 ScreenDriver->SetBackgroundColor(pT->iAttributeBuffer[i].iBg); |
|
234 ScreenDriver->Blit(&c,1,p+pT->iViewOrigin); |
|
235 //#endif // K.K |
|
236 } |
|
237 pT->iCursorIsOn=EFalse; |
|
238 } |
|
239 else |
|
240 { |
|
241 if (pT->iCursorRequired && pT->iReadIsValid) |
|
242 { |
|
243 TPoint p=pT->iCursorPos-pT->iCurrentOffset; |
|
244 if (pT->IsInClippedTextArea(p)) |
|
245 { |
|
246 if (p+pT->iViewOrigin!=MousePos) |
|
247 { |
|
248 ScreenDriver->Blit(&(pT->iCursor),1,p+pT->iViewOrigin); |
|
249 //#if defined(_UNICODE) // K.K |
|
250 // TPoint sp; // K.K |
|
251 // pT->OffsetHZwP(pT->iTextBuffer, pT->iCursorPos, pT->iCurrentSize, sp); //K.K |
|
252 // sp= sp - pT->iCurrentOffset; // K.K |
|
253 // ScreenDriver->Blit(&(pT->iCursor),1,sp+pT->iViewOrigin); // K.K |
|
254 //#else // K.K |
|
255 ScreenDriver->SetForegroundColor(pT->iFgColor); |
|
256 ScreenDriver->SetBackgroundColor(WindowBgColor); |
|
257 ScreenDriver->Blit(&(pT->iCursor),1,p+pT->iViewOrigin); |
|
258 //#endif // K.K |
|
259 } |
|
260 pT->iCursorIsOn=ETrue; |
|
261 } |
|
262 } |
|
263 } |
|
264 EndUpdateScreen(); |
|
265 } |
|
266 return(KErrNone); |
|
267 } |
|
268 |
|
269 void CWsWindow::SetCursor() |
|
270 // |
|
271 // Place the text cursor for this window (if required) |
|
272 // |
|
273 { |
|
274 |
|
275 BeginUpdateScreen(); |
|
276 if (iCursorIsOn) |
|
277 { |
|
278 if (iCursorPos!=iLastCursorPos || !IsTop() || !iCursorRequired) |
|
279 { |
|
280 TPoint p=iLastCursorPos-iCurrentOffset; |
|
281 if (IsInClippedTextArea(p)) |
|
282 { |
|
283 TPoint q=p+iViewOrigin; |
|
284 if (q!=MousePos) |
|
285 { |
|
286 if(VisibilityMap[Offset(q,ScreenSize)]==iNumber) |
|
287 { |
|
288 //#if defined(_UNICODE) // K.K |
|
289 // TPoint sp; // K.K |
|
290 // TInt offset = OffsetHZwP(iTextBuffer, iLastCursorPos, iCurrentSize, sp); //K.K |
|
291 // sp= sp - iCurrentOffset; // K.K |
|
292 // const TText c = iTextBuffer[offset]; // K.K |
|
293 // sp = sp + iViewOrigin; // K.K |
|
294 // ScreenDriver->Blit(&c,1,sp); // K.K |
|
295 //#else // K.K |
|
296 TInt i=Offset(iLastCursorPos,iCurrentSize); |
|
297 const TText c=iTextBuffer[i]; |
|
298 ScreenDriver->SetForegroundColor(iAttributeBuffer[i].iFg); |
|
299 ScreenDriver->SetBackgroundColor(iAttributeBuffer[i].iBg); |
|
300 ScreenDriver->Blit(&c,1,q); |
|
301 //#endif // K.K |
|
302 } |
|
303 } |
|
304 iCursorIsOn=EFalse; |
|
305 } |
|
306 } |
|
307 } |
|
308 if (IsTop() && iCursorRequired && iReadIsValid) |
|
309 { |
|
310 TPoint p=iCursorPos-iCurrentOffset; |
|
311 if (IsInClippedTextArea(p)) |
|
312 { |
|
313 TPoint q=p+iViewOrigin; |
|
314 if (q!=MousePos) |
|
315 { |
|
316 //#if defined(_UNICODE) // K.K |
|
317 // TPoint sp; // K.K |
|
318 // OffsetHZwP(iTextBuffer, iLastCursorPos, iCurrentSize, sp); //K.K |
|
319 // sp= sp - iCurrentOffset; // K.K |
|
320 // sp = sp + iViewOrigin; // K.K |
|
321 // ScreenDriver->Blit(&iCursor,1,sp); // K.K |
|
322 //#else // K.K |
|
323 ScreenDriver->SetForegroundColor(iFgColor); |
|
324 ScreenDriver->SetBackgroundColor(WindowBgColor); |
|
325 ScreenDriver->Blit(&iCursor,1,q); |
|
326 //#endif // K.K |
|
327 } |
|
328 iLastCursorPos=iCursorPos; |
|
329 iCursorIsOn=ETrue; |
|
330 } |
|
331 } |
|
332 EndUpdateScreen(); |
|
333 } |
|
334 |
|
335 void CWsWindow::SetClip() |
|
336 // |
|
337 // Set the clipped width and depth. |
|
338 // |
|
339 { |
|
340 |
|
341 iClippedSize=ScreenSize-iViewOrigin; |
|
342 if (iClippedSize.iWidth>iViewSize.iWidth) |
|
343 iClippedSize.iWidth=iViewSize.iWidth; |
|
344 if (iClippedSize.iHeight>iViewSize.iHeight) |
|
345 iClippedSize.iHeight=iViewSize.iHeight; |
|
346 } |
|
347 |
|
348 void CWsWindow::ResetVisibilityMap() |
|
349 // |
|
350 // Recreate visibility map from window queue |
|
351 // |
|
352 { |
|
353 |
|
354 TDblQueIter<CWsWindow> q(WQueue); |
|
355 CWsWindow *pW; |
|
356 Mem::Fill(VisibilityMap,ScreenSize.iWidth*ScreenSize.iHeight,0); |
|
357 q.SetToLast(); |
|
358 while((pW=q--)!=NULL) |
|
359 { |
|
360 if (pW->iIsVisible) |
|
361 { |
|
362 TInt8 *pV=&VisibilityMap[Offset(pW->iViewOrigin,ScreenSize)]; |
|
363 for(TInt i=0; i<pW->iClippedSize.iHeight; i++) |
|
364 { |
|
365 Mem::Fill(pV,pW->iClippedSize.iWidth,pW->iNumber); |
|
366 pV+=ScreenSize.iWidth; |
|
367 } |
|
368 } |
|
369 } |
|
370 } |
|
371 |
|
372 void CWsWindow::BeginUpdateScreen() |
|
373 // |
|
374 // Prepare for a whole bunch of UpdateScreen() calls |
|
375 // |
|
376 { |
|
377 |
|
378 MouseMutex.Wait(); |
|
379 } |
|
380 |
|
381 void CWsWindow::EndUpdateScreen() |
|
382 // |
|
383 // End of bunch of UpdateScreen() calls |
|
384 // |
|
385 { |
|
386 |
|
387 MouseMutex.Signal(); |
|
388 } |
|
389 |
|
390 void CWsWindow::UpdateScreen(TPoint &aPosition,TInt aLength,TInt8 aNumber,TText *aTextBuffer,ColorInformation * anAttributeBuffer) |
|
391 // |
|
392 // This function purposefully made static,so that it can be used to update the background (aNumber=0) as well as |
|
393 // window data. Line by line, it finds contiguous sections of visible window (using aNumber in the visibility map) |
|
394 // and passes them to CScreenDriver::Blit(). |
|
395 // |
|
396 { |
|
397 |
|
398 TPoint q=aPosition; |
|
399 TInt8 *pV=&VisibilityMap[Offset(q,ScreenSize)]; |
|
400 TInt w=aLength; |
|
401 while(w>0) |
|
402 { |
|
403 if (*pV==aNumber) |
|
404 { |
|
405 TPoint p=q; |
|
406 TInt l=0; |
|
407 TColorIndex fg=anAttributeBuffer[aLength-w].iFg; |
|
408 TColorIndex bg=anAttributeBuffer[aLength-w].iBg; |
|
409 while(w>=0) |
|
410 { |
|
411 if (*pV==aNumber && w!=0 && anAttributeBuffer[aLength-w].iFg==fg && anAttributeBuffer[aLength-w].iBg==bg) |
|
412 { |
|
413 l++; |
|
414 w--; |
|
415 q.iX++; |
|
416 pV++; |
|
417 } |
|
418 else |
|
419 { |
|
420 TText *pT=&aTextBuffer[p.iX-aPosition.iX]; |
|
421 ScreenDriver->SetForegroundColor(fg); |
|
422 ScreenDriver->SetBackgroundColor(bg); |
|
423 ScreenDriver->Blit(pT,l,p); |
|
424 if (p.iY==MousePos.iY) |
|
425 { |
|
426 if (MousePos.iX>=p.iX && MousePos.iX<p.iX+l) |
|
427 TurnMouseOn(); |
|
428 } |
|
429 break; |
|
430 } |
|
431 } |
|
432 } |
|
433 else |
|
434 { |
|
435 w--; |
|
436 q.iX++; |
|
437 pV++; |
|
438 } |
|
439 } |
|
440 } |
|
441 |
|
442 TInt CWsWindow::SetMode(TVideoMode aMode) |
|
443 { |
|
444 |
|
445 TInt r=CWsWindow::ScreenDriver->SetMode(aMode); |
|
446 if(r!=KErrNone) |
|
447 return(r); |
|
448 CWsWindow::ScreenDriver->GetAttributeColors(IndexOf); |
|
449 CWsWindow::ScreenColor=IndexOf[ETextAttributeNormal+1]; |
|
450 CWsWindow::BorderColor=IndexOf[ETextAttributeNormal]; |
|
451 CWsWindow::WindowBgColor=IndexOf[ETextAttributeNormal+1]; |
|
452 CWsWindow::ChangeUIColors(); |
|
453 CWsWindow* w; |
|
454 TDblQueIter<CWsWindow>q(WQueue); |
|
455 while((w=q++)!=NULL) |
|
456 { |
|
457 w->iFgColor=IndexOf[ETextAttributeNormal]; |
|
458 w->iBgColor=IndexOf[ETextAttributeNormal+1]; |
|
459 } |
|
460 Redraw(); |
|
461 return KErrNone; |
|
462 } |
|
463 |
|
464 void CWsWindow::Display() |
|
465 // |
|
466 // Display a windows contents on the screen. |
|
467 // |
|
468 { |
|
469 |
|
470 if (iIsVisible) |
|
471 { |
|
472 TPoint p=iViewOrigin; |
|
473 TSize s=iClippedSize; |
|
474 BeginUpdateScreen(); |
|
475 TText *pT=&iTextBuffer[Offset(iCurrentOffset,iCurrentSize)]; |
|
476 ColorInformation *pA=&iAttributeBuffer[Offset(iCurrentOffset,iCurrentSize)]; |
|
477 while(s.iHeight>0) |
|
478 { |
|
479 UpdateScreen(p,s.iWidth,iNumber,pT,pA); |
|
480 s.iHeight--; |
|
481 p.iY++; |
|
482 pT=&pT[iCurrentSize.iWidth]; |
|
483 pA=&pA[iCurrentSize.iWidth]; |
|
484 } |
|
485 EndUpdateScreen(); |
|
486 SetCursor(); |
|
487 } |
|
488 } |
|
489 |
|
490 void CWsWindow::Background() |
|
491 // |
|
492 // Update wallpaper to physical screen |
|
493 // |
|
494 { |
|
495 |
|
496 TPoint p(0,0); |
|
497 BeginUpdateScreen(); |
|
498 while(p.iY<ScreenSize.iHeight) |
|
499 { |
|
500 UpdateScreen(p,ScreenSize.iWidth,0,BlankLineText,BlankLineAttributes); |
|
501 p.iY++; |
|
502 } |
|
503 EndUpdateScreen(); |
|
504 } |
|
505 |
|
506 void CWsWindow::Redraw() |
|
507 // |
|
508 // Redraw the whole screen including all the windows and the background |
|
509 // |
|
510 { |
|
511 |
|
512 CWsWindow *pW=TopWindow(); |
|
513 if (pW) |
|
514 pW->Refresh(); |
|
515 else |
|
516 { |
|
517 ResetVisibilityMap(); |
|
518 Background(); |
|
519 } |
|
520 } |
|
521 |
|
522 void CWsWindow::Refresh() |
|
523 // |
|
524 // Refresh this window and those below it |
|
525 // |
|
526 { |
|
527 |
|
528 CWsWindow* w; |
|
529 TDblQueIter<CWsWindow> q(WQueue); |
|
530 ResetVisibilityMap(); |
|
531 while(q++!=this) |
|
532 { |
|
533 } |
|
534 Display(); // this window |
|
535 while((w=q++)!=NULL) |
|
536 w->Display(); // lower windows |
|
537 Background(); |
|
538 } |
|
539 |
|
540 void CWsWindow::ChangeUIColors() |
|
541 // |
|
542 // Change UI colours as set by the user |
|
543 // |
|
544 { |
|
545 CWsWindow* w; |
|
546 |
|
547 TDblQueIter<CWsWindow>q(WQueue); |
|
548 while((w=q++)!=NULL) |
|
549 { |
|
550 TInt i=w->iCurrentSize.iWidth*w->iCurrentSize.iHeight; |
|
551 TColorIndex c=w->iAttributeBuffer[i-1].iBg; |
|
552 for(TInt t=0;t<i;t++) |
|
553 if (w->iAttributeBuffer[t].iBg==c) |
|
554 w->iAttributeBuffer[t].iBg=WindowBgColor; |
|
555 w->SetFrame(); |
|
556 } |
|
557 Mem::Fill(BlankLineAttributes,ScreenSize.iWidth*sizeof(ColorInformation),ScreenColor); |
|
558 Redraw(); |
|
559 } |
|
560 |
|
561 void CWsWindow::SetTextAttribute(TTextAttribute anAttribute) |
|
562 // |
|
563 // |
|
564 // |
|
565 { |
|
566 |
|
567 iFgColor=IndexOf[anAttribute*2]; |
|
568 iBgColor=IndexOf[anAttribute*2+1]; |
|
569 } |
|
570 |
|
571 void CWsWindow::Clear() |
|
572 // |
|
573 // Clear the whole window and place cursor at top left. |
|
574 // |
|
575 { |
|
576 |
|
577 TextFill(iTextBuffer,iCurrentSize.iWidth*iCurrentSize.iHeight,_S(" ")); |
|
578 Mem::Fill(iAttributeBuffer,iCurrentSize.iWidth*iCurrentSize.iHeight*sizeof(ColorInformation),WindowBgColor); |
|
579 SetFrame(); |
|
580 iCursorPos=TPoint(1,1); |
|
581 Display(); |
|
582 } |
|
583 |
|
584 void CWsWindow::Write(const TDesC &aBuffer) |
|
585 // |
|
586 // Write characters to the window |
|
587 // |
|
588 { |
|
589 |
|
590 const TText *b=aBuffer.Ptr(); |
|
591 const TText *bE=b+aBuffer.Length(); |
|
592 while(b<bE) |
|
593 { |
|
594 switch(*b) |
|
595 { |
|
596 case 0x00://Null |
|
597 break; |
|
598 case 0x07: |
|
599 User::Beep(440,100000); |
|
600 break; |
|
601 case 0x08://Backspace |
|
602 case 0x7f://Delete |
|
603 BackSpace(); |
|
604 break; |
|
605 case 0x09: |
|
606 HorizontalTab(); |
|
607 break; |
|
608 case 0x0a: |
|
609 LineFeed(); |
|
610 break; |
|
611 case 0x0b://Vertical tab - do nothing |
|
612 break; |
|
613 case 0x0c: |
|
614 FormFeed(); |
|
615 break; |
|
616 case 0x0d: |
|
617 CarriageReturn(); |
|
618 break; |
|
619 default: |
|
620 WriteCharacter(b); |
|
621 } |
|
622 b++; |
|
623 } |
|
624 } |
|
625 |
|
626 void CWsWindow::WriteCharacter(const TText *aCharacter) |
|
627 // |
|
628 // Write a single character at the current cursor location - must check if it's being written to an |
|
629 // position temporarily occupied by the frame. In this case, the character goes to the 'edge' of the |
|
630 // buffer. It will be restored from here when necessary. |
|
631 // |
|
632 { |
|
633 |
|
634 TPoint p=iCursorPos; |
|
635 TText *pT=&iTextBuffer[Offset(p,iCurrentSize)]; |
|
636 ColorInformation *pA=&iAttributeBuffer[Offset(p,iCurrentSize)]; |
|
637 if (p.iX>=iCurrentOffset.iX && p.iX<iCurrentOffset.iX+iViewSize.iWidth) // within view width |
|
638 { |
|
639 if (p.iY==iCurrentOffset.iY) // top edge |
|
640 { |
|
641 TPoint q=p; |
|
642 q.iY=0; |
|
643 pT=&iTextBuffer[Offset(q,iCurrentSize)]; |
|
644 pA=&iAttributeBuffer[Offset(q,iCurrentSize)]; |
|
645 } |
|
646 else if (p.iY==iCurrentOffset.iY+iViewSize.iHeight-1) // bottom edge |
|
647 { |
|
648 TPoint q=p; |
|
649 q.iY=iCurrentSize.iHeight-1; |
|
650 pT=&iTextBuffer[Offset(q,iCurrentSize)]; |
|
651 pA=&iAttributeBuffer[Offset(q,iCurrentSize)]; |
|
652 } |
|
653 } |
|
654 if (p.iY>=iCurrentOffset.iY && p.iY<iCurrentOffset.iY+iViewSize.iHeight) // within view depth |
|
655 { |
|
656 if (p.iX==iCurrentOffset.iX) // left edge |
|
657 { |
|
658 TPoint q=p; |
|
659 q.iX=0; |
|
660 pT=&iTextBuffer[Offset(q,iCurrentSize)]; |
|
661 pA=&iAttributeBuffer[Offset(q,iCurrentSize)]; |
|
662 } |
|
663 else if (p.iX==iCurrentOffset.iX+iViewSize.iWidth-1) // right edge |
|
664 { |
|
665 TPoint q=p; |
|
666 q.iX=iCurrentSize.iWidth-1; |
|
667 pT=&iTextBuffer[Offset(q,iCurrentSize)]; |
|
668 pA=&iAttributeBuffer[Offset(q,iCurrentSize)]; |
|
669 } |
|
670 } |
|
671 |
|
672 *pT=*aCharacter; |
|
673 pA->iFg=iFgColor; |
|
674 pA->iBg=iBgColor; |
|
675 |
|
676 p-=iCurrentOffset; |
|
677 |
|
678 if (IsInClippedTextArea(p)) |
|
679 { |
|
680 p+=iViewOrigin; |
|
681 TInt8 *pV=&VisibilityMap[Offset(p,ScreenSize)]; |
|
682 if (*pV==iNumber && p!=MousePos) |
|
683 { |
|
684 BeginUpdateScreen(); |
|
685 ScreenDriver->SetForegroundColor(iFgColor); |
|
686 ScreenDriver->SetBackgroundColor(iBgColor); |
|
687 ScreenDriver->Blit(aCharacter,1,p); |
|
688 EndUpdateScreen(); |
|
689 } |
|
690 if (iCursorIsOn && iCursorPos==((CWsWindow*)this)->iLastCursorPos) |
|
691 iCursorIsOn=EFalse; // Just overwrote the cursor character |
|
692 } |
|
693 Right(); |
|
694 } |
|
695 |
|
696 void CWsWindow::BackSpace() |
|
697 // |
|
698 // BS on this window |
|
699 // |
|
700 { |
|
701 |
|
702 if (iCursorPos!=TPoint(1,1)) |
|
703 { |
|
704 Left(); |
|
705 TColorIndex col=iBgColor; |
|
706 iBgColor=WindowBgColor; |
|
707 WriteCharacter(_S(" ")); |
|
708 iBgColor=col; |
|
709 Left(); |
|
710 } |
|
711 } |
|
712 |
|
713 void CWsWindow::HorizontalTab() |
|
714 // |
|
715 // Tab on this window |
|
716 // |
|
717 { |
|
718 |
|
719 iCursorPos.iX=iCursorPos.iX-(iCursorPos.iX-1)%KTabSize+KTabSize; |
|
720 if (iCursorPos.iX>iCurrentSize.iWidth-1) |
|
721 { |
|
722 CarriageReturn(); |
|
723 if (!iWrapLock) |
|
724 LineFeed(); |
|
725 } |
|
726 } |
|
727 |
|
728 void CWsWindow::FormFeed() |
|
729 // |
|
730 // FF on this window = clear the screen and place cursor at top left corner |
|
731 // |
|
732 { |
|
733 |
|
734 Clear(); |
|
735 Display(); |
|
736 } |
|
737 |
|
738 void CWsWindow::LineFeed() |
|
739 // |
|
740 // LF on this window (must do CR separately) |
|
741 // |
|
742 { |
|
743 |
|
744 if (iNewLineMode) |
|
745 CarriageReturn(); |
|
746 if (iCursorPos.iY<(iCurrentSize.iHeight-2)) |
|
747 iCursorPos.iY++; |
|
748 else |
|
749 ScrollUp(); |
|
750 } |
|
751 |
|
752 void CWsWindow::CarriageReturn() |
|
753 // |
|
754 // CR on this wiondow |
|
755 // |
|
756 { |
|
757 |
|
758 iCursorPos.iX=1; |
|
759 } |
|
760 |
|
761 void CWsWindow::Right() |
|
762 // |
|
763 // Move the cursor right one character. |
|
764 // |
|
765 { |
|
766 |
|
767 if (++iCursorPos.iX>=iCurrentSize.iWidth-1) |
|
768 { |
|
769 if (!iWrapLock) |
|
770 { |
|
771 CarriageReturn(); |
|
772 LineFeed(); |
|
773 } |
|
774 else iCursorPos.iX--; |
|
775 } |
|
776 } |
|
777 |
|
778 |
|
779 void CWsWindow::Left() |
|
780 // |
|
781 // Move the cursor left one character |
|
782 // |
|
783 { |
|
784 |
|
785 if (iCursorPos!=TPoint(1,1)) |
|
786 { |
|
787 if (iCursorPos.iX==1) |
|
788 { |
|
789 iCursorPos.iX+=iCurrentSize.iWidth-2; |
|
790 iCursorPos.iY--; |
|
791 } |
|
792 iCursorPos.iX--; |
|
793 } |
|
794 } |
|
795 |
|
796 void CWsWindow::RestoreEdges() |
|
797 // |
|
798 // Restore saved charcters from the 'edges' of the buffer back into their proper place in the buffer |
|
799 // |
|
800 { |
|
801 |
|
802 if (iCurrentOffset.iY!=0) // need to restore top edge |
|
803 { |
|
804 TPoint t(iCurrentOffset.iX,0); // Top left point of buffer 'edge' |
|
805 TPoint f(iCurrentOffset.iX,iCurrentOffset.iY); // Top left point of frame in buffer |
|
806 TText *pTT=&iTextBuffer[Offset(t,iCurrentSize)]; |
|
807 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
808 Mem::Copy(pTF,pTT,iViewSize.iWidth*sizeof(TText)); |
|
809 ColorInformation *pAT=&iAttributeBuffer[Offset(t,iCurrentSize)]; |
|
810 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
811 Mem::Copy(pAF,pAT,iViewSize.iWidth*sizeof(ColorInformation)); |
|
812 } |
|
813 if (iCurrentOffset.iY+iViewSize.iHeight!=iCurrentSize.iHeight) // need to save bottom edge |
|
814 { |
|
815 TPoint b(iCurrentOffset.iX,iCurrentSize.iHeight-1); // Bottom left point of buffer 'edge' |
|
816 TPoint f(iCurrentOffset.iX,iCurrentOffset.iY+iViewSize.iHeight-1); // Bottom left point of frame in buffer |
|
817 TText *pTB=&iTextBuffer[Offset(b,iCurrentSize)]; |
|
818 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
819 Mem::Copy(pTF,pTB,iViewSize.iWidth*sizeof(TText)); |
|
820 ColorInformation *pAB=&iAttributeBuffer[Offset(b,iCurrentSize)]; |
|
821 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
822 Mem::Copy(pAF,pAB,iViewSize.iWidth*sizeof(ColorInformation)); |
|
823 } |
|
824 if (iCurrentOffset.iX!=0) // need to save left hand edge |
|
825 { |
|
826 TPoint l(0,iCurrentOffset.iY); // Top left point of buffer 'edge' |
|
827 TPoint f(iCurrentOffset.iX,iCurrentOffset.iY); // Top left point of frame in buffer |
|
828 for(TInt y=0;y<iViewSize.iHeight;y++) |
|
829 { |
|
830 TText *pTL=&iTextBuffer[Offset(l,iCurrentSize)]; |
|
831 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
832 *pTF=*pTL; |
|
833 ColorInformation *pAL=&iAttributeBuffer[Offset(l,iCurrentSize)]; |
|
834 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
835 pAF->iFg=pAL->iFg; |
|
836 pAF->iBg=pAL->iBg; |
|
837 l.iY++; |
|
838 f.iY++; |
|
839 } |
|
840 } |
|
841 if (iCurrentOffset.iX+iViewSize.iWidth!=iCurrentSize.iWidth) // need to save right hand edge |
|
842 { |
|
843 TPoint r(iCurrentSize.iWidth-1,iCurrentOffset.iY); // Top right point of buffer 'edge' |
|
844 TPoint f(iCurrentOffset.iX+iViewSize.iWidth-1,iCurrentOffset.iY); // Top right point of frame in buffer |
|
845 for(TInt y=0;y<iViewSize.iHeight;y++) |
|
846 { |
|
847 TText *pTL=&iTextBuffer[Offset(r,iCurrentSize)]; |
|
848 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
849 *pTF=*pTL; |
|
850 ColorInformation *pAL=&iAttributeBuffer[Offset(r,iCurrentSize)]; |
|
851 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
852 pAF->iFg=pAL->iFg; |
|
853 pAF->iBg=pAL->iBg; |
|
854 r.iY++; |
|
855 f.iY++; |
|
856 } |
|
857 } |
|
858 } |
|
859 |
|
860 |
|
861 void CWsWindow::SaveEdges() |
|
862 // |
|
863 // Save charcters about to be stonked by the frame into the 'edges' of the buffer - the buffer is already 2 positions |
|
864 // wider and 2 positions deeper than requested when the window was set. |
|
865 // |
|
866 { |
|
867 |
|
868 if (iCurrentOffset.iY!=0) // need to save top edge |
|
869 { |
|
870 TPoint t(iCurrentOffset.iX,0); // Top left point of buffer 'edge' |
|
871 TPoint f(iCurrentOffset.iX,iCurrentOffset.iY); // Top left point of frame in buffer |
|
872 TText *pTT=&iTextBuffer[Offset(t,iCurrentSize)]; |
|
873 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
874 Mem::Copy(pTT,pTF,iViewSize.iWidth*sizeof(TText)); |
|
875 ColorInformation *pAT=&iAttributeBuffer[Offset(t,iCurrentSize)]; |
|
876 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
877 Mem::Copy(pAT,pAF,iViewSize.iWidth*sizeof(ColorInformation)); |
|
878 } |
|
879 if (iCurrentOffset.iY+iViewSize.iHeight!=iCurrentSize.iHeight) // need to save bottom edge |
|
880 { |
|
881 TPoint b(iCurrentOffset.iX,iCurrentSize.iHeight-1); // Bottom left point of buffer 'edge' |
|
882 TPoint f(iCurrentOffset.iX,iCurrentOffset.iY+iViewSize.iHeight-1); // Bottom left point of frame in buffer |
|
883 TText *pTB=&iTextBuffer[Offset(b,iCurrentSize)]; |
|
884 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
885 Mem::Copy(pTB,pTF,iViewSize.iWidth*sizeof(TText)); |
|
886 ColorInformation *pAB=&iAttributeBuffer[Offset(b,iCurrentSize)]; |
|
887 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
888 Mem::Copy(pAB,pAF,iViewSize.iWidth*sizeof(ColorInformation)); |
|
889 } |
|
890 if (iCurrentOffset.iX!=0) // need to save left hand edge |
|
891 { |
|
892 TPoint l(0,iCurrentOffset.iY); // Top left point of buffer 'edge' |
|
893 TPoint f(iCurrentOffset.iX,iCurrentOffset.iY); // Top left point of frame in buffer |
|
894 for(TInt y=0;y<iViewSize.iHeight;y++) |
|
895 { |
|
896 TText *pTL=&iTextBuffer[Offset(l,iCurrentSize)]; |
|
897 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
898 *pTL=*pTF; |
|
899 ColorInformation *pAL=&iAttributeBuffer[Offset(l,iCurrentSize)]; |
|
900 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
901 pAL->iFg=pAF->iFg; |
|
902 pAL->iBg=pAF->iBg; |
|
903 l.iY++; |
|
904 f.iY++; |
|
905 } |
|
906 } |
|
907 if (iCurrentOffset.iX+iViewSize.iWidth!=iCurrentSize.iWidth) // need to save right hand edge |
|
908 { |
|
909 TPoint r(iCurrentSize.iWidth-1,iCurrentOffset.iY); // Top right point of buffer 'edge' |
|
910 TPoint f(iCurrentOffset.iX+iViewSize.iWidth-1,iCurrentOffset.iY); // Top right point of frame in buffer |
|
911 for(TInt y=0;y<iViewSize.iHeight;y++) |
|
912 { |
|
913 TText *pTL=&iTextBuffer[Offset(r,iCurrentSize)]; |
|
914 TText *pTF=&iTextBuffer[Offset(f,iCurrentSize)]; |
|
915 *pTL=*pTF; |
|
916 ColorInformation *pAL=&iAttributeBuffer[Offset(r,iCurrentSize)]; |
|
917 ColorInformation *pAF=&iAttributeBuffer[Offset(f,iCurrentSize)]; |
|
918 pAL->iFg=pAF->iFg; |
|
919 pAL->iBg=pAF->iBg; |
|
920 r.iY++; |
|
921 f.iY++; |
|
922 } |
|
923 } |
|
924 } |
|
925 |
|
926 TBool CWsWindow::IsInClippedTextArea(const TPoint& aPoint) const |
|
927 // |
|
928 // Returns ETrue if aPoint (relative to window) is in the screen and the text part of the window |
|
929 // |
|
930 { |
|
931 |
|
932 return (aPoint.iX>0 && aPoint.iX<iClippedSize.iWidth-(iClippedSize.iWidth==iViewSize.iWidth) && aPoint.iY>0 && aPoint.iY<iClippedSize.iHeight-(iClippedSize.iHeight==iViewSize.iHeight)); |
|
933 } |
|
934 |
|
935 TBool CWsWindow::IsRectVisible(TRect& aRect) const |
|
936 // |
|
937 // Returns ETrue if window is visible in aRect, possibly clips edges to make a visible rectangle |
|
938 // |
|
939 { |
|
940 |
|
941 if (IsTop()) |
|
942 return ETrue; |
|
943 |
|
944 //First clip off the left |
|
945 TInt top=-1; |
|
946 TInt bottom=aRect.iBr.iY; |
|
947 TInt j; |
|
948 TInt i; |
|
949 for (i=aRect.iTl.iX;i<aRect.iBr.iX && top==-1;i++) |
|
950 { |
|
951 for (j=aRect.iTl.iY;j<aRect.iBr.iY;j++) |
|
952 { |
|
953 if (VisibilityMap[Offset(TPoint(i,j),ScreenSize)]!=iNumber) |
|
954 { |
|
955 if (top!=-1 && bottom==aRect.iBr.iY) |
|
956 bottom=j; |
|
957 } |
|
958 else |
|
959 { |
|
960 if (bottom!=aRect.iBr.iY) |
|
961 return EFalse; |
|
962 if (top==-1) |
|
963 top=j; |
|
964 } |
|
965 } |
|
966 } |
|
967 |
|
968 if (top==-1) //Area completely covered |
|
969 { |
|
970 aRect.iTl=aRect.iBr; |
|
971 return ETrue;//It is a rectangle - the zero rectangle |
|
972 } |
|
973 aRect.iTl.iX=i-1; |
|
974 |
|
975 TBool passedEdge=EFalse;//Right edge |
|
976 for (;i<aRect.iBr.iX && !passedEdge;i++) |
|
977 { |
|
978 for (j=aRect.iTl.iY;j<aRect.iBr.iY;j++) |
|
979 { |
|
980 if (VisibilityMap[Offset(TPoint(i,j),ScreenSize)]==iNumber) |
|
981 { |
|
982 if (passedEdge || j<top || j>=bottom) |
|
983 return EFalse; |
|
984 } |
|
985 else |
|
986 { |
|
987 if (j==top) |
|
988 passedEdge=ETrue; |
|
989 if (!passedEdge && j>top && j<bottom) |
|
990 return EFalse; |
|
991 } |
|
992 } |
|
993 } |
|
994 |
|
995 if (passedEdge) |
|
996 { |
|
997 TInt right=i-1; |
|
998 |
|
999 for (;i<aRect.iBr.iX;i++) |
|
1000 for (j=aRect.iTl.iY;j<aRect.iBr.iY;j++) |
|
1001 if (VisibilityMap[Offset(TPoint(i,j),ScreenSize)]==iNumber) |
|
1002 return EFalse; |
|
1003 aRect.iBr.iX=right; |
|
1004 } |
|
1005 aRect.iTl.iY=top; |
|
1006 aRect.iBr.iY=bottom; |
|
1007 return ETrue; |
|
1008 } |
|
1009 |
|
1010 void CWsWindow::ScrollUp() |
|
1011 // |
|
1012 // Scroll the window up by one line. |
|
1013 // |
|
1014 { |
|
1015 |
|
1016 if (!iScrollLock) |
|
1017 { |
|
1018 RestoreEdges(); |
|
1019 TurnMouseOff(); |
|
1020 TText *pT=&iTextBuffer[iCurrentSize.iWidth]; |
|
1021 Mem::Copy(pT,&pT[iCurrentSize.iWidth],iCurrentSize.iWidth*(iCurrentSize.iHeight-3)*sizeof(TText)); |
|
1022 TextFill(&pT[iCurrentSize.iWidth*(iCurrentSize.iHeight-3)],iCurrentSize.iWidth*sizeof(TText),_S(" ")); |
|
1023 ColorInformation *pA=&iAttributeBuffer[iCurrentSize.iWidth]; |
|
1024 Mem::Copy(pA,&pA[iCurrentSize.iWidth],iCurrentSize.iWidth*(iCurrentSize.iHeight-3)*sizeof(ColorInformation)); |
|
1025 Mem::Fill(&pA[iCurrentSize.iWidth*(iCurrentSize.iHeight-3)],iCurrentSize.iWidth*sizeof(ColorInformation),WindowBgColor); |
|
1026 SaveEdges(); |
|
1027 SetFrame(); |
|
1028 |
|
1029 TBool oldCursorRequired = iCursorRequired; |
|
1030 iCursorRequired = EFalse; |
|
1031 SetCursor(); |
|
1032 |
|
1033 if (iIsVisible) |
|
1034 { |
|
1035 |
|
1036 TRect updateRect(iViewOrigin.iX+1,iViewOrigin.iY+1,iViewOrigin.iX+iViewSize.iWidth-1,iViewOrigin.iY+iViewSize.iHeight-1); |
|
1037 updateRect.Intersection(TRect(TPoint(0,0),ScreenSize)); |
|
1038 if (IsRectVisible(updateRect)) |
|
1039 { |
|
1040 #ifndef __X86__ |
|
1041 if (ScreenDriver->ScrollUp(updateRect)) |
|
1042 { |
|
1043 //Update bottom line |
|
1044 updateRect.iTl.iY=updateRect.iBr.iY-1; |
|
1045 pT=&iTextBuffer[Offset(updateRect.iTl-iViewOrigin,iCurrentSize)]; |
|
1046 pA=&iAttributeBuffer[Offset(updateRect.iTl-iViewOrigin,iCurrentSize)]; |
|
1047 TColorIndex fg=pA->iFg; |
|
1048 TColorIndex bg=pA->iBg; |
|
1049 TInt k=updateRect.Width(); |
|
1050 TInt l=0; |
|
1051 for(TInt i=0;i<k;i++) |
|
1052 { |
|
1053 if(fg==pA->iFg && bg==pA->iBg && i!=k-1) |
|
1054 l++; |
|
1055 else |
|
1056 { |
|
1057 if(i==k-1) l++; |
|
1058 ScreenDriver->SetForegroundColor(fg); |
|
1059 ScreenDriver->SetBackgroundColor(bg); |
|
1060 ScreenDriver->Blit(pT,l,updateRect.iTl); |
|
1061 pT+=l; |
|
1062 pA+=l; |
|
1063 fg=(pA+1)->iFg; |
|
1064 bg=(pA+1)->iBg; |
|
1065 l=1; |
|
1066 } |
|
1067 } |
|
1068 } |
|
1069 else |
|
1070 #endif |
|
1071 Display(); |
|
1072 } |
|
1073 } |
|
1074 |
|
1075 iCursorRequired = oldCursorRequired; |
|
1076 SetCursor(); |
|
1077 TurnMouseOn(); |
|
1078 } |
|
1079 } |
|
1080 |
|
1081 void CWsWindow::TurnMouseOff() |
|
1082 // |
|
1083 // Take the mouse of the screen |
|
1084 // |
|
1085 { |
|
1086 #ifdef __CHARACTERPOINTER |
|
1087 CWsWindow *pW=MouseWindow(); |
|
1088 #if defined(_UNICODE) // K.K |
|
1089 TPoint sp=MousePos; // K.K |
|
1090 if (pW) |
|
1091 { |
|
1092 TPoint p=MousePos-pW->iViewOrigin+pW->iCurrentOffset; |
|
1093 TInt offset=pW->OffsetHZwP(pW->iTextBuffer,p,pW->iCurrentSize,sp); // K.K |
|
1094 sp=sp+pW->iViewOrigin-pW->iCurrentOffset; // K.K |
|
1095 TText c=pW->iTextBuffer[offset]; // K.K |
|
1096 if (pW->iCursorIsOn && p==pW->iCursorPos-pW->iCurrentOffset) |
|
1097 c=pW->iCursor; |
|
1098 ScreenDriver->SetForegroundColor(pW->iAttributeBuffer[offset].iFg); |
|
1099 ScreenDriver->SetBackgroundColor(pW->iAttributeBuffer[offset].iBg); |
|
1100 ScreenDriver->Blit(&c, 1, sp); // K.K |
|
1101 } |
|
1102 else |
|
1103 { |
|
1104 ScreenDriver->SetBackgroundColor(ScreenColor); |
|
1105 ScreenDriver->Blit(BlankLineText, 1, sp); // K.K |
|
1106 } |
|
1107 #else // K.K |
|
1108 if (pW) |
|
1109 { |
|
1110 TPoint p=MousePos-pW->iViewOrigin+pW->iCurrentOffset; |
|
1111 TText c=pW->iTextBuffer[Offset(p,pW->iCurrentSize)]; |
|
1112 if (pW->iCursorIsOn && p==pW->iCursorPos-pW->iCurrentOffset) |
|
1113 c=pW->iCursor; |
|
1114 ScreenDriver->SetForegroundColor(pW->iAttributeBuffer[Offset(p,pW->iCurrentSize)].iFg); |
|
1115 ScreenDriver->SetBackgroundColor(pW->iAttributeBuffer[Offset(p,pW->iCurrentSize)].iBg); |
|
1116 ScreenDriver->Blit(&c, 1, MousePos); |
|
1117 } |
|
1118 else |
|
1119 { |
|
1120 ScreenDriver->SetBackgroundColor(ScreenColor); |
|
1121 ScreenDriver->Blit(BlankLineText, 1, MousePos); |
|
1122 } |
|
1123 #endif // K.K |
|
1124 |
|
1125 #endif // __CHARACTERPOINTER |
|
1126 } |
|
1127 |
|
1128 void CWsWindow::TurnMouseOn() |
|
1129 // |
|
1130 // Place the mouse on the screen |
|
1131 // |
|
1132 { |
|
1133 |
|
1134 #ifdef __CHARACTERPOINTER |
|
1135 const TText c=EMouseCharacter; |
|
1136 ScreenDriver->SetForegroundColor(BorderColor); |
|
1137 ScreenDriver->Blit(&c, 1, MousePos); |
|
1138 #endif |
|
1139 } |
|
1140 |
|
1141 void CWsWindow::MouseMove(TPoint aGraphicsPosition) |
|
1142 // |
|
1143 // Move the mouse to a new position |
|
1144 // |
|
1145 { |
|
1146 |
|
1147 TPoint p=aGraphicsPosition; |
|
1148 p.iX/=FontSize.iWidth; |
|
1149 p.iY/=FontSize.iHeight; |
|
1150 if (p.iX>=ScreenSize.iWidth) |
|
1151 p.iX=ScreenSize.iWidth-1; |
|
1152 if (p.iY>=ScreenSize.iHeight) |
|
1153 p.iY=ScreenSize.iHeight-1; |
|
1154 if (p.iX<0) |
|
1155 p.iX=0; |
|
1156 if (p.iY<0) |
|
1157 p.iY=0; |
|
1158 if (MousePos!=p) |
|
1159 { |
|
1160 MouseMutex.Wait(); |
|
1161 TurnMouseOff(); |
|
1162 MousePos=p; |
|
1163 TurnMouseOn(); |
|
1164 MouseMutex.Signal(); |
|
1165 CWsWindow* tw=TopWindow(); |
|
1166 if (ScrollWithMouse!=TPoint(-1,-1)) |
|
1167 { |
|
1168 if (tw) |
|
1169 tw->MouseSlide(); |
|
1170 } |
|
1171 else if (MoveWithMouse!=TPoint(-1,-1)) |
|
1172 { |
|
1173 if (tw) |
|
1174 { |
|
1175 if(MousePos.iX<tw->iViewOrigin.iX-1||MousePos.iX>tw->iViewOrigin.iX+tw->iCurrentSize.iWidth||MousePos.iY<tw->iViewOrigin.iY-1||MousePos.iY>tw->iViewOrigin.iY+tw->iCurrentSize.iHeight) |
|
1176 { |
|
1177 MoveWithMouse=TPoint(-1,-1); |
|
1178 return; |
|
1179 } |
|
1180 CWsWindow::MoveTopWindowRelative(MousePos-MoveWithMouse); |
|
1181 MoveWithMouse=MousePos; |
|
1182 if(MousePos.iX==0 && tw->iViewOrigin.iX!=0) |
|
1183 CWsWindow::MoveTopWindowRelative(TPoint(-tw->iViewOrigin.iX,0)); |
|
1184 if(MousePos.iY==0 && tw->iViewOrigin.iY!=0) |
|
1185 CWsWindow::MoveTopWindowRelative(TPoint(0,-tw->iViewOrigin.iY)); |
|
1186 } |
|
1187 } |
|
1188 else if (ResizeWithMouse!=TPoint(-1,-1)) |
|
1189 { |
|
1190 TInt r=CWsWindow::ChangeTopWindowSize(TSize(MousePos.iX-ResizeWithMouse.iX,MousePos.iY-ResizeWithMouse.iY)); |
|
1191 if(!r) |
|
1192 ResizeWithMouse=MousePos; |
|
1193 } |
|
1194 } |
|
1195 } |
|
1196 |
|
1197 void CWsWindow::MouseSlide() |
|
1198 // |
|
1199 // Scroll the window |
|
1200 // |
|
1201 { |
|
1202 |
|
1203 if(ScrollWithMouse.iX && MousePos.iX!=ScrollWithMouse.iX) |
|
1204 { |
|
1205 TInt r=SlideTopWindowRelative(TPoint((MousePos.iX-ScrollWithMouse.iX)*ScrollSpeed,0)); |
|
1206 if(!r) |
|
1207 ScrollWithMouse.iX=MousePos.iX; |
|
1208 else if(MousePos.iX<ScrollWithMouse.iX) |
|
1209 { |
|
1210 SlideTopWindowRelative(TPoint(-iCurrentOffset.iX,0)); |
|
1211 if(MousePos.iX<=iViewOrigin.iX) |
|
1212 ScrollWithMouse.iX=iViewOrigin.iX+1; |
|
1213 else |
|
1214 ScrollWithMouse.iX=MousePos.iX; |
|
1215 } |
|
1216 else |
|
1217 { |
|
1218 SlideTopWindowRelative(TPoint(iCurrentSize.iWidth-iViewSize.iWidth-iCurrentOffset.iX,0)); |
|
1219 if(MousePos.iX>iViewOrigin.iX+iViewSize.iWidth-2) |
|
1220 ScrollWithMouse.iX=iViewOrigin.iX+iViewSize.iWidth-2; |
|
1221 else |
|
1222 ScrollWithMouse.iX=MousePos.iX; |
|
1223 } |
|
1224 } |
|
1225 else if(ScrollWithMouse.iY && MousePos.iY!=ScrollWithMouse.iY) |
|
1226 { |
|
1227 TInt r=SlideTopWindowRelative(TPoint(0,(MousePos.iY-ScrollWithMouse.iY)*ScrollSpeed)); |
|
1228 if(!r) |
|
1229 ScrollWithMouse.iY=MousePos.iY; |
|
1230 else if(MousePos.iY<ScrollWithMouse.iY) |
|
1231 { |
|
1232 SlideTopWindowRelative(TPoint(0,-iCurrentOffset.iY)); |
|
1233 if(MousePos.iY<=iViewOrigin.iY) |
|
1234 ScrollWithMouse.iY=iViewOrigin.iY+1; |
|
1235 else |
|
1236 ScrollWithMouse.iY=MousePos.iY; |
|
1237 } |
|
1238 else |
|
1239 { |
|
1240 SlideTopWindowRelative(TPoint(0,iCurrentSize.iHeight-iViewSize.iHeight-iCurrentOffset.iY)); |
|
1241 if(MousePos.iY>iViewOrigin.iY+iViewSize.iHeight-2) |
|
1242 ScrollWithMouse.iY=iViewOrigin.iY+iViewSize.iHeight-2; |
|
1243 else |
|
1244 ScrollWithMouse.iY=MousePos.iY; |
|
1245 } |
|
1246 } |
|
1247 |
|
1248 } |
|
1249 |
|
1250 void CWsWindow::InformTopMouse(TPoint aPos) |
|
1251 // |
|
1252 // Called if mouse has been captured |
|
1253 // |
|
1254 { |
|
1255 |
|
1256 CWsWindow *pM=TopWindow(); |
|
1257 if(pM) |
|
1258 pM->InformMouse(aPos); |
|
1259 } |
|
1260 |
|
1261 void CWsWindow::MouseLeftButton() |
|
1262 // |
|
1263 // Called when the left button is pressed |
|
1264 // |
|
1265 { |
|
1266 |
|
1267 CWsWindow *pM=MouseWindow(); |
|
1268 CWsWindow *pT=TopWindow(); |
|
1269 if (pT && !MouseIsCaptured) |
|
1270 { |
|
1271 if (pM) |
|
1272 { |
|
1273 if(pM!=pT) |
|
1274 pM->MakeTopWindow(); |
|
1275 if(pM==TopWindow()) |
|
1276 pM->DoMouseLeftButton(); |
|
1277 } |
|
1278 else |
|
1279 RotateWindowsForwards(); |
|
1280 } |
|
1281 } |
|
1282 |
|
1283 void CWsWindow::MouseLeftButtonUp() |
|
1284 // |
|
1285 // Called when the left button is released |
|
1286 // |
|
1287 { |
|
1288 ScrollWithMouse=TPoint(-1,-1); |
|
1289 MoveWithMouse=TPoint(-1,-1); |
|
1290 ResizeWithMouse=TPoint(-1,-1); |
|
1291 } |
|
1292 |
|
1293 CWsWindow *CWsWindow::MouseWindow() |
|
1294 // |
|
1295 // Return the window containing the mouse. |
|
1296 // |
|
1297 { |
|
1298 |
|
1299 TInt8 n=VisibilityMap[Offset(MousePos,ScreenSize)]; |
|
1300 if (n!=0) |
|
1301 { |
|
1302 CWsWindow *pW; |
|
1303 TDblQueIter<CWsWindow> q(WQueue); |
|
1304 for(pW=q++;pW->iNumber!=n;pW=q++) |
|
1305 ; |
|
1306 return(pW); |
|
1307 } |
|
1308 else |
|
1309 return(NULL); |
|
1310 } |
|
1311 |
|
1312 TBool CWsWindow::IsTop() const |
|
1313 // |
|
1314 // Return TRUE if this window is the top window |
|
1315 // |
|
1316 { |
|
1317 |
|
1318 return(WQueue.IsFirst(this)); |
|
1319 } |
|
1320 |
|
1321 CWsWindow* CWsWindow::TopWindow() |
|
1322 // |
|
1323 // Return the top window |
|
1324 // |
|
1325 { |
|
1326 |
|
1327 if (WQueue.IsEmpty()) |
|
1328 return(NULL); |
|
1329 return(WQueue.First()); |
|
1330 } |
|
1331 |
|
1332 CWsWindow *CWsWindow::BottomWindow() |
|
1333 // |
|
1334 // Return the bottom window |
|
1335 // |
|
1336 { |
|
1337 |
|
1338 if (WQueue.IsEmpty()) |
|
1339 return(NULL); |
|
1340 return(WQueue.Last()); |
|
1341 } |
|
1342 |
|
1343 void CWsWindow::MakeTopWindow() |
|
1344 // |
|
1345 // Make this window the top window if possible |
|
1346 // |
|
1347 { |
|
1348 |
|
1349 ResizeWithMouse=TPoint(-1,-1); |
|
1350 ScrollWithMouse=TPoint(-1,-1); |
|
1351 iLink.Deque(); |
|
1352 if(iOnTop||WQueue.IsEmpty()||!TopWindow()->iOnTop) |
|
1353 { |
|
1354 CWsWindow *pT=TopWindow(); |
|
1355 WQueue.AddFirst(*this); |
|
1356 if(pT) |
|
1357 pT->SetFrame(); |
|
1358 } |
|
1359 else |
|
1360 { |
|
1361 TDblQueIter<CWsWindow> q(WQueue); |
|
1362 q.SetToFirst(); |
|
1363 do |
|
1364 q++; |
|
1365 while(q!=NULL&&((CWsWindow*)q)->iOnTop); |
|
1366 if (q==NULL) |
|
1367 WQueue.AddLast(*this); |
|
1368 else |
|
1369 { |
|
1370 q--; |
|
1371 iLink.Enque(&(((CWsWindow*)q)->iLink)); |
|
1372 } |
|
1373 } |
|
1374 SetFrame(); |
|
1375 Refresh(); |
|
1376 } |
|
1377 |
|
1378 void CWsWindow::SetWindowPosAbs(const TPoint &aPoint) |
|
1379 // |
|
1380 // Move the window to aPoint |
|
1381 // |
|
1382 { |
|
1383 |
|
1384 ResizeWithMouse=TPoint(-1,-1); |
|
1385 ScrollWithMouse=TPoint(-1,-1); |
|
1386 iViewOrigin=aPoint; |
|
1387 if (iViewOrigin.iX<0) |
|
1388 iViewOrigin.iX=0; |
|
1389 else if (iViewOrigin.iX>=ScreenSize.iWidth) |
|
1390 iViewOrigin.iX=ScreenSize.iWidth-1; |
|
1391 if (iViewOrigin.iY<0) |
|
1392 iViewOrigin.iY=0; |
|
1393 else if (iViewOrigin.iY>=ScreenSize.iHeight) |
|
1394 iViewOrigin.iY=ScreenSize.iHeight-1; |
|
1395 SetClip(); |
|
1396 Refresh(); |
|
1397 } |
|
1398 |
|
1399 TInt CWsWindow::MoveTopWindowRelative(TPoint aDirection) |
|
1400 // |
|
1401 // Move the top window relative to its current position |
|
1402 // |
|
1403 { |
|
1404 |
|
1405 CWsWindow *pT=TopWindow(); |
|
1406 if (pT) |
|
1407 { |
|
1408 TPoint p=pT->iViewOrigin+aDirection; |
|
1409 if (p.iX>=ScreenSize.iWidth || p.iX<0 || p.iY>=ScreenSize.iHeight || p.iY<0) |
|
1410 return KErrArgument; |
|
1411 pT->iViewOrigin=p; |
|
1412 pT->SetClip(); |
|
1413 pT->Refresh(); |
|
1414 } |
|
1415 return KErrNone; |
|
1416 } |
|
1417 |
|
1418 TInt CWsWindow::SlideTopWindowRelative(TPoint aDirection) |
|
1419 // |
|
1420 // Slide the top window relative to its current position |
|
1421 // |
|
1422 { |
|
1423 |
|
1424 CWsWindow *pT=TopWindow(); |
|
1425 if (pT && pT->iAllowSlide && aDirection!=TPoint(0,0)) |
|
1426 { |
|
1427 TPoint p=pT->iCurrentOffset+aDirection; |
|
1428 TSize s=pT->iCurrentSize-pT->iViewSize; |
|
1429 if (p.iX>s.iWidth || p.iX<0 || p.iY>s.iHeight || p.iY<0) |
|
1430 return KErrArgument; |
|
1431 pT->RestoreEdges(); |
|
1432 pT->iCurrentOffset=p; |
|
1433 pT->SaveEdges(); |
|
1434 pT->SetFrame(); |
|
1435 pT->Display(); |
|
1436 } |
|
1437 return KErrNone; |
|
1438 } |
|
1439 |
|
1440 TInt CWsWindow::ChangeTopWindowSize(TSize aGrowth) |
|
1441 // |
|
1442 // Increase the viewing size of the top window relative to its current size |
|
1443 // |
|
1444 { |
|
1445 |
|
1446 CWsWindow *pT=TopWindow(); |
|
1447 if (pT && pT->iAllowResize) |
|
1448 { |
|
1449 TSize s=pT->iViewSize+aGrowth; |
|
1450 if (s.iWidth>pT->iCurrentSize.iWidth || s.iWidth<3 || s.iHeight>pT->iCurrentSize.iHeight || s.iHeight<3) |
|
1451 return KErrArgument; |
|
1452 pT->RestoreEdges(); |
|
1453 pT->iViewSize=s; |
|
1454 s=pT->iCurrentSize-pT->iViewSize; |
|
1455 if (pT->iCurrentOffset.iX>s.iWidth ||pT-> iCurrentOffset.iY>s.iHeight) |
|
1456 pT->iCurrentOffset-=aGrowth; |
|
1457 pT->SaveEdges(); |
|
1458 pT->SetFrame(); |
|
1459 pT->SetClip(); |
|
1460 pT->Refresh(); |
|
1461 } |
|
1462 return KErrNone; |
|
1463 } |
|
1464 |
|
1465 void CWsWindow::RotateWindowsForwards() |
|
1466 // |
|
1467 // Put the next window on top |
|
1468 // |
|
1469 { |
|
1470 |
|
1471 CWsWindow *pT=TopWindow(); |
|
1472 if(pT && pT->iOnTop==EFalse) |
|
1473 { |
|
1474 CWsWindow *pB=BottomWindow(); |
|
1475 if (pT!=pB) |
|
1476 { |
|
1477 MoveWithMouse=TPoint(-1,-1); |
|
1478 ResizeWithMouse=TPoint(-1,-1); |
|
1479 ScrollWithMouse=TPoint(-1,-1); |
|
1480 do |
|
1481 { |
|
1482 pB->iLink.Deque(); |
|
1483 WQueue.AddFirst(*pB); |
|
1484 pT->SetFrame(); |
|
1485 pB->SetFrame(); |
|
1486 pT=TopWindow(); |
|
1487 pB=BottomWindow(); |
|
1488 } |
|
1489 while(!pT->iIsVisible); |
|
1490 pT->Refresh(); |
|
1491 } |
|
1492 } |
|
1493 } |
|
1494 |
|
1495 void CWsWindow::RotateWindowsBackwards() |
|
1496 // |
|
1497 // Put the previous window on top |
|
1498 // |
|
1499 { |
|
1500 |
|
1501 CWsWindow *pT=TopWindow(); |
|
1502 if(pT && pT->iOnTop==EFalse) |
|
1503 { |
|
1504 CWsWindow *pB=BottomWindow(); |
|
1505 if (pT!=pB) |
|
1506 { |
|
1507 MoveWithMouse=TPoint(-1,-1); |
|
1508 ResizeWithMouse=TPoint(-1,-1); |
|
1509 ScrollWithMouse=TPoint(-1,-1); |
|
1510 do |
|
1511 { |
|
1512 pT->iLink.Deque(); |
|
1513 WQueue.AddLast(*pT); |
|
1514 pT->SetFrame(); |
|
1515 pT=TopWindow(); |
|
1516 } |
|
1517 while(!pT->iIsVisible); |
|
1518 pT->SetFrame(); |
|
1519 pT->Refresh(); |
|
1520 } |
|
1521 } |
|
1522 } |
|
1523 |
|
1524 void CWsWindow::QueueTopWindowKey(TKeyData &aKeystroke) |
|
1525 // |
|
1526 // Place keystroke in top window's keyboard queue |
|
1527 // |
|
1528 { |
|
1529 CWsWindow *pT=TopWindow(); |
|
1530 if (pT) |
|
1531 pT->QueueWindowKey(aKeystroke); |
|
1532 } |
|
1533 |
|
1534 void CWsWindow::KeyPress(TKeyData &aKeystroke) |
|
1535 // |
|
1536 // Called whenever a key is pressed |
|
1537 // |
|
1538 { |
|
1539 switch(aKeystroke.iKeyCode) |
|
1540 { |
|
1541 case EKeyIncContrast: |
|
1542 { |
|
1543 TInt max=0; |
|
1544 if (HAL::Get(HAL::EDisplayContrastMax,max)==KErrNone) |
|
1545 { |
|
1546 TInt now=0; |
|
1547 HAL::Get(HAL::EDisplayContrast,now); |
|
1548 if (now++<max) |
|
1549 HAL::Set(HAL::EDisplayContrast,now); |
|
1550 } |
|
1551 } |
|
1552 break; |
|
1553 case EKeyDecContrast: |
|
1554 { |
|
1555 TInt now=0; |
|
1556 TInt r=HAL::Get(HAL::EDisplayContrast,now); |
|
1557 if (r==KErrNone && now-->0) |
|
1558 HAL::Set(HAL::EDisplayContrast,now); |
|
1559 } |
|
1560 break; |
|
1561 case EKeyIncBrightness: |
|
1562 { |
|
1563 TInt max=0; |
|
1564 if (HAL::Get(HAL::EDisplayBrightnessMax,max)==KErrNone) |
|
1565 { |
|
1566 TInt now=0; |
|
1567 HAL::Get(HAL::EDisplayBrightness,now); |
|
1568 if (now++<max) |
|
1569 HAL::Set(HAL::EDisplayBrightness,now); |
|
1570 } |
|
1571 } |
|
1572 break; |
|
1573 case EKeyDecBrightness: |
|
1574 { |
|
1575 TInt now=0; |
|
1576 TInt r=HAL::Get(HAL::EDisplayBrightness,now); |
|
1577 if (r==KErrNone && now-->0) |
|
1578 HAL::Set(HAL::EDisplayBrightness,now); |
|
1579 } |
|
1580 break; |
|
1581 case EKeyOff: |
|
1582 { |
|
1583 RDmDomainManager mgr; |
|
1584 TInt r = mgr.Connect(); |
|
1585 if (r != KErrNone) |
|
1586 User::Panic(_L("EWSRV KeyOff0"), r); |
|
1587 TRequestStatus status; |
|
1588 mgr.RequestSystemTransition(EPwStandby, status); |
|
1589 User::WaitForRequest(status); |
|
1590 if (status.Int() != KErrNone) |
|
1591 User::Panic(_L("EWSRV KeyOff1"), status.Int()); |
|
1592 mgr.Close(); |
|
1593 } |
|
1594 break; |
|
1595 case EKeyBacklightOn: |
|
1596 HAL::Set(HAL::EBacklightState,ETrue); |
|
1597 break; |
|
1598 case EKeyBacklightOff: |
|
1599 HAL::Set(HAL::EBacklightState,EFalse); |
|
1600 break; |
|
1601 case EKeyBacklightToggle: |
|
1602 { |
|
1603 TBool state; |
|
1604 if (HAL::Get(HAL::EBacklightState,state)==KErrNone) |
|
1605 HAL::Set(HAL::EBacklightState,!state); |
|
1606 } |
|
1607 break; |
|
1608 default: |
|
1609 if (aKeystroke.iModifiers&EModifierCtrl) // Trap all Crtl + keystrokes for window manipulation |
|
1610 { |
|
1611 if (aKeystroke.iModifiers&EModifierShift) |
|
1612 { // Ctrl + Shift |
|
1613 switch(aKeystroke.iKeyCode) |
|
1614 { |
|
1615 case EKeyLeftArrow: |
|
1616 SlideTopWindowRelative(TPoint(-1,0)); |
|
1617 break; |
|
1618 case EKeyRightArrow: |
|
1619 SlideTopWindowRelative(TPoint(1,0)); |
|
1620 break; |
|
1621 case EKeyUpArrow: |
|
1622 SlideTopWindowRelative(TPoint(0,-1)); |
|
1623 break; |
|
1624 case EKeyDownArrow: |
|
1625 SlideTopWindowRelative(TPoint(0,1)); |
|
1626 break; |
|
1627 default: |
|
1628 QueueTopWindowKey(aKeystroke); // Buffer keystroke for app |
|
1629 break; |
|
1630 } |
|
1631 } |
|
1632 else |
|
1633 { // Ctrl |
|
1634 switch(aKeystroke.iKeyCode) |
|
1635 { |
|
1636 case EKeyLeftArrow: |
|
1637 ChangeTopWindowSize(TSize(-1,0)); |
|
1638 break; |
|
1639 case EKeyRightArrow: |
|
1640 ChangeTopWindowSize(TSize(1,0)); |
|
1641 break; |
|
1642 case EKeyUpArrow: |
|
1643 ChangeTopWindowSize(TSize(0,-1)); |
|
1644 break; |
|
1645 case EKeyDownArrow: |
|
1646 ChangeTopWindowSize(TSize(0,1)); |
|
1647 break; |
|
1648 case '1': |
|
1649 ScreenDriver->SetMode(EMono); |
|
1650 break; |
|
1651 case '2': |
|
1652 ScreenDriver->SetMode(EGray4); |
|
1653 break; |
|
1654 case '4': |
|
1655 ScreenDriver->SetMode(EGray16); |
|
1656 break; |
|
1657 case '0': |
|
1658 ControlTopWindowMaximised(ETrue); |
|
1659 break; |
|
1660 case '9': |
|
1661 ControlTopWindowMaximised(EFalse); |
|
1662 break; |
|
1663 case '5': |
|
1664 KeyRepeat->Cancel(); |
|
1665 RotateWindowsBackwards(); |
|
1666 break; |
|
1667 case '6': |
|
1668 KeyRepeat->Cancel(); |
|
1669 RotateWindowsForwards(); |
|
1670 break; |
|
1671 default: |
|
1672 QueueTopWindowKey(aKeystroke); // Buffer keystroke for app |
|
1673 break; |
|
1674 } |
|
1675 } |
|
1676 } |
|
1677 else if (aKeystroke.iModifiers&EModifierShift) |
|
1678 |
|
1679 { // Shift |
|
1680 switch(aKeystroke.iKeyCode) |
|
1681 { |
|
1682 case EKeyLeftArrow: |
|
1683 MoveTopWindowRelative(TPoint(-1,0)); |
|
1684 break; |
|
1685 case EKeyRightArrow: |
|
1686 MoveTopWindowRelative(TPoint(1,0)); |
|
1687 break; |
|
1688 case EKeyUpArrow: |
|
1689 MoveTopWindowRelative(TPoint(0,-1)); |
|
1690 break; |
|
1691 case EKeyDownArrow: |
|
1692 MoveTopWindowRelative(TPoint(0,1)); |
|
1693 break; |
|
1694 default: |
|
1695 QueueTopWindowKey(aKeystroke); // Buffer keystroke for app |
|
1696 break; |
|
1697 } |
|
1698 } |
|
1699 if (!(aKeystroke.iModifiers&EModifierShift||aKeystroke.iModifiers&EModifierCtrl)) |
|
1700 QueueTopWindowKey(aKeystroke); |
|
1701 } |
|
1702 DrainAllReadRequests(); |
|
1703 } |
|
1704 |
|
1705 void CWsWindow::ControlInformAllMouse(TBool anIndicator) |
|
1706 // |
|
1707 // Turn reporting of pointer events on or off according to the value of anIndicator |
|
1708 // |
|
1709 { |
|
1710 |
|
1711 MouseIsCaptured=anIndicator; |
|
1712 } |
|
1713 |
|
1714 void CWsWindow::ControlTopWindowMaximised(TBool anIndicator) |
|
1715 // |
|
1716 // Maximise or minimise the top window according to the value of anIndicator |
|
1717 // |
|
1718 { |
|
1719 |
|
1720 CWsWindow *pT=TopWindow(); |
|
1721 if(pT) |
|
1722 pT->ControlMaximised(anIndicator); |
|
1723 } |
|
1724 |
|
1725 void CWsWindow::DrainAllReadRequests() |
|
1726 // |
|
1727 // Drain all the satisfied read requests on all waiting windows |
|
1728 // |
|
1729 { |
|
1730 |
|
1731 TDblQueIter<CWsWindow> q(WQueue); |
|
1732 CWsWindow *pW; |
|
1733 while((pW=q++)!=NULL) |
|
1734 pW->DrainReadRequest(); |
|
1735 } |
|
1736 |
|
1737 #pragma warning( disable : 4705 ) // statement has no effect |
|
1738 CWsWindow::CWsWindow() |
|
1739 : iNumber(-1) |
|
1740 // |
|
1741 // Constructor. |
|
1742 // |
|
1743 { |
|
1744 } |
|
1745 #pragma warning( default : 4705 ) |
|
1746 |
|
1747 void CWsWindow::SetTitle(const TDesC &aName) |
|
1748 // |
|
1749 // Changes the window's title |
|
1750 // |
|
1751 { |
|
1752 |
|
1753 iTitle=aName; |
|
1754 SetFrame(); |
|
1755 Display(); |
|
1756 } |
|
1757 |
|
1758 void CWsWindow::SetSize(const TSize &aSize) |
|
1759 // |
|
1760 // Changes the window's size |
|
1761 // |
|
1762 { |
|
1763 iCurrentSize=aSize; // This does not get called. Proper implementation is obviously more complicated than this. |
|
1764 } |
|
1765 |
|
1766 TSize CWsWindow::Size() |
|
1767 // |
|
1768 // Return underlying window size |
|
1769 // |
|
1770 { |
|
1771 return(iCurrentSize); |
|
1772 } |
|
1773 |
|
1774 CWsWindow::~CWsWindow() |
|
1775 // |
|
1776 // Destructor |
|
1777 // |
|
1778 { |
|
1779 |
|
1780 SWsKey *pS; |
|
1781 while(!iKQueue.IsEmpty()) |
|
1782 { |
|
1783 pS=iKQueue.First(); |
|
1784 iKQueue.Remove(*pS); |
|
1785 delete pS; |
|
1786 } |
|
1787 User::Free(iTextBuffer); |
|
1788 User::Free(iAttributeBuffer); |
|
1789 if (iNumber >= 0) |
|
1790 { |
|
1791 ReleaseNumber(iNumber); |
|
1792 } |
|
1793 if (iLink.iNext!=NULL) |
|
1794 iLink.Deque(); |
|
1795 if(!WQueue.IsEmpty()) |
|
1796 WQueue.First()->SetFrame(); |
|
1797 |
|
1798 Redraw(); |
|
1799 } |
|
1800 |
|
1801 |
|
1802 void CWsWindow::SetView() |
|
1803 // |
|
1804 // Assign an initial wiewing region to a window (this maybe modified later by the user) |
|
1805 // |
|
1806 { |
|
1807 |
|
1808 Count&=3; // Increment count through the sequence 0, 1, 2, 3, 0, 1, 2, .... |
|
1809 iViewSize.iWidth=ScreenSize.iWidth>>1; // View is half width and half depth of physical screen |
|
1810 iViewSize.iHeight=ScreenSize.iHeight>>1; // View is half width and half depth of physical screen |
|
1811 iViewOrigin=TPoint(0,0); |
|
1812 if (iViewSize.iWidth<30 || iViewSize.iHeight<10) |
|
1813 iViewSize=ScreenSize; |
|
1814 else |
|
1815 { |
|
1816 if (Count&1) |
|
1817 iViewOrigin.iX+=iViewSize.iWidth; |
|
1818 if (Count&2) |
|
1819 iViewOrigin.iY+=iViewSize.iHeight; |
|
1820 } |
|
1821 if (iViewSize.iWidth>iCurrentSize.iWidth) |
|
1822 iViewSize.iWidth=iCurrentSize.iWidth; |
|
1823 if (iViewSize.iHeight>iCurrentSize.iHeight) |
|
1824 iViewSize.iHeight=iCurrentSize.iHeight; |
|
1825 Count++; |
|
1826 } |
|
1827 |
|
1828 void CWsWindow::SetFull() |
|
1829 // |
|
1830 // Calculate the view size and origin for this window if it were maximised and placed centrally |
|
1831 // |
|
1832 { |
|
1833 |
|
1834 if (iCurrentSize.iWidth>ScreenSize.iWidth) |
|
1835 { |
|
1836 iMaximumOrigin.iX=0; |
|
1837 iMaximumSize.iWidth=ScreenSize.iWidth; |
|
1838 } |
|
1839 else |
|
1840 { |
|
1841 iMaximumOrigin.iX=(ScreenSize.iWidth-iCurrentSize.iWidth)/2; |
|
1842 iMaximumSize.iWidth=iCurrentSize.iWidth; |
|
1843 } |
|
1844 if (iCurrentSize.iHeight>ScreenSize.iHeight) |
|
1845 { |
|
1846 iMaximumOrigin.iY=0; |
|
1847 iMaximumSize.iHeight=ScreenSize.iHeight; |
|
1848 } |
|
1849 else |
|
1850 { |
|
1851 iMaximumOrigin.iY=(ScreenSize.iHeight-iCurrentSize.iHeight)/2; |
|
1852 iMaximumSize.iHeight=iCurrentSize.iHeight; |
|
1853 } |
|
1854 } |
|
1855 |
|
1856 void CWsWindow::SetFrame() |
|
1857 // |
|
1858 // Draw the frame into the buffer. |
|
1859 // |
|
1860 { |
|
1861 |
|
1862 // WINS text window server uses underlying Win32 graphics calls, so the Unicode |
|
1863 // WINS build has access to Unicode fonts, and needs to use the Unicode box-drawing |
|
1864 // character codes. |
|
1865 // EPOC devices have a codepage 1252 font compiled into the simple display driver, |
|
1866 // so they need to use "Unicode" characters which are just the CP1252 characters |
|
1867 // expanded to 16-bits. |
|
1868 |
|
1869 #if defined(_UNICODE) && defined(__WINS__) |
|
1870 const TText bf[] = {0x2554,0x2557,0x255A,0x255D,0x2550,0x2551,0x2550,0x2550,0x2551,0x2551}; |
|
1871 const TText bf1[] = {0x2554,0x2557,0x255A,0x255D,0x2550,0x2551,0x2591,0x2592,0x2591,0x2592}; |
|
1872 const TText *frame[2] ={ bf, bf1 }; |
|
1873 #else // K.K |
|
1874 const TText *frame[2] = { |
|
1875 _S("\xDA\xBF\xC0\xD9\xC4\xB3\xC4\xC4\xB3\xB3"), |
|
1876 _S("\xC9\xBB\xC8\xBC\xCD\xBA\xB1\xB2\xB1\xB1") |
|
1877 }; |
|
1878 #endif // K.K |
|
1879 const TText *pF=frame[IsTop() ? 1 : 0]; |
|
1880 #if defined(_UNICODE) // K.K |
|
1881 TText *pLT=GetCpFromOffset(iTextBuffer, iCurrentOffset,iCurrentSize); // K.K |
|
1882 #else // K.K |
|
1883 TText *pLT=&iTextBuffer[Offset(iCurrentOffset,iCurrentSize)]; |
|
1884 #endif // K.K |
|
1885 TText *pRT=&pLT[iViewSize.iWidth-1]; |
|
1886 ColorInformation *pLA=&iAttributeBuffer[Offset(iCurrentOffset,iCurrentSize)]; |
|
1887 ColorInformation *pRA=&pLA[iViewSize.iWidth-1]; |
|
1888 TextFill(pLT,iViewSize.iWidth,&pF[4]); |
|
1889 for(TInt x=0;x<iViewSize.iWidth;x++) |
|
1890 { |
|
1891 (pLA+x)->iFg=BorderColor; |
|
1892 (pLA+x)->iBg=WindowBgColor; |
|
1893 } |
|
1894 |
|
1895 TInt i=iViewSize.iWidth-2; |
|
1896 TInt s=iTitle.Length(); |
|
1897 if (s>i) |
|
1898 s=i; |
|
1899 // #if defined(_UNICODE) // K.K |
|
1900 // i=((i-s)>>2); |
|
1901 // #else // K.K |
|
1902 i=((i-s)>>1); |
|
1903 // #endif // K.K |
|
1904 Mem::Copy(pLT+i+1,iTitle.Ptr(),s*sizeof(TText)); |
|
1905 |
|
1906 *pLT=pF[0]; |
|
1907 #if defined(_UNICODE) // K.K |
|
1908 // if (s&1) pLT[i+1+s] = 0x0020; // K.K |
|
1909 FitInWidth(pLT,iCurrentSize.iWidth,iViewSize.iWidth-1,pF[1]); // K.K |
|
1910 #else // K.K |
|
1911 *pRT=pF[1]; |
|
1912 #endif // K.K |
|
1913 |
|
1914 i=iViewSize.iHeight-2; |
|
1915 s=(i*iCurrentOffset.iY)/(iCurrentSize.iHeight-2); |
|
1916 TInt l=((i*i)/(iCurrentSize.iHeight-2))+1; |
|
1917 |
|
1918 while(i-->0) |
|
1919 { |
|
1920 pLT=&pLT[iCurrentSize.iWidth]; |
|
1921 pRT=&pRT[iCurrentSize.iWidth]; |
|
1922 pLA=&pLA[iCurrentSize.iWidth]; |
|
1923 pRA=&pRA[iCurrentSize.iWidth]; |
|
1924 |
|
1925 *pLT=pF[5]; |
|
1926 pLA->iFg=BorderColor; |
|
1927 pLA->iBg=WindowBgColor; |
|
1928 |
|
1929 if (!iHasScrollBars) |
|
1930 { |
|
1931 #if defined(_UNICODE) // K.K |
|
1932 FitInWidth(pLT, iCurrentSize.iWidth, iViewSize.iWidth-1, pF[5]); // K.K |
|
1933 #else // K.K |
|
1934 *pRT=pF[5]; |
|
1935 #endif // K.K |
|
1936 pRA->iFg=BorderColor; |
|
1937 pRA->iBg=WindowBgColor; |
|
1938 } |
|
1939 else |
|
1940 { |
|
1941 #if defined(_UNICODE) // K.K |
|
1942 FitInWidth(pLT, iCurrentSize.iWidth, iViewSize.iWidth-1, pF[8]); // K.K |
|
1943 #else // K.K |
|
1944 *pRT=pF[8]; |
|
1945 #endif // K.K |
|
1946 pRA->iFg=BorderColor; |
|
1947 pRA->iBg=WindowBgColor; |
|
1948 if (s) |
|
1949 --s; |
|
1950 else if (l) |
|
1951 { |
|
1952 #if defined(_UNICODE) // K.K |
|
1953 FitInWidth(pLT, iCurrentSize.iWidth, iViewSize.iWidth-1, pF[9]); // K.K |
|
1954 #else // K.K |
|
1955 *pRT=pF[9]; |
|
1956 #endif // K.K |
|
1957 pRA->iFg=BorderColor; |
|
1958 pRA->iBg=WindowBgColor; |
|
1959 --l; |
|
1960 } |
|
1961 } |
|
1962 } |
|
1963 |
|
1964 pLT=&pLT[iCurrentSize.iWidth]; |
|
1965 pRT=&pRT[iCurrentSize.iWidth]; |
|
1966 pLA=&pLA[iCurrentSize.iWidth]; |
|
1967 pRA=&pRA[iCurrentSize.iWidth]; |
|
1968 |
|
1969 for(i=0;i<iViewSize.iWidth;i++) |
|
1970 { |
|
1971 pLA->iFg=BorderColor; |
|
1972 pLA->iBg=WindowBgColor; |
|
1973 pLA++; |
|
1974 } |
|
1975 |
|
1976 if (!iHasScrollBars) |
|
1977 { |
|
1978 TextFill(pLT,iViewSize.iWidth,&pF[4]); |
|
1979 } |
|
1980 else |
|
1981 { |
|
1982 i=iViewSize.iWidth-2; |
|
1983 s=(i*iCurrentOffset.iX)/(iCurrentSize.iWidth-2); |
|
1984 l=((i*i)/(iCurrentSize.iWidth-2))+1; |
|
1985 #if defined(_UNICODE) // K.K |
|
1986 // s >>= 1; // K.K |
|
1987 // l >>= 1; // K.K |
|
1988 #endif // K.K |
|
1989 TextFill(&pLT[1],i,&pF[6]); |
|
1990 TextFill(&pLT[s+1],l,&pF[7]); |
|
1991 } |
|
1992 |
|
1993 *pLT=pF[2]; |
|
1994 #if defined(_UNICODE) // K.K |
|
1995 FitInWidth(pLT, iCurrentSize.iWidth, iViewSize.iWidth-1, pF[3]); // K.K |
|
1996 #else // K.K |
|
1997 *pRT=pF[3]; |
|
1998 #endif // K.K |
|
1999 } |
|
2000 |
|
2001 void CWsWindow::SetCursorHeight(TInt aPercentage) |
|
2002 // |
|
2003 // Set percentage height of cursor |
|
2004 // |
|
2005 { |
|
2006 |
|
2007 aPercentage=Min(aPercentage,100); |
|
2008 if(aPercentage==0) |
|
2009 iCursorRequired=EFalse; |
|
2010 else |
|
2011 iCursorRequired=ETrue; |
|
2012 |
|
2013 #if defined(_UNICODE) // K.K |
|
2014 iCursor=0x005F; // K.K |
|
2015 #else // K.K |
|
2016 iCursor=Cursors[aPercentage]; |
|
2017 #endif // K.K |
|
2018 |
|
2019 SetCursor(); |
|
2020 } |
|
2021 |
|
2022 void CWsWindow::ClearToEndOfLine() |
|
2023 // |
|
2024 // Clear the window from the current cursor position to the end of the line. |
|
2025 // |
|
2026 { |
|
2027 TInt w=iCurrentSize.iWidth-iCursorPos.iX-1; |
|
2028 RestoreEdges(); |
|
2029 TextFill(&iTextBuffer[Offset(iCursorPos,iCurrentSize)],w,_S(" ")); |
|
2030 Mem::Fill(&iAttributeBuffer[Offset(iCursorPos,iCurrentSize)],w*sizeof(ColorInformation),WindowBgColor); |
|
2031 SaveEdges(); |
|
2032 SetFrame(); |
|
2033 __ASSERT_DEBUG(IsTop(),User::Panic(_L("Not front window"),0)); |
|
2034 if (IsInClippedTextArea(iCursorPos)) |
|
2035 Display(); |
|
2036 } |
|
2037 |
|
2038 void CWsWindow::WriteDone() |
|
2039 // |
|
2040 // Called after a bunch of Write() calls |
|
2041 // |
|
2042 { |
|
2043 |
|
2044 SetCursor(); |
|
2045 } |
|
2046 |
|
2047 void CWsWindow::NewLine() |
|
2048 // |
|
2049 // Do CR/LF on this window |
|
2050 // |
|
2051 { |
|
2052 |
|
2053 if (!iWrapLock) |
|
2054 { |
|
2055 LineFeed(); |
|
2056 CarriageReturn(); |
|
2057 } |
|
2058 } |
|
2059 |
|
2060 void CWsWindow::InformMouse(TPoint aPos) |
|
2061 // |
|
2062 // Called if mouse has been captured |
|
2063 // |
|
2064 { |
|
2065 SWsKey *pS=new SWsKey; |
|
2066 |
|
2067 if (pS) |
|
2068 { |
|
2069 pS->iMousePos=aPos; |
|
2070 pS->iType=EMouseClick; |
|
2071 iKQueue.AddLast(*pS); |
|
2072 } |
|
2073 DrainAllReadRequests(); |
|
2074 } |
|
2075 |
|
2076 void CWsWindow::DoMouseLeftButton() |
|
2077 // |
|
2078 // Called when the left button is pressed |
|
2079 // |
|
2080 { |
|
2081 |
|
2082 if(iAllowResize && MousePos==iViewOrigin+iViewSize-TPoint(1,1)) |
|
2083 ResizeWithMouse=MousePos; |
|
2084 else |
|
2085 { |
|
2086 TInt i=iViewSize.iWidth-2; |
|
2087 TInt s=(i*iCurrentOffset.iX)/(iCurrentSize.iWidth-2); |
|
2088 TInt l=((i*i)/(iCurrentSize.iWidth-2))+1; |
|
2089 if(iHasScrollBars && MousePos.iY==iViewOrigin.iY+iViewSize.iHeight-1 && MousePos.iX>iViewOrigin.iX+s && MousePos.iX<iViewOrigin.iX+s+l+1) |
|
2090 { |
|
2091 ScrollWithMouse=TPoint(MousePos.iX,0); |
|
2092 ScrollSpeed=(iCurrentSize.iWidth+iViewSize.iWidth/2-3)/(iViewSize.iWidth-2); |
|
2093 } |
|
2094 else |
|
2095 { |
|
2096 i=iViewSize.iHeight-2; |
|
2097 s=(i*iCurrentOffset.iY)/(iCurrentSize.iHeight-2); |
|
2098 l=((i*i)/(iCurrentSize.iHeight-2))+1; |
|
2099 if(iHasScrollBars && MousePos.iX==iViewOrigin.iX+iViewSize.iWidth-1 && MousePos.iY>iViewOrigin.iY+s && MousePos.iY<iViewOrigin.iY+s+l+1) |
|
2100 { |
|
2101 ScrollWithMouse=TPoint(0,MousePos.iY); |
|
2102 ScrollSpeed=(iCurrentSize.iHeight+iViewSize.iHeight/2-3)/(iViewSize.iHeight-2); |
|
2103 } |
|
2104 else MoveWithMouse=MousePos; |
|
2105 } |
|
2106 } |
|
2107 if(iPointerEvents) |
|
2108 { |
|
2109 SWsKey *pS=new SWsKey; |
|
2110 if (pS) |
|
2111 { |
|
2112 pS->iMousePos=MousePos; |
|
2113 pS->iType=EMouseClick; |
|
2114 iKQueue.AddLast(*pS); |
|
2115 } |
|
2116 DrainAllReadRequests(); |
|
2117 } |
|
2118 } |
|
2119 |
|
2120 void CWsWindow::QueueWindowKey(TKeyData &aKeystroke) |
|
2121 // |
|
2122 // Place keystroke in window's keyboard queue |
|
2123 // |
|
2124 |
|
2125 { |
|
2126 SWsKey *pS=new SWsKey; |
|
2127 if (pS) |
|
2128 { |
|
2129 pS->iKeyData=aKeystroke; |
|
2130 pS->iType=EKeyPress; |
|
2131 iKQueue.AddLast(*pS); |
|
2132 } |
|
2133 } |
|
2134 |
|
2135 void CWsWindow::QueueRawEvent(TRawEvent& anEvent) |
|
2136 // |
|
2137 // Deliver a raw event to the raw event window |
|
2138 // |
|
2139 { |
|
2140 |
|
2141 if (RawEventWindow) |
|
2142 { |
|
2143 RawEventWindow->QueueWindowRawEvent(anEvent); |
|
2144 DrainAllReadRequests(); |
|
2145 } |
|
2146 } |
|
2147 |
|
2148 void CWsWindow::QueueWindowRawEvent(TRawEvent& anEvent) |
|
2149 // |
|
2150 // Place raw event in window's event queue |
|
2151 // |
|
2152 { |
|
2153 SWsKey *pS=new SWsKey; |
|
2154 if (pS) |
|
2155 { |
|
2156 pS->iKeyData.iModifiers=0; |
|
2157 pS->iKeyData.iApp=0; |
|
2158 pS->iKeyData.iHandle=0; |
|
2159 pS->iKeyData.iIsCaptureKey=EFalse; |
|
2160 pS->iKeyData.iKeyCode=0; |
|
2161 pS->iMousePos=TPoint(0,0); |
|
2162 pS->iType=anEvent.Type(); |
|
2163 switch(anEvent.Type()) |
|
2164 { |
|
2165 case TRawEvent::EPointerMove: |
|
2166 case TRawEvent::EButton1Down: |
|
2167 case TRawEvent::EButton1Up: |
|
2168 case TRawEvent::EButton2Down: |
|
2169 case TRawEvent::EButton2Up: |
|
2170 case TRawEvent::EButton3Down: |
|
2171 case TRawEvent::EButton3Up: |
|
2172 pS->iMousePos=anEvent.Pos(); |
|
2173 break; |
|
2174 case TRawEvent::EKeyUp: |
|
2175 case TRawEvent::EKeyDown: |
|
2176 pS->iKeyData.iKeyCode=anEvent.ScanCode(); |
|
2177 break; |
|
2178 default: |
|
2179 break; |
|
2180 } |
|
2181 iKQueue.AddLast(*pS); |
|
2182 } |
|
2183 } |
|
2184 |
|
2185 void CWsWindow::SetCursorPosAbs(const TPoint &aPosition) |
|
2186 // |
|
2187 // Place cursor at position specified |
|
2188 // |
|
2189 { |
|
2190 |
|
2191 iCursorPos=aPosition; |
|
2192 iCursorPos+=TPoint(1,1); |
|
2193 if (iCursorPos.iX<1) |
|
2194 iCursorPos.iX=1; |
|
2195 if (iCursorPos.iX>=iCurrentSize.iWidth-1) |
|
2196 iCursorPos.iX=iCurrentSize.iWidth-2; |
|
2197 if (iCursorPos.iY<1) |
|
2198 iCursorPos.iY=1; |
|
2199 if (iCursorPos.iY>=iCurrentSize.iHeight-1) |
|
2200 iCursorPos.iY=iCurrentSize.iHeight-2; |
|
2201 SetCursor(); |
|
2202 } |
|
2203 |
|
2204 void CWsWindow::SetCursorPosRel(const TPoint &aPosition) |
|
2205 // |
|
2206 // Place cursor at position relative to current position |
|
2207 // |
|
2208 { |
|
2209 |
|
2210 TPoint p=iCursorPos+aPosition-TPoint(1,1); |
|
2211 SetCursorPosAbs(p); |
|
2212 } |
|
2213 |
|
2214 TPoint CWsWindow::CursorPosition() |
|
2215 // |
|
2216 // Return current cursor position |
|
2217 // |
|
2218 { |
|
2219 |
|
2220 return(iCursorPos-TPoint(1,1)); |
|
2221 } |
|
2222 |
|
2223 void CWsWindow::ControlScrollBars(TBool anIndicator) |
|
2224 // |
|
2225 // Turn scroll bars on or off according to the value of anIndicator |
|
2226 // |
|
2227 { |
|
2228 |
|
2229 iHasScrollBars=anIndicator; |
|
2230 if (iTextBuffer) |
|
2231 { |
|
2232 SetFrame(); |
|
2233 Refresh(); |
|
2234 if (IsTop()) |
|
2235 ScrollWithMouse=TPoint(-1,-1); |
|
2236 } |
|
2237 } |
|
2238 |
|
2239 void CWsWindow::ControlWrapLock(TBool anIndicator) |
|
2240 // |
|
2241 // Turn wrap lock on or off according to the value of anIndicator |
|
2242 // |
|
2243 { |
|
2244 |
|
2245 iWrapLock=anIndicator; |
|
2246 } |
|
2247 |
|
2248 void CWsWindow::ControlPointerEvents(TBool anIndicator) |
|
2249 // |
|
2250 // Turn reporting of pointer events on or off according to the value of anIndicator |
|
2251 // |
|
2252 { |
|
2253 |
|
2254 ResizeWithMouse=TPoint(-1,-1); |
|
2255 ScrollWithMouse=TPoint(-1,-1); |
|
2256 iPointerEvents=anIndicator; |
|
2257 } |
|
2258 |
|
2259 void CWsWindow::ControlScrollLock(TBool anIndicator) |
|
2260 // |
|
2261 // Turn scroll lock on or off according to the value of anIndicator |
|
2262 // |
|
2263 { |
|
2264 |
|
2265 iScrollLock=anIndicator; |
|
2266 } |
|
2267 |
|
2268 void CWsWindow::ControlAllowResize(TBool anIndicator) |
|
2269 // |
|
2270 // Turn iAllowResize on or off |
|
2271 // |
|
2272 { |
|
2273 |
|
2274 iAllowResize=anIndicator; |
|
2275 ResizeWithMouse=TPoint(-1,-1); |
|
2276 } |
|
2277 |
|
2278 void CWsWindow::ControlOnTop(TBool anIndicator) |
|
2279 // |
|
2280 // Turn iOnTop on or off |
|
2281 // |
|
2282 { |
|
2283 |
|
2284 iOnTop=anIndicator; |
|
2285 if(iOnTop) |
|
2286 iIsVisible=ETrue; |
|
2287 if(iTextBuffer) |
|
2288 MakeTopWindow(); |
|
2289 } |
|
2290 |
|
2291 void CWsWindow::ControlVisibility(TBool anIndicator) |
|
2292 // |
|
2293 // Turn visibility on or off according to the value of anIndicator |
|
2294 // |
|
2295 { |
|
2296 if(!iOnTop) |
|
2297 { |
|
2298 iIsVisible=anIndicator; |
|
2299 if (!iIsVisible && IsTop()) |
|
2300 RotateWindowsBackwards(); // make sure we have a visible window on top |
|
2301 if (!iIsVisible&&iTextBuffer) |
|
2302 Refresh(); |
|
2303 if (iTextBuffer&&iIsVisible) |
|
2304 MakeTopWindow(); |
|
2305 } |
|
2306 } |
|
2307 |
|
2308 void CWsWindow::ControlCursorRequired(TBool anIndicator) |
|
2309 // |
|
2310 // Turn the text cursor on or off according to the value of anIndicator |
|
2311 // |
|
2312 { |
|
2313 |
|
2314 iCursorRequired=anIndicator; |
|
2315 SetCursor(); |
|
2316 } |
|
2317 |
|
2318 void CWsWindow::ControlMaximised(TBool anIndicator) |
|
2319 // |
|
2320 // Maximise or minimise the window according to the value of anIndicator |
|
2321 // |
|
2322 { |
|
2323 ResizeWithMouse=TPoint(-1,-1); |
|
2324 ScrollWithMouse=TPoint(-1,-1); |
|
2325 if (anIndicator) |
|
2326 { |
|
2327 if (iViewSize==iMaximumSize && iViewOrigin==iMaximumOrigin) |
|
2328 return; |
|
2329 RestoreEdges(); |
|
2330 iMinimumSize=iViewSize; |
|
2331 iMinimumOrigin=iViewOrigin; |
|
2332 iViewSize=iMaximumSize; |
|
2333 iViewOrigin=iMaximumOrigin; |
|
2334 TSize s=iCurrentSize-iViewSize; |
|
2335 if (iCurrentOffset.iX>s.iWidth) |
|
2336 iCurrentOffset.iX=s.iWidth; |
|
2337 if (iCurrentOffset.iY>s.iHeight) |
|
2338 iCurrentOffset.iY=s.iHeight; |
|
2339 SaveEdges(); |
|
2340 SetFrame(); |
|
2341 SetClip(); |
|
2342 Refresh(); |
|
2343 } |
|
2344 else |
|
2345 { |
|
2346 if (iViewSize==iMaximumSize && iViewOrigin==iMaximumOrigin) |
|
2347 { |
|
2348 RestoreEdges(); |
|
2349 iViewSize=iMinimumSize; |
|
2350 iViewOrigin=iMinimumOrigin; |
|
2351 SaveEdges(); |
|
2352 SetFrame(); |
|
2353 SetClip(); |
|
2354 Refresh(); |
|
2355 } |
|
2356 } |
|
2357 } |
|
2358 |
|
2359 void CWsWindow::ControlNewLineMode(TBool anIndicator) |
|
2360 // |
|
2361 // Set the newline mode |
|
2362 // |
|
2363 { |
|
2364 |
|
2365 iNewLineMode=anIndicator; |
|
2366 } |
|
2367 |
|
2368 void CWsWindow::ControlRawEventMode(TBool anIndicator) |
|
2369 // |
|
2370 // Set the raw event mode |
|
2371 // |
|
2372 { |
|
2373 |
|
2374 if (anIndicator) |
|
2375 { |
|
2376 if (!RawEventWindow) |
|
2377 RawEventWindow=this; |
|
2378 } |
|
2379 else |
|
2380 { |
|
2381 if (RawEventWindow==this) |
|
2382 RawEventWindow=NULL; |
|
2383 } |
|
2384 } |
|
2385 |
|
2386 TBool CWsWindow::RawEventMode() |
|
2387 // |
|
2388 // Report whether in raw event mode |
|
2389 // |
|
2390 { |
|
2391 |
|
2392 return(RawEventWindow!=NULL); |
|
2393 } |
|
2394 |
|
2395 TBool CWsWindow::EnqueReadRequest(const RMessage2 &aMessage) |
|
2396 // |
|
2397 // Accept read request on this window |
|
2398 // |
|
2399 { |
|
2400 |
|
2401 if (!iReadIsValid) |
|
2402 { |
|
2403 iReadRequest=aMessage; |
|
2404 iReadIsValid=ETrue; |
|
2405 DrainAllReadRequests(); |
|
2406 SetCursor(); |
|
2407 return(ETrue); |
|
2408 } |
|
2409 return(EFalse); |
|
2410 } |
|
2411 |
|
2412 void CWsWindow::DequeReadRequest() |
|
2413 { |
|
2414 if (iReadIsValid) |
|
2415 { |
|
2416 iReadIsValid=EFalse; |
|
2417 iReadRequest.Complete(KErrCancel); |
|
2418 } |
|
2419 } |
|
2420 |
|
2421 void CWsWindow::DrainReadRequest() |
|
2422 // |
|
2423 // Drain satisfied read requests |
|
2424 // |
|
2425 { |
|
2426 |
|
2427 if (iReadIsValid && !(iKQueue.IsEmpty())) |
|
2428 { |
|
2429 RMessage2& m=iReadRequest; |
|
2430 SConsoleKey k; |
|
2431 SWsKey *pS=iKQueue.First(); |
|
2432 k.iCode=(TKeyCode)pS->iKeyData.iKeyCode; |
|
2433 |
|
2434 k.iModifiers=KeyTranslator->GetModifierState(); |
|
2435 |
|
2436 k.iType=pS->iType; |
|
2437 k.iMousePos=pS->iMousePos; |
|
2438 |
|
2439 TPckgC<SConsoleKey> keystroke(k); |
|
2440 m.WriteL(0,keystroke); |
|
2441 iKQueue.Remove(*pS); |
|
2442 delete pS; |
|
2443 iReadIsValid=EFalse; // Do this before message completion to prevent message flow control problems |
|
2444 m.Complete(KErrNone); |
|
2445 } |
|
2446 } |
|
2447 |
|
2448 void CWsWindow::CreateL(const TSize &aSize) |
|
2449 // |
|
2450 // Default the new control block and add to queue. |
|
2451 // |
|
2452 { |
|
2453 iNumber=NewNumberL(); |
|
2454 iCurrentOffset=TPoint(0,0); |
|
2455 iCurrentSize=aSize+TSize(2,2); // Allow for window border |
|
2456 if (iCurrentSize.iWidth==KConsFullScreen+2) |
|
2457 iCurrentSize.iWidth=ScreenSize.iWidth; |
|
2458 if (iCurrentSize.iHeight==KConsFullScreen+2) |
|
2459 iCurrentSize.iHeight=ScreenSize.iHeight; |
|
2460 if (iCurrentSize.iWidth>ScreenSize.iWidth) |
|
2461 User::Leave(EWindowTooWide); |
|
2462 if (iCurrentSize.iWidth<3) |
|
2463 User::Leave(EWindowTooThin); |
|
2464 if (iCurrentSize.iHeight>ScreenSize.iHeight) |
|
2465 User::Leave(EWindowTooHigh); |
|
2466 if (iCurrentSize.iHeight<3) |
|
2467 User::Leave(EWindowTooShort); |
|
2468 iTextBuffer=(TText *)User::Alloc(sizeof(TText)*iCurrentSize.iWidth*iCurrentSize.iHeight); |
|
2469 if (!iTextBuffer) |
|
2470 User::Leave(EWindowOutOfMemory); |
|
2471 iAttributeBuffer=(ColorInformation *)User::Alloc(iCurrentSize.iWidth*iCurrentSize.iHeight*sizeof(ColorInformation)); |
|
2472 if (!iAttributeBuffer) |
|
2473 User::Leave(EWindowOutOfMemory); |
|
2474 iFgColor=IndexOf[ETextAttributeNormal]; |
|
2475 iBgColor=IndexOf[ETextAttributeNormal+1]; |
|
2476 WQueue.AddLast(*this); |
|
2477 SetView(); |
|
2478 SetFull(); |
|
2479 SetClip(); |
|
2480 Clear(); |
|
2481 if (iIsVisible) |
|
2482 MakeTopWindow(); |
|
2483 } |
|
2484 |