|
1 // Copyright (c) 1994-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 handling |
|
15 // |
|
16 // |
|
17 |
|
18 #include "CLIENT.H" |
|
19 |
|
20 #include "ANIM.H" |
|
21 #include "Direct.H" |
|
22 #include "EVENT.H" |
|
23 #include "KEYCLICK.H" |
|
24 #include "server.h" |
|
25 #include "gc.h" |
|
26 #include "rootwin.h" |
|
27 #include "windowgroup.h" |
|
28 #include "wstop.h" |
|
29 #include "panics.h" |
|
30 #include "../CLIENT/w32comm.h" |
|
31 #include "password.h" |
|
32 #include "pointer.h" |
|
33 #include <u32hal.h> // EHalGroupEmulator |
|
34 #include "WsMemMgr.h" |
|
35 #include <e32hashtab.h> // for RHashMap |
|
36 #include "registeredsurfacemap.h" |
|
37 #include <graphics/wselement.h> |
|
38 |
|
39 #include "windowelementset.h" |
|
40 #include "drawresource.h" |
|
41 |
|
42 extern CDebugLogBase* wsDebugLog; |
|
43 _LIT(KWSERVSessionPanicCategory,"WSERV"); |
|
44 |
|
45 GLREF_D TPtr nullDescriptor; |
|
46 |
|
47 TWsCmdHeaderBase CWsClient::iCurrentCommand; |
|
48 TBuf8<EClientBufferMaxSize> CWsClient::iCmdBuf; |
|
49 TInt CWsClient::iReply; |
|
50 TInt CWsClient::iReplyOffset; |
|
51 CWsClient* CWsClient::iCurrentClient; |
|
52 CWsObject* CWsClient::iDestObj; |
|
53 const TUint8* CWsClient::iNextCmd; |
|
54 CIdle* CWsClient::iMoreCommands=NULL; |
|
55 |
|
56 TUint CWsClient::iConnectionId = CDebugLogBase::EDummyConnectionId+1; |
|
57 CArrayFixFlat<CWsClient::TWsCursorArrayItem>* CWsClient::iSystemPointerCursors = NULL; |
|
58 TInt CWsClient::iDefaultSystemPointerCursorIndex = 0; //Negative when there isn't one |
|
59 CWsPointerCursor* CWsClient::iDefaultSystemPointerCursor; |
|
60 CWsClient* CWsClient::iSystemPointerCursorListOwner = NULL; |
|
61 CArrayFixFlat<CWsClient::TWsCursorArrayItem>* CWsClient::iTextCursorArray = NULL; |
|
62 |
|
63 TKeyArrayFix CWsClient::iCursorKey(_FOFF(CWsClient::TWsCursorArrayItem,iIndex), ECmpTInt); |
|
64 |
|
65 /** |
|
66 Used for enforcing the redraw calling convention in emulator builds. |
|
67 When enabled this will panic any client calling a CWindowGc draw operation outside a |
|
68 RWindow::BeginRedraw() / RWindow::EndRedraw() pair (known as non-redraw drawing). |
|
69 |
|
70 Enable by adding "debug_wserv_exe_EnforceRedrawCallingConvention X" to epoc.ini |
|
71 where X is either 0 (zero) for "off" or 1 (one) for "on". |
|
72 |
|
73 Then enable globally in WServ AutoFlush by defining __AUTO_FLUSH in ../client/client.h |
|
74 or locally by calling RWsSession::SetAutoFlush(ETrue) for a specific client programatically, |
|
75 or locally pressing Ctrl-Alt-Shift-F in the emulator. |
|
76 */ |
|
77 TBool CWsClient::iDebug_EnforceRedrawCallingConvention = EFalse; |
|
78 |
|
79 // Security policy stings |
|
80 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_WriteDeviceData,ECapabilityWriteDeviceData); |
|
81 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_SwEvent,ECapabilitySwEvent); |
|
82 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_PowerMgmt,ECapabilityPowerMgmt); |
|
83 |
|
84 // |
|
85 // class CWsClient |
|
86 // |
|
87 |
|
88 CWsClient::CWsClient(RThread aClient) : iClient(aClient), iGraphicMessageQueue(this), iInternalFlags(ERemoveKeyCode|EFinishedProcessingCommands) |
|
89 { |
|
90 iScreen = CWsTop::Screen(); |
|
91 } |
|
92 |
|
93 CWsClient::~CWsClient() |
|
94 { |
|
95 CWsTop::WindowServer()->RemoveAllGraphicDrawers(*this); // deindexes all graphic drawers owned by this client |
|
96 |
|
97 delete iTempCustomTextCursor.iCursor; |
|
98 FreeSystemPointerCursorList(); |
|
99 CWsTop::ClientDestroyed(this); |
|
100 if (wsDebugLog) |
|
101 { |
|
102 _LIT(ClientDestuct,"Client %d destructing"); |
|
103 wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,ClientDestuct, iConnectionHandle); |
|
104 } |
|
105 |
|
106 iInternalFlags |= EClientIsClosing; |
|
107 delete iObjectIndex; |
|
108 delete iEventQueue; |
|
109 delete iRedrawQueue; |
|
110 delete iPriorityKeyEvent; |
|
111 CWsTop::ClearSurfaceMap(this); |
|
112 |
|
113 CWsTop::SessionExited(this); |
|
114 iClient.Close(); |
|
115 } |
|
116 |
|
117 void CWsClient::CompleteInitializationL() |
|
118 { |
|
119 iObjectIndex = new(ELeave) CWsObjectIx(); |
|
120 iObjectIndex->ConstructL(); |
|
121 |
|
122 iEventQueue = new(ELeave) CEventQueue(this); |
|
123 iEventQueue->ConstructL(); |
|
124 |
|
125 iRedrawQueue = new(ELeave) CRedrawQueue(this); |
|
126 iRedrawQueue->ConstructL(); |
|
127 |
|
128 iPriorityKeyEvent = new(ELeave) CPriorityKey(this); |
|
129 |
|
130 CWsCliObj::NewL(this); |
|
131 |
|
132 iComputeMode = RWsSession::EPriorityControlComputeOff; |
|
133 |
|
134 CWsTop::NewSession(this); |
|
135 |
|
136 #ifdef __WINS__ |
|
137 TBool halValue = EFalse; |
|
138 if (UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, |
|
139 (TAny*)"debug_wserv_exe_EnforceRedrawCallingConvention", &halValue) == KErrNone) |
|
140 { |
|
141 iDebug_EnforceRedrawCallingConvention = halValue; |
|
142 } |
|
143 #endif |
|
144 |
|
145 iInternalFlags |= EIsInitialised; |
|
146 } |
|
147 |
|
148 TBool CWsClient::DebugEnforceRedrawCallingConvention() |
|
149 { |
|
150 return iDebug_EnforceRedrawCallingConvention; |
|
151 } |
|
152 |
|
153 void CWsClient::StartInitializationL(TUint aConnectionHandle) |
|
154 { |
|
155 if (wsDebugLog) |
|
156 wsDebugLog->NewClient(aConnectionHandle); |
|
157 |
|
158 if (iObjectIndex) |
|
159 PPanic(EWservPanicReInitialise); |
|
160 else |
|
161 { |
|
162 iConnectionHandle = aConnectionHandle; |
|
163 CompleteInitializationL(); |
|
164 } |
|
165 } |
|
166 |
|
167 // |
|
168 // Convert a handle to object checking it is of the correct type. |
|
169 // |
|
170 void CWsClient::HandleToWindow(TInt aHandle,CWsWindowBase** pWin) |
|
171 { |
|
172 if ((*pWin=(CWsWindowBase* )HandleToObjUntyped(aHandle))==NULL || |
|
173 ((*pWin)->Type()!=WS_HANDLE_WINDOW && (*pWin)->Type()!=WS_HANDLE_GROUP_WINDOW)) |
|
174 PPanic(EWservPanicWindow); |
|
175 } |
|
176 |
|
177 // |
|
178 // Convert a handle to object checking it is of the correct type. |
|
179 // |
|
180 void CWsClient::HandleToClientWindow(TInt aHandle,CWsClientWindow** pWin) |
|
181 { |
|
182 if ((*pWin=(CWsClientWindow*)HandleToObj(aHandle, WS_HANDLE_WINDOW))==NULL) |
|
183 PPanic(EWservPanicWindow); |
|
184 } |
|
185 |
|
186 void CWsClient::CreateNewPointerCursorL(const TWsClCmdCreatePointerCursor &aCmd) |
|
187 { |
|
188 CWsPointerCursor* pc=new(ELeave) CWsPointerCursor(this); |
|
189 CleanupStack::PushL(pc); |
|
190 pc->ConstructL(aCmd); |
|
191 CleanupStack::Pop(); |
|
192 } |
|
193 |
|
194 // Create a new custom text cursor |
|
195 void CWsClient::StartSetCustomTextCursorL(const TWsClCmdCustomTextCursorData& aCmd) |
|
196 { |
|
197 if (!iTextCursorArray) |
|
198 { |
|
199 const TInt textCursorArrayGranularity = 4; |
|
200 iTextCursorArray = new(ELeave) CArrayFixFlat<TWsCursorArrayItem>(textCursorArrayGranularity); |
|
201 } |
|
202 |
|
203 TInt arrayIndex = KErrNotFound; |
|
204 if (FindCursorArrayItem(iTextCursorArray, aCmd.identifier, arrayIndex)) |
|
205 User::Leave(KErrAlreadyExists); |
|
206 |
|
207 delete iTempCustomTextCursor.iCursor; |
|
208 iTempCustomTextCursor.iCursor = NULL; |
|
209 iTempCustomTextCursor.iCursor = new(ELeave) CWsCustomTextCursor(this, aCmd.alignment); |
|
210 |
|
211 static_cast<CWsCustomTextCursor*>(iTempCustomTextCursor.iCursor)->ConstructL(aCmd.flags); |
|
212 iTempCustomTextCursor.iIndex = aCmd.identifier; |
|
213 } |
|
214 |
|
215 // Add new custom text cursor to global list |
|
216 void CWsClient::CompleteSetCustomTextCursorL(TInt aError) |
|
217 { |
|
218 if (aError) |
|
219 { |
|
220 delete iTempCustomTextCursor.iCursor; |
|
221 iTempCustomTextCursor.iCursor = NULL; |
|
222 User::Leave(aError); |
|
223 } |
|
224 |
|
225 TWsCursorArrayItem entry = iTempCustomTextCursor; |
|
226 iTempCustomTextCursor.iCursor = NULL; |
|
227 CleanupStack::PushL(entry.iCursor); |
|
228 |
|
229 TInt arrayIndex; |
|
230 if (FindCursorArrayItem(iTextCursorArray, entry.iIndex, arrayIndex)) |
|
231 User::Leave(KErrAlreadyExists); |
|
232 else |
|
233 iTextCursorArray->InsertIsqL(entry, iCursorKey); |
|
234 |
|
235 CleanupStack::Pop(entry.iCursor); |
|
236 } |
|
237 |
|
238 CWsCustomTextCursor* CWsClient::FindCustomTextCursor(TInt aIdentifier) |
|
239 { |
|
240 TInt arrayIndex; |
|
241 if (!FindCursorArrayItem(iTextCursorArray, aIdentifier, arrayIndex)) |
|
242 return NULL; |
|
243 |
|
244 return TextCursor(arrayIndex); |
|
245 } |
|
246 |
|
247 void CWsClient::CreateNewSpriteL(const TWsClCmdCreateSprite &aCmd) |
|
248 { |
|
249 CWsSprite* sprite = new(ELeave) CWsSprite(this); |
|
250 CleanupStack::PushL(sprite); |
|
251 sprite->ConstructL(aCmd); |
|
252 CleanupStack::Pop(); |
|
253 } |
|
254 |
|
255 void CWsClient::CreateNewBitmapL(const TWsClCmdCreateBitmap &aCmd) |
|
256 { |
|
257 DWsBitmap* bitmap = new(ELeave) DWsBitmap(this); |
|
258 CleanupStack::PushL(bitmap); |
|
259 bitmap->ConstructL(aCmd); |
|
260 CleanupStack::Pop(); |
|
261 } |
|
262 |
|
263 /** Creates a new window. |
|
264 |
|
265 If the parent is a window group then a new CWsTopClientWindow instance is created. If the parent is |
|
266 a window then a new CWsClientWindow instance is created. |
|
267 |
|
268 @param aCmd The command received from the client |
|
269 @internalComponent |
|
270 @released |
|
271 */ |
|
272 void CWsClient::CreateNewWindowL(const TWsClCmdCreateWindow &aCmd) |
|
273 { |
|
274 CWsWindowBase* parent; |
|
275 HandleToWindow(aCmd.parent,&parent); |
|
276 CWsClientWindow* win = NULL; |
|
277 TBool deviceIsInvalid = EFalse; |
|
278 CScreen* screen = parent->Screen(); |
|
279 if (parent->WinType()==EWinTypeGroup) |
|
280 { |
|
281 __ASSERT_DEBUG(!((CWsWindowGroup*)parent)->ScreenDeviceDeleted(),PPanic(EWservPanicGroupWinScreenDeviceDeleted)); |
|
282 win=new(ELeave) CWsTopClientWindow(this, screen); |
|
283 deviceIsInvalid=!((CWsWindowGroup*)parent)->ScreenDeviceValid(); |
|
284 } |
|
285 else |
|
286 win=new(ELeave) CWsClientWindow(this, screen); |
|
287 |
|
288 CleanupStack::PushL(win); |
|
289 win->ConstructL(aCmd,parent,deviceIsInvalid); |
|
290 CleanupStack::Pop(win); |
|
291 } |
|
292 |
|
293 void CWsClient::CreateNewWindowGroupL(const TWsClCmdCreateWindowGroup &aCmd) |
|
294 { |
|
295 CWsWindowGroup::NewL(this, NULL, aCmd); //screen is initialised inside the constructL |
|
296 } |
|
297 |
|
298 void CWsClient::CreateNewAnimDllL(const TWsClCmdUnion &aParams) |
|
299 { |
|
300 CWsAnimDll* animDll = new(ELeave) CWsAnimDll(this); |
|
301 CleanupStack::PushL(animDll); |
|
302 animDll->LoadL(BufferTPtr((TText*)(aParams.LoadAnimDll+1),aParams.LoadAnimDll->length)); |
|
303 CleanupStack::Pop(); |
|
304 } |
|
305 |
|
306 void CWsClient::CreateNewScreenDeviceL(TInt aDefaultScreenNumber, TUint aClientScreenDevicePointer) |
|
307 { |
|
308 DWsScreenDevice* screenDevice = new(ELeave) DWsScreenDevice(this, aDefaultScreenNumber,aClientScreenDevicePointer); |
|
309 CleanupStack::PushL(screenDevice); |
|
310 screenDevice->ConstructL(); |
|
311 CleanupStack::Pop(screenDevice); |
|
312 if (iPrimaryScreenDevice==NULL) |
|
313 { |
|
314 iPrimaryScreenDevice=screenDevice; |
|
315 // When client create screen device, change default screen to the one specified. |
|
316 // Client should do this immediately after establishing session |
|
317 iScreen = iPrimaryScreenDevice->Screen(); |
|
318 InitialiseScreenDevices(); |
|
319 } |
|
320 } |
|
321 |
|
322 void CWsClient::InitialiseScreenDevices() |
|
323 { |
|
324 const TWsObject* ptr = iObjectIndex->FirstObject(); |
|
325 const TWsObject* end = ptr+iObjectIndex->Length(); |
|
326 WS_ASSERT_DEBUG(ptr->iObject==NULL, EWsPanicObjectIndexError); |
|
327 while(++ptr<end) |
|
328 { |
|
329 if (ptr->iObject && ptr->iObject->Type()==WS_HANDLE_GROUP_WINDOW) |
|
330 { |
|
331 CWsWindowGroup* gw = static_cast<CWsWindowGroup*>(ptr->iObject); |
|
332 if(!gw->Device()) |
|
333 gw->SetScreenDevice(iPrimaryScreenDevice); |
|
334 } |
|
335 } |
|
336 } |
|
337 |
|
338 void CWsClient::CreateNewClickHandlerL(const TUid& aUid) |
|
339 { |
|
340 CClick* click = new(ELeave) CClick(this); |
|
341 CleanupStack::PushL(click); |
|
342 click->ConstructL(aUid); |
|
343 CleanupStack::Pop(click); |
|
344 } |
|
345 |
|
346 void CWsClient::RequestComplete(TRequestStatus* &aStatus, TInt aErr) |
|
347 { |
|
348 Client().RequestComplete(aStatus,aErr); |
|
349 } |
|
350 |
|
351 void CWsClient::PanicCurrentClient(TClientPanic aPanic) |
|
352 { |
|
353 iCurrentClient->PPanic(aPanic); |
|
354 } |
|
355 |
|
356 void CWsClient::PPanic(TClientPanic aPanic) const |
|
357 //This function is allowed to leave with out the 'L' convention for special reasons |
|
358 { |
|
359 SessionPanic(aPanic); |
|
360 User::Leave(EPanicLeave); |
|
361 } |
|
362 |
|
363 void CWsClient::SessionPanic(TClientPanic aReason) const |
|
364 { |
|
365 if (wsDebugLog) |
|
366 wsDebugLog->Panic(iConnectionHandle, aReason); |
|
367 |
|
368 if (!(iInternalFlags&EPanicClientAsSoonAsPossible)) // keep the first error code |
|
369 { |
|
370 iInternalFlags |= EPanicClientAsSoonAsPossible; |
|
371 iPanicReason = aReason; |
|
372 } |
|
373 } |
|
374 |
|
375 void CWsClient::SessionTerminate() |
|
376 { |
|
377 if (wsDebugLog) |
|
378 wsDebugLog->Panic(iConnectionHandle, 0); |
|
379 |
|
380 const RThread thread=Client(); |
|
381 RProcess process; |
|
382 if (thread.Process(process)==KErrNone) |
|
383 { |
|
384 process.Terminate(0); |
|
385 process.Close(); |
|
386 } |
|
387 } |
|
388 |
|
389 /** |
|
390 Returns the remaining space in the descriptor |
|
391 */ |
|
392 TInt CWsClient::ReplyBufSpace() |
|
393 { |
|
394 const TInt retVal = iCurrentClient->ClientMessage().GetDesLength(KReplyBufferMessageSlot); |
|
395 |
|
396 if (iReplyOffset>=0 && retVal>=iReplyOffset) |
|
397 return retVal-iReplyOffset; |
|
398 else |
|
399 return (retVal<0 ? retVal : KErrBadDescriptor); |
|
400 } |
|
401 |
|
402 void CWsClient::ReplyBuf(const TDesC16 &aDes) // static |
|
403 { |
|
404 WS_ASSERT_DEBUG(!iCurrentClient->ClientMessage().IsNull(), EWsPanicInvalidMessageHandle); |
|
405 |
|
406 if(iCurrentClient->ClientMessage().Write(KReplyBufferMessageSlot,aDes,iReplyOffset) != KErrNone) |
|
407 PanicCurrentClient(EWservPanicDescriptor); |
|
408 |
|
409 iReplyOffset += aDes.Length(); |
|
410 if (wsDebugLog) |
|
411 wsDebugLog->ReplyBuf(aDes); |
|
412 } |
|
413 |
|
414 void CWsClient::ReplyBuf(const TDesC8 &aDes) // static |
|
415 { |
|
416 WS_ASSERT_DEBUG(!iCurrentClient->ClientMessage().IsNull(), EWsPanicInvalidMessageHandle); |
|
417 |
|
418 if(iCurrentClient->ClientMessage().Write(KReplyBufferMessageSlot, aDes, iReplyOffset) != KErrNone) |
|
419 PanicCurrentClient(EWservPanicDescriptor); |
|
420 |
|
421 iReplyOffset += aDes.Length(); |
|
422 if (wsDebugLog) |
|
423 wsDebugLog->ReplyBuf(aDes); |
|
424 } |
|
425 |
|
426 void CWsClient::ReplyBuf(const TAny* aSource, TInt aLength) // static |
|
427 // |
|
428 // Send a buffer to the client process. |
|
429 // |
|
430 { |
|
431 TPtrC8 src(reinterpret_cast<const TUint8*>(aSource),aLength); |
|
432 ReplyBuf(src); |
|
433 } |
|
434 |
|
435 void CWsClient::ReplySize(const TSize &aSize) // static |
|
436 { |
|
437 ReplyBuf(&aSize, sizeof(aSize)); |
|
438 } |
|
439 |
|
440 void CWsClient::ReplyPoint(const TPoint &aPoint) // static |
|
441 { |
|
442 ReplyBuf(&aPoint, sizeof(aPoint)); |
|
443 } |
|
444 |
|
445 void CWsClient::ReplyRect(const TRect &aRect) // static |
|
446 { |
|
447 ReplyBuf(&aRect, sizeof(aRect)); |
|
448 } |
|
449 |
|
450 void CWsClient::SetReply(TInt reply) |
|
451 { |
|
452 iReply = reply; |
|
453 if (wsDebugLog) |
|
454 wsDebugLog->Reply(reply); |
|
455 } |
|
456 |
|
457 const TUint8* CWsClient::EndOfCommandBuffer() |
|
458 { |
|
459 return(iCmdBuf.Ptr()+iCmdBuf.Size()); |
|
460 } |
|
461 |
|
462 const TPtrC CWsClient::BufferTPtr(TText *aStart,TInt aLen) |
|
463 { |
|
464 TPtrC ptr; |
|
465 if (!BufferTPtrGc(aStart,aLen,ptr)) |
|
466 PanicCurrentClient(EWservPanicBufferPtr); |
|
467 return(ptr); |
|
468 } |
|
469 |
|
470 TBool CWsClient::BufferTPtrGc(TText* aStart,TInt aLen, TPtrC& aPtr) |
|
471 { |
|
472 if (iCurrentCommand.iOpcode>0) |
|
473 { |
|
474 if ((REINTERPRET_CAST(TUint8*,aStart)<iCmdBuf.Ptr() |
|
475 || REINTERPRET_CAST(TUint8*,aStart+aLen)>(iCmdBuf.Ptr()+iCmdBuf.Size()))) |
|
476 return(EFalse); |
|
477 } |
|
478 else |
|
479 { |
|
480 if (aLen>=iCurrentCommand.iCmdLength) |
|
481 return(EFalse); |
|
482 } |
|
483 aPtr.Set(aStart,aLen); |
|
484 return(ETrue); |
|
485 } |
|
486 |
|
487 const TPtrC8 CWsClient::BufferTPtr8(TUint8* aStart,TInt aLen) |
|
488 { |
|
489 if (iCurrentCommand.iOpcode>0 && (REINTERPRET_CAST(TUint8*,aStart)<iCmdBuf.Ptr() |
|
490 || REINTERPRET_CAST(TUint8*,aStart+aLen)>(iCmdBuf.Ptr()+iCmdBuf.Size()))) |
|
491 PanicCurrentClient(EWservPanicBufferPtr); |
|
492 |
|
493 return(TPtrC8(aStart,aLen)); |
|
494 } |
|
495 |
|
496 /** |
|
497 Process a command buffer |
|
498 |
|
499 @internalComponent |
|
500 @released |
|
501 */ |
|
502 void CWsClient::DispatchCommandsInBufL() // (step #4) |
|
503 { |
|
504 if (wsDebugLog) |
|
505 { |
|
506 wsDebugLog->CommandBuf(iConnectionHandle); |
|
507 RThread client = Client(); |
|
508 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything, client.FullName()); |
|
509 } |
|
510 const TUint8* endCmd=iCmdBuf.Ptr()+iCmdBuf.Length(); |
|
511 do |
|
512 { |
|
513 const TWsCmdHeader* pCmd= |
|
514 reinterpret_cast<const TWsCmdHeader*>(iNextCmd); |
|
515 TUint opcode = pCmd->iBase.iOpcode; |
|
516 TInt headerLen = sizeof(pCmd->iBase); |
|
517 iCurrentCommand = pCmd->iBase; |
|
518 |
|
519 // For performance reasons the handle is only included |
|
520 // if it is different from the previous command. The EWsOpcodeHandle |
|
521 // flag indicates whether a new handle has been included in the |
|
522 // current command. If not we use the same handle as the previous |
|
523 // command. |
|
524 if (opcode&EWsOpcodeHandle) |
|
525 { |
|
526 // Find the WServ object associated with this op code |
|
527 opcode &= ~EWsOpcodeHandle; |
|
528 iCurrentCommand.iOpcode = reinterpret_cast<TUint16&>(opcode); |
|
529 iDestObj=HandleToObjUntyped(pCmd->iDestHandle); |
|
530 headerLen = sizeof(*pCmd); |
|
531 } |
|
532 |
|
533 iNextCmd += headerLen; |
|
534 const TAny* cmdParams = iNextCmd; |
|
535 iNextCmd += pCmd->iBase.iCmdLength; |
|
536 if (!iDestObj || iNextCmd>endCmd) // Invalid handle or Corrupt buffer |
|
537 { |
|
538 SessionPanic(iDestObj==NULL ? EWservPanicHandle : EWservPanicBuffer); |
|
539 iInternalFlags|=EFinishedProcessingCommands; |
|
540 break; |
|
541 } |
|
542 |
|
543 if (iNextCmd==endCmd) |
|
544 iInternalFlags|=EFinishedProcessingCommands; |
|
545 |
|
546 if (wsDebugLog) |
|
547 wsDebugLog->Command(iDestObj->Type(), opcode, cmdParams, iDestObj->LogHandle()); |
|
548 |
|
549 // Dispatch the command to the WServ object that will process it |
|
550 iDestObj->CommandL(opcode, cmdParams); // (call #5) |
|
551 } |
|
552 while(iNextCmd<endCmd && !TWindowServerEvent::EventReceiver()->IsReadyToRun()); |
|
553 |
|
554 } |
|
555 |
|
556 void CWsClient::DoServiceCommandBuf() // (step #3.1) |
|
557 { |
|
558 iCurrentClient=this; |
|
559 iInternalFlags&=~EFinishedProcessingCommands; |
|
560 TRAPD(err, DispatchCommandsInBufL()); // (call #4) |
|
561 |
|
562 #if defined(_DEBUG) |
|
563 if (err!=KErrNone && !(iInternalFlags&(EFinishedProcessingCommands|EPanicClientAsSoonAsPossible))) |
|
564 SessionPanic(EWservPanicFunctionLeave); |
|
565 #endif |
|
566 |
|
567 if (err<KErrNone) |
|
568 SetReply(err); |
|
569 |
|
570 if (iInternalFlags&(EFinishedProcessingCommands|EPanicClientAsSoonAsPossible)) |
|
571 CompleteMessage(iClientMessage,iReply); // (finish) |
|
572 else |
|
573 iMoreCommands->Start(TCallBack(CWsClient::DoContinueDeferredServiceOfCommandBuf,this)); // (call #3.1.1) |
|
574 |
|
575 iCurrentClient=NULL; |
|
576 #if defined(_DEBUG) |
|
577 User::Heap().Check(); |
|
578 #endif |
|
579 } |
|
580 |
|
581 TInt CWsClient::DoContinueDeferredServiceOfCommandBuf(TAny* aClient) // (step #3.1.1) |
|
582 { |
|
583 static_cast<CWsClient*>(aClient)->DoServiceCommandBuf(); // (call #3.1) |
|
584 return KErrNone; |
|
585 } |
|
586 |
|
587 |
|
588 void CWsClient::ExecuteAsyncClientCommandL(TInt aOpcode, const RMessage2& aMessage) // (step #3.2) |
|
589 { |
|
590 switch(aOpcode) |
|
591 { |
|
592 case EWsClOpEventReady: |
|
593 EventReady(aMessage); |
|
594 break; |
|
595 case EWsClOpPriorityKeyReady: |
|
596 PriorityKeyEventReady(aMessage); |
|
597 break; |
|
598 case EWsClOpRedrawReady: |
|
599 RedrawEventReady(aMessage); |
|
600 break; |
|
601 case EWsClOpGraphicMessageReady: |
|
602 iGraphicMessageQueue.EventReady(aMessage); |
|
603 break; |
|
604 default: |
|
605 { |
|
606 PPanic(EWservPanicOpcode); |
|
607 break; |
|
608 } |
|
609 } |
|
610 } |
|
611 |
|
612 |
|
613 |
|
614 void CWsClient::ExecuteCommandL(TInt aOpcode, const TAny* aCmdData) // (step #6) |
|
615 { |
|
616 TWsClCmdUnion pData; |
|
617 pData.any=aCmdData; |
|
618 switch(aOpcode) |
|
619 { |
|
620 case EWsClOpCreateWindowGroup: |
|
621 CreateNewWindowGroupL(*pData.CreateWindowGroup); |
|
622 break; |
|
623 case EWsClOpCreateWindow: |
|
624 CreateNewWindowL(*pData.CreateWindow); |
|
625 break; |
|
626 case EWsClOpCreateGc: |
|
627 CWsGc::NewL(this); |
|
628 break; |
|
629 case EWsClOpCreateAnimDll: |
|
630 if (!CheckBuffer(pData.LoadAnimDll->length, KMaxFileName)) |
|
631 PanicCurrentClient(EWservPanicBufferPtr); |
|
632 CreateNewAnimDllL(pData); |
|
633 break; |
|
634 case EWsClOpCreateGraphic: |
|
635 CWsGraphicDrawerObject::NewL(this,pData); |
|
636 break; |
|
637 case EWsClOpCreateScreenDevice: |
|
638 { |
|
639 const TInt screenNumber = pData.CreateScreenDevice->screenNumber; |
|
640 const TUint clientScreenDevicePointer = pData.CreateScreenDevice->clientScreenDevicePointer; |
|
641 if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens()) |
|
642 { |
|
643 PPanic(EWservPanicScreenNumber); |
|
644 } |
|
645 else |
|
646 { |
|
647 CreateNewScreenDeviceL(screenNumber,clientScreenDevicePointer); |
|
648 } |
|
649 } |
|
650 break; |
|
651 case EWsClOpCreateSprite: |
|
652 CreateNewSpriteL(*pData.CreateSprite); |
|
653 break; |
|
654 case EWsClOpCreatePointerCursor: |
|
655 CreateNewPointerCursorL(*pData.CreatePointerCursor); |
|
656 break; |
|
657 case EWsClOpStartSetCustomTextCursor: |
|
658 StartSetCustomTextCursorL(*pData.CustomTextCursorData); |
|
659 break; |
|
660 case EWsClOpCompleteSetCustomTextCursor: |
|
661 CompleteSetCustomTextCursorL(*pData.Int); |
|
662 break; |
|
663 case EWsClOpCreateBitmap: |
|
664 CreateNewBitmapL(*pData.CreateBitmap); |
|
665 break; |
|
666 case EWsClOpCreateDirectScreenAccess: |
|
667 CWsDirectScreenAccess::NewL(this,EFalse); |
|
668 break; |
|
669 case EWsClOpCreateDirectScreenAccessRegionTrackingOnly: |
|
670 CWsDirectScreenAccess::NewL(this,ETrue); //creates a DSA object that will not draw to the screen, but will use just the region tracking functionality |
|
671 break; |
|
672 case EWsClOpCreateClick: |
|
673 CreateNewClickHandlerL(*pData.Uid); |
|
674 break; |
|
675 case EWsClOpSetHotKey: |
|
676 { |
|
677 if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetHotKey API"))) |
|
678 { |
|
679 User::Leave(KErrPermissionDenied); |
|
680 } |
|
681 TWindowServerEvent::SetHotKeyL(*pData.SetHotKey); |
|
682 } |
|
683 break; |
|
684 case EWsClOpClearHotKeys: |
|
685 { |
|
686 if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::ClearHotKeys API"))) |
|
687 { |
|
688 User::Leave(KErrPermissionDenied); |
|
689 } |
|
690 TWindowServerEvent::ClearHotKeysL(*pData.UInt); |
|
691 } |
|
692 break; |
|
693 case EWsClOpRestoreDefaultHotKey: |
|
694 TWindowServerEvent::ResetDefaultHotKeyL(*pData.UInt); |
|
695 break; |
|
696 case EWsClOpSetShadowVector: |
|
697 PPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client |
|
698 break; |
|
699 case EWsClOpShadowVector: |
|
700 PPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client |
|
701 break; |
|
702 case EWsClOpSetKeyboardRepeatRate: |
|
703 { |
|
704 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetKeyboardRepeatRate API"))) |
|
705 { |
|
706 User::Leave(KErrPermissionDenied); |
|
707 } |
|
708 if ((pData.SetKeyboardRepeatRate->initial.Int()<0) || (pData.SetKeyboardRepeatRate->time.Int()<0)) |
|
709 { |
|
710 User::Leave(KErrArgument); |
|
711 } |
|
712 CKeyboardRepeat::SetRepeatTime(pData.SetKeyboardRepeatRate->initial,pData.SetKeyboardRepeatRate->time); |
|
713 } |
|
714 break; |
|
715 case EWsClOpGetKeyboardRepeatRate: |
|
716 { |
|
717 SKeyRepeatSettings settings; |
|
718 CKeyboardRepeat::GetRepeatTime(settings.iInitialTime,settings.iTime); |
|
719 ReplyBuf(&settings,sizeof(settings)); |
|
720 } |
|
721 break; |
|
722 case EWsClOpSetDoubleClick: |
|
723 { |
|
724 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetDoubleClick API"))) |
|
725 { |
|
726 User::Leave(KErrPermissionDenied); |
|
727 } |
|
728 TWsPointer::SetDoubleClick(pData.SetDoubleClick->interval,pData.SetDoubleClick->distance); |
|
729 } |
|
730 break; |
|
731 case EWsClOpGetDoubleClickSettings: |
|
732 { |
|
733 SDoubleClickSettings settings; |
|
734 TWsPointer::GetDoubleClickSettings(settings.iInterval,settings.iDistance); |
|
735 ReplyBuf(&settings,sizeof(settings)); |
|
736 } |
|
737 break; |
|
738 case EWsClOpEventReady: |
|
739 // No need to do anything |
|
740 break; |
|
741 case EWsClOpGetEvent: |
|
742 HandleClientRequestForEventData(); |
|
743 // Check flag if the group message queue is overflow and has pended messages |
|
744 if (iInternalFlags & EWgMsgQueueOverflow) |
|
745 { |
|
746 iInternalFlags &= ~EWgMsgQueueOverflow; |
|
747 CWsWindowGroup::ReleasePendedMessagesToAllGroups(this); |
|
748 } |
|
749 break; |
|
750 case EWsClOpPurgePointerEvents: |
|
751 PurgePointerEvents(); |
|
752 break; |
|
753 case EWsClOpEventReadyCancel: |
|
754 CancelClientRequestForEventData(); |
|
755 break; |
|
756 case EWsClOpRedrawReady: |
|
757 iInternalFlags&=~EIsPerformingRedrawEvent; |
|
758 break; |
|
759 case EWsClOpRedrawReadyCancel: |
|
760 CancelClientRequestForRedrawEvent(); |
|
761 break; |
|
762 case EWsClOpGetRedraw: |
|
763 HandleClientRequestForRedrawData(); |
|
764 break; |
|
765 case EWsClOpPriorityKeyReady: |
|
766 // No need to do anything |
|
767 break; |
|
768 case EWsClOpPriorityKeyReadyCancel: |
|
769 CancelClientRequestForPriorityKeyEvent(); |
|
770 break; |
|
771 case EWsClOpGetPriorityKey: |
|
772 HandleClientRequestForPriorityKeyData(); |
|
773 break; |
|
774 case EWsClOpNumWindowGroups: |
|
775 SetReply(CWsWindowGroup::NumWindowGroups(EFalse,* pData.Int)); |
|
776 break; |
|
777 case EWsClOpNumWindowGroupsAllPriorities: |
|
778 SetReply(CWsWindowGroup::NumWindowGroups(ETrue, 0)); |
|
779 break; |
|
780 case EWsClOpNumWindowGroupsOnScreen: |
|
781 { |
|
782 const TInt screenNumber=pData.NumWinGroups->screenNumber; |
|
783 if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens()) |
|
784 PPanic(EWservPanicScreenNumber); |
|
785 else |
|
786 SetReply(CWsWindowGroup::NumWindowGroupsOnScreen(CWsTop::Screen(screenNumber)->RootWindow()->Child(),(pData.NumWinGroups->priority==EAllPriorities),pData.NumWinGroups->priority)); |
|
787 } |
|
788 break; |
|
789 case EWsClOpWindowGroupList: |
|
790 { |
|
791 const TInt screenNumber=pData.WindowGroupList->screenNumber; |
|
792 if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens()) |
|
793 PPanic(EWservPanicScreenNumber); |
|
794 else |
|
795 SetReply(CWsWindowGroup::SendWindowGroupListL(screenNumber,(pData.WindowGroupList->priority==EAllPriorities), pData.WindowGroupList->priority, pData.WindowGroupList->count)); |
|
796 } |
|
797 break; |
|
798 case EWsClOpWindowGroupListAllPriorities: |
|
799 { |
|
800 const TInt screenNumber=pData.WindowGroupList->screenNumber; |
|
801 if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens()) |
|
802 PPanic(EWservPanicScreenNumber); |
|
803 else |
|
804 SetReply(CWsWindowGroup::SendWindowGroupListL(screenNumber,ETrue, 0, pData.WindowGroupList->count)); |
|
805 } |
|
806 break; |
|
807 case EWsClOpWindowGroupListAndChain: |
|
808 SetReply(CWsWindowGroup::SendWindowGroupListAndChainL(EFalse, pData.WindowGroupList->priority, pData.WindowGroupList->count)); |
|
809 break; |
|
810 case EWsClOpWindowGroupListAndChainAllPriorities: |
|
811 SetReply(CWsWindowGroup::SendWindowGroupListAndChainL(ETrue, 0, pData.WindowGroupList->count)); |
|
812 break; |
|
813 case EWsClOpGetDefaultOwningWindow: |
|
814 { |
|
815 const TInt screenNumber = *pData.Int; |
|
816 if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens()) |
|
817 PPanic(EWservPanicScreenNumber); |
|
818 else |
|
819 { |
|
820 CScreen* screen = (screenNumber ==KDummyScreenNumber) ? iScreen : CWsTop::Screen(screenNumber); |
|
821 SetReply(screen->DefaultOwningWindowGroup() ? screen->DefaultOwningWindowGroup()->Identifier():0); |
|
822 } |
|
823 } |
|
824 break; |
|
825 case EWsClOpGetFocusWindowGroup: |
|
826 { |
|
827 const TInt screenNumber = *pData.Int; |
|
828 if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens()) |
|
829 PPanic(EWservPanicScreenNumber); |
|
830 else |
|
831 CWsWindowGroup::GetFocusWindowGroupL(screenNumber); |
|
832 } |
|
833 break; |
|
834 case EWsClOpSetWindowGroupOrdinalPosition: |
|
835 CWsWindowGroup::WindowGroupFromIdentifierL(pData.SetWindowGroupOrdinalPosition->identifier)->SetOrdinalPosition(pData.SetWindowGroupOrdinalPosition->position); |
|
836 break; |
|
837 case EWsClOpGetWindowGroupHandle: |
|
838 SetReply(CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->ClientHandle()); |
|
839 break; |
|
840 case EWsClOpGetWindowGroupOrdinalPriority: |
|
841 SetReply(CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->OrdinalPriority()); |
|
842 break; |
|
843 case EWsClOpGetWindowGroupClientThreadId: |
|
844 { |
|
845 TThreadId id=CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->WsOwner()->Client().Id(); |
|
846 ReplyBuf(&id,sizeof(id)); |
|
847 } |
|
848 break; |
|
849 case EWsClOpSendEventToWindowGroup: |
|
850 { |
|
851 CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(pData.SendEventToWindowGroup->parameter); |
|
852 TWsEvent event=pData.SendEventToWindowGroup->event; |
|
853 event.SetHandle(group->ClientHandle()); |
|
854 // Events in enum TEventCode is protected by capabilities |
|
855 if (group->WsOwner()!=this && event.Type()>=EEventNull && event.Type()<EEventUser) |
|
856 { |
|
857 if (event.Type()<EEventPowerMgmt || event.Type()>=EEventReserved) |
|
858 { |
|
859 if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToWindowGroup API"))) |
|
860 User::Leave(KErrPermissionDenied); |
|
861 } |
|
862 else |
|
863 { |
|
864 if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToWindowGroup API"))) |
|
865 User::Leave(KErrPermissionDenied); |
|
866 } |
|
867 } |
|
868 if (event.Type()==EEventKey && event.Key()->iRepeats!=0) |
|
869 CKeyboardRepeat::CancelRepeat(NULL); //Otherwise we will trip an invarient |
|
870 if (!group->EventQueue()->QueueEvent(event)) |
|
871 User::Leave(KErrNoMemory); |
|
872 } |
|
873 break; |
|
874 case EWsClOpSendEventToAllWindowGroup: |
|
875 case EWsClOpSendEventToAllWindowGroupPriority: |
|
876 case EWsClOpSendEventToOneWindowGroupPerClient: |
|
877 { |
|
878 TWsEvent event=pData.SendEventToWindowGroup->event; |
|
879 if (event.Type()<0) |
|
880 User::Leave(KErrArgument); |
|
881 if(event.Type()<EEventUser) |
|
882 { |
|
883 if (event.Type()<EEventPowerMgmt || event.Type()>=EEventReserved) |
|
884 { |
|
885 if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToAllWindowGroup API"))) |
|
886 User::Leave(KErrPermissionDenied); |
|
887 } |
|
888 else |
|
889 { |
|
890 if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToAllWindowGroup API"))) |
|
891 User::Leave(KErrPermissionDenied); |
|
892 } |
|
893 } |
|
894 if (!CWsWindowGroup::SendEventToAllGroups(aOpcode!=EWsClOpSendEventToAllWindowGroupPriority |
|
895 ,aOpcode==EWsClOpSendEventToOneWindowGroupPerClient,*pData.SendEventToWindowGroup)) |
|
896 User::Leave(KErrNoMemory); |
|
897 } |
|
898 break; |
|
899 case EWsClOpSendMessageToWindowGroup: |
|
900 { |
|
901 CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(pData.SendMessageToWindowGroup->identifierOrPriority); |
|
902 if (group->WsOwner()!=this) |
|
903 { |
|
904 if (!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendMessageToWindowGroup API"))) |
|
905 { |
|
906 User::Leave(KErrPermissionDenied); |
|
907 } |
|
908 } |
|
909 group->QueueMessageL(pData.SendMessageToWindowGroup->uid, pData.SendMessageToWindowGroup->dataLength,* this); |
|
910 } |
|
911 break; |
|
912 case EWsClOpSendMessageToAllWindowGroups: |
|
913 case EWsClOpSendMessageToAllWindowGroupsPriority: |
|
914 { |
|
915 if ((pData.SendMessageToWindowGroup->dataLength<0) || (pData.SendMessageToWindowGroup->dataLength>=(KMaxTInt/2))) |
|
916 { |
|
917 User::Leave(KErrArgument); |
|
918 } |
|
919 CWsWindowGroup::SendMessageToAllGroupsL(*this,aOpcode==EWsClOpSendMessageToAllWindowGroups,*pData.SendMessageToWindowGroup); |
|
920 } |
|
921 break; |
|
922 case EWsClOpFetchMessage: |
|
923 CWsWindowGroup::WindowGroupFromIdentifierL(pData.FetchMessage->windowGroupIdentifier)->FetchMessageL(); |
|
924 break; |
|
925 case EWsClOpGetWindowGroupNameFromIdentifier: |
|
926 ReplyGroupName(CWsWindowGroup::WindowGroupFromIdentifierL(pData.GetWindowGroupNameFromIdentifier->identifier)->GroupName(),pData.GetWindowGroupNameFromIdentifier->maxLength); |
|
927 break; |
|
928 case EWsClOpFindWindowGroupIdentifier: |
|
929 { |
|
930 if (pData.FindWindowGroupIdentifier->length<0) |
|
931 User::Leave(KErrArgument); |
|
932 TPtrC ptr(BufferTPtr((TText*)(pData.FindWindowGroupIdentifier+1),pData.FindWindowGroupIdentifier->length)); |
|
933 SetReply(CWsWindowGroup::FindWindowGroupL(this, pData.FindWindowGroupIdentifier->identifier, |
|
934 pData.FindWindowGroupIdentifier->offset,&ptr,NULL)->Identifier()); |
|
935 } |
|
936 break; |
|
937 case EWsClOpFindWindowGroupIdentifierThread: |
|
938 SetReply(CWsWindowGroup::FindWindowGroupL(this, pData.FindWindowGroupIdentifierThread->identifier,0,NULL, |
|
939 &pData.FindWindowGroupIdentifierThread->threadId)->Identifier()); |
|
940 break; |
|
941 case EWsClOpSetBackgroundColor: |
|
942 for(TInt i=0;i<CWsTop::NumberOfScreens();i++) |
|
943 { |
|
944 CWsTop::Screen(i)->RootWindow()->SetColor(*pData.rgb); |
|
945 } |
|
946 break; |
|
947 case EWsClOpGetBackgroundColor: |
|
948 SetReply(iScreen->RootWindow()->BackColor().Internal()); |
|
949 break; |
|
950 case EWsClOpClaimSystemPointerCursorList: |
|
951 { |
|
952 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::ClaimSystemPointerCursorList API"))) |
|
953 { |
|
954 User::Leave(KErrPermissionDenied); |
|
955 } |
|
956 ClaimSystemPointerCursorListL(); |
|
957 } |
|
958 break; |
|
959 case EWsClOpFreeSystemPointerCursorList: |
|
960 FreeSystemPointerCursorList(); |
|
961 break; |
|
962 case EWsClOpSetSystemPointerCursor: |
|
963 { |
|
964 CWsObject* pointercursor = NULL; |
|
965 if ((pointercursor=HandleToObj(pData.SetSystemPointerCursor->handle, WS_HANDLE_POINTER_CURSOR))==NULL) |
|
966 PPanic(EWservPanicSprite); |
|
967 |
|
968 SetSystemPointerCursorL(pData.SetSystemPointerCursor->number, (CWsPointerCursor* )pointercursor); |
|
969 } |
|
970 break; |
|
971 case EWsClOpClearSystemPointerCursor: |
|
972 ClearSystemPointerCursor(*pData.Int); |
|
973 break; |
|
974 case EWsClOpSetPointerCursorArea: |
|
975 { |
|
976 if(KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorArea API"))) |
|
977 { |
|
978 if (!iScreen->IsValidScreenSizeMode(*pData.Int)) |
|
979 PPanic(EWservPanicScreenModeNumber); |
|
980 iScreen->SetPointerCursorArea(pData.SetPointerCursorArea->mode,pData.SetPointerCursorArea->area); |
|
981 } |
|
982 } |
|
983 break; |
|
984 case EWsClOpPointerCursorArea: |
|
985 if (!iScreen->IsValidScreenSizeMode(*pData.Int)) |
|
986 PPanic(EWservPanicScreenModeNumber); |
|
987 |
|
988 ReplyRect(iScreen->GetPointerCursorArea(*pData.Int)); |
|
989 break; |
|
990 case EWsClOpSetPointerCursorMode: |
|
991 { |
|
992 CWsWindowGroup* focusWinGp=CWsTop::FocusWindowGroup(); |
|
993 if (focusWinGp && focusWinGp->WsOwner()==this) |
|
994 { |
|
995 TWsPointer::SetPointerCursorMode(*pData.Mode); |
|
996 TWsPointer::UpdatePointerCursor(); |
|
997 } |
|
998 } |
|
999 break; |
|
1000 case EWsClOpSetClientCursorMode : |
|
1001 { |
|
1002 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorModeIfFocused API"))) |
|
1003 { |
|
1004 User::Leave(KErrPermissionDenied); |
|
1005 } |
|
1006 TWsPointer::SetPointerCursorMode(*pData.Mode); |
|
1007 TWsPointer::UpdatePointerCursor(); |
|
1008 } |
|
1009 break; |
|
1010 case EWsClOpPointerCursorMode: |
|
1011 SetReply(TWsPointer::PointerCursorMode()); |
|
1012 break; |
|
1013 case EWsClOpSetDefaultSystemPointerCursor: |
|
1014 SetDefaultSystemPointerCursor(*pData.Int); |
|
1015 break; |
|
1016 case EWsClOpClearDefaultSystemPointerCursor: |
|
1017 SetDefaultSystemPointerCursor(ENoDefaultSystemPointerCursor); |
|
1018 break; |
|
1019 case EWsClOpSetPointerCursorPosition: |
|
1020 { |
|
1021 CWsWindowGroup* focusWinGp=CWsTop::FocusWindowGroup(); |
|
1022 if ((!focusWinGp || focusWinGp->WsOwner()!=this)&& |
|
1023 (!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorPosition API")))) |
|
1024 { |
|
1025 User::Leave(KErrPermissionDenied); |
|
1026 } |
|
1027 TWsPointer::SetPointerCursorPos(*pData.Point); |
|
1028 } |
|
1029 break; |
|
1030 case EWsClOpPointerCursorPosition: |
|
1031 ReplyPoint(TWsPointer::PointerCursorPos()); |
|
1032 break; |
|
1033 case EWsClOpSetModifierState: |
|
1034 { |
|
1035 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetModifierState API"))) |
|
1036 { |
|
1037 User::Leave(KErrPermissionDenied); |
|
1038 } |
|
1039 TWindowServerEvent::SetModifierState(pData.SetModifierState->modifier,pData.SetModifierState->state); |
|
1040 } |
|
1041 break; |
|
1042 case EWsClOpGetModifierState: |
|
1043 SetReply(TWindowServerEvent::GetModifierState()); |
|
1044 break; |
|
1045 case EWsClOpHeapCount: |
|
1046 SetReply(CWsMemoryManager::Static()->Count()); |
|
1047 break; |
|
1048 case EWsClOpDebugInfo: |
|
1049 DebugInfoL(pData.DebugInfo->iFunction,pData.DebugInfo->iParam,EFalse); |
|
1050 break; |
|
1051 case EWsClOpDebugInfoReplyBuf: |
|
1052 DebugInfoL(pData.DebugInfo->iFunction,pData.DebugInfo->iParam,ETrue); |
|
1053 break; |
|
1054 case EWsClOpResourceCount: |
|
1055 SetReply(iObjectIndex->Count()); |
|
1056 break; |
|
1057 case EWsClOpHeapSetFail: |
|
1058 { |
|
1059 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::HeapSetFail API"))) |
|
1060 { |
|
1061 PPanic(EWservPanicPermissionDenied); |
|
1062 } |
|
1063 #if !defined(_DEBUG) |
|
1064 if (pData.HeapSetFail->type!=RHeap::ENone) |
|
1065 TWindowServerEvent::NotifyOom(); |
|
1066 #endif |
|
1067 // if there is a memory manager and we are making the allocator fail next or |
|
1068 // deteministic we want to make sure we test both when the memory manager |
|
1069 // succeeds and fails in allocating after freeing up memory. we do that by |
|
1070 // remapping the rate and explicitly telling the memory manager to fail: |
|
1071 // requested rate | fail on retry, actual rate |
|
1072 // 1 | true , 1 |
|
1073 // 2 | false , 1 |
|
1074 // 3 | true , 2 |
|
1075 CWsMemoryManager* memoryManager = NULL; |
|
1076 TInt rate = pData.HeapSetFail->value; |
|
1077 TBool memoryManagerRetryFail = EFalse; |
|
1078 if((pData.HeapSetFail->type == RAllocator::EFailNext || pData.HeapSetFail->type == RAllocator::EDeterministic)) |
|
1079 { |
|
1080 memoryManager = CWsMemoryManager::Static(); |
|
1081 if(memoryManager) |
|
1082 { |
|
1083 memoryManagerRetryFail = (rate % 2 == 1); |
|
1084 rate = rate / 2 + (memoryManagerRetryFail ? 1 : 0); |
|
1085 } |
|
1086 } |
|
1087 |
|
1088 switch (pData.HeapSetFail->type) |
|
1089 { //This log message means you can safely ignore the allocation failures in between |
|
1090 //see CWindowServer::ReleaseMemory() |
|
1091 case RAllocator::ENone: |
|
1092 RDebug::Printf("WSERV Heap: __DbgSetAllocFail() <<<ENone"); |
|
1093 break; |
|
1094 case RAllocator::EReset: |
|
1095 RDebug::Printf("WSERV Heap: __DbgSetAllocFail() <<<EReset"); |
|
1096 break; |
|
1097 default: |
|
1098 if (memoryManagerRetryFail) |
|
1099 RDebug::Printf("WSERV Heap: Memory Manager set to fail on retry"); |
|
1100 RDebug::Printf("WSERV Heap: __DbgSetAllocFail(EUser,%i,%i)>>>", pData.HeapSetFail->type, rate); |
|
1101 break; |
|
1102 } |
|
1103 |
|
1104 if (memoryManager && memoryManagerRetryFail) |
|
1105 memoryManager->SetFailNextRetry(); |
|
1106 |
|
1107 if (pData.HeapSetFail->burst >= 0) |
|
1108 User::__DbgSetBurstAllocFail(RHeap::EUser, pData.HeapSetFail->type, rate, pData.HeapSetFail->burst); |
|
1109 else |
|
1110 User::__DbgSetAllocFail(RHeap::EUser, pData.HeapSetFail->type, rate); |
|
1111 break; |
|
1112 } |
|
1113 case EWsClOpRawEvent: |
|
1114 { |
|
1115 if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SimulateRawEvent API"))) |
|
1116 { |
|
1117 PPanic(EWservPanicPermissionDenied); |
|
1118 } |
|
1119 TRawEvent event(*pData.RawEvent); |
|
1120 if (TWsPointer::PreProcessDriverEvent(event)) |
|
1121 TWindowServerEvent::ProcessRawEvent(event); |
|
1122 } |
|
1123 break; |
|
1124 case EWsClOpKeyEvent: |
|
1125 { |
|
1126 if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SimulateKeyEvent API"))) |
|
1127 { |
|
1128 PPanic(EWservPanicPermissionDenied); |
|
1129 } |
|
1130 TWindowServerEvent::ProcessKeyEvent(*pData.KeyEvent,0); |
|
1131 } |
|
1132 break; |
|
1133 case EWsClOpLogMessage: |
|
1134 if (wsDebugLog) |
|
1135 { |
|
1136 if (CheckBuffer(*pData.Int, KLogMessageLength)) |
|
1137 wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,BufferTPtr((TText* )(pData.Int+1),*pData.Int),0); |
|
1138 } |
|
1139 break; |
|
1140 case EWsClOpPasswordEntered: |
|
1141 CWsPassword::PasswordEntered(this); |
|
1142 break; |
|
1143 case EWsClOpComputeMode: |
|
1144 SetComputeMode(*pData.ComputeMode); |
|
1145 break; |
|
1146 case EWsClOpSendOffEventsToShell: |
|
1147 { |
|
1148 if(!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::RequestOffEvents API"))) |
|
1149 { |
|
1150 User::Leave(KErrPermissionDenied); |
|
1151 } |
|
1152 SetReply(CWsTop::SetSendOffEventsToShell(this,*pData.OffEventsToShell)); |
|
1153 } |
|
1154 break; |
|
1155 case EWsClOpGetDefModeMaxNumColors: |
|
1156 { |
|
1157 SDefModeMaxNumColors colors; |
|
1158 const TInt screenNumber = *pData.Int; |
|
1159 if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens()) |
|
1160 PPanic(EWservPanicScreenNumber); |
|
1161 else |
|
1162 { |
|
1163 CScreen* screen = (screenNumber==KDummyScreenNumber)?iScreen:CWsTop::Screen(screenNumber); |
|
1164 screen->MaxNumColors(colors.iColors,colors.iGrays); |
|
1165 colors.iDisplayMode=screen->FirstDefaultDisplayMode(); |
|
1166 } |
|
1167 ReplyBuf(&colors,sizeof(colors)); |
|
1168 } |
|
1169 break; |
|
1170 case EWsClOpGetColorModeList: |
|
1171 { |
|
1172 const TInt screenNumber = *pData.Int; |
|
1173 if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens()) |
|
1174 PPanic(EWservPanicScreenNumber); |
|
1175 else |
|
1176 SetReply((screenNumber==KDummyScreenNumber) ? iScreen->ColorModesFlag() : CWsTop::Screen(screenNumber)->ColorModesFlag()); |
|
1177 } |
|
1178 break; |
|
1179 case EWsClOpSetDefaultFadingParams: |
|
1180 { |
|
1181 if(KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetDefaultFadingParameters API"))) |
|
1182 { |
|
1183 iScreen->SetFadingParams(WservEncoding::ExtractFirst8BitValue(*pData.UInt),WservEncoding::ExtractSecond8BitValue(*pData.UInt)); |
|
1184 } |
|
1185 } |
|
1186 break; |
|
1187 case EWsClOpPrepareForSwitchOff: |
|
1188 { |
|
1189 if(KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::PrepareForSwitchOff API"))) |
|
1190 { |
|
1191 } |
|
1192 } |
|
1193 break; |
|
1194 case EWsClOpSetFaded: |
|
1195 { |
|
1196 // Deprecated - retained for BC with applications that retrieve the fade count |
|
1197 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetSystemFaded API"))) |
|
1198 User::Leave(KErrPermissionDenied); |
|
1199 |
|
1200 TUint8 blackMap; |
|
1201 TUint8 whiteMap; |
|
1202 if (pData.SetSystemFaded->UseDefaultMap()) |
|
1203 iScreen->GetFadingParams(blackMap,whiteMap); |
|
1204 else |
|
1205 pData.SetSystemFaded->GetFadingParams(blackMap,whiteMap); |
|
1206 |
|
1207 iScreen->RootWindow()->SetSystemFaded(pData.SetSystemFaded->Faded(),blackMap,whiteMap); |
|
1208 } |
|
1209 break; |
|
1210 case EWsClOpLogCommand: |
|
1211 CWsTop::LogCommand(*pData.LogCommand); |
|
1212 break; |
|
1213 #if defined(__WINS__) |
|
1214 case EWsClOpRemoveKeyCode: |
|
1215 iInternalFlags&=~ERemoveKeyCode; |
|
1216 if (*pData.Bool) |
|
1217 iInternalFlags|=ERemoveKeyCode; |
|
1218 break; |
|
1219 case EWsClOpSimulateXyInput: |
|
1220 TWsPointer::SetXyInputType(*pData.XyInput); |
|
1221 break; |
|
1222 #endif |
|
1223 case EWsClOpNoFlickerFree: |
|
1224 PPanic(EWservPanicOpcode); //not supported anymore |
|
1225 break; |
|
1226 case EWsClOpSetFocusScreen: |
|
1227 { |
|
1228 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetFocusScreen API"))) |
|
1229 { |
|
1230 User::Leave(KErrPermissionDenied); |
|
1231 } |
|
1232 TInt focusScreen=*pData.Int; |
|
1233 if (focusScreen>=0 && focusScreen<CWsTop::NumberOfScreens()) |
|
1234 SetReply(CWsTop::SetCurrentFocusScreen(focusScreen)); |
|
1235 else |
|
1236 SessionPanic(EWservPanicScreenNumber); |
|
1237 break; |
|
1238 } |
|
1239 case EWsClOpGetFocusScreen: |
|
1240 SetReply(CWsTop::CurrentFocusScreen()->ScreenNumber()); |
|
1241 break; |
|
1242 case EWsClOpGetNumberOfScreens: |
|
1243 SetReply(CWsTop::NumberOfScreens()); |
|
1244 break; |
|
1245 case EWsClOpClearAllRedrawStores: |
|
1246 CWsTop::ClearAllRedrawStores(); |
|
1247 break; |
|
1248 case EWsClOpGetGraphicMessage: |
|
1249 iGraphicMessageQueue.GetGraphicMessage(); |
|
1250 break; |
|
1251 case EWsClOpGraphicMessageCancel: |
|
1252 iGraphicMessageQueue.CancelRead(); |
|
1253 break; |
|
1254 case EWsClOpGraphicAbortMessage: |
|
1255 iGraphicMessageQueue.AbortMessage(*pData.Int); |
|
1256 break; |
|
1257 case EWsClOpGraphicFetchHeaderMessage: |
|
1258 SetReply(iGraphicMessageQueue.TopClientHandle()); |
|
1259 break; |
|
1260 case EWsClOpRegisterSurface: |
|
1261 SetReply(RegisterSurface(pData)); |
|
1262 break; |
|
1263 case EWsClOpUnregisterSurface: |
|
1264 UnregisterSurface(pData); |
|
1265 break; |
|
1266 case EWsClOpSetCloseProximityThresholds: |
|
1267 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(), |
|
1268 __PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetCloseProximityThresholds"))) |
|
1269 { |
|
1270 User::Leave(KErrPermissionDenied); |
|
1271 } |
|
1272 SetReply(TWsPointer::SetCloseProximityThresholds(pData.ZThresholdPair->enterThreshold, |
|
1273 pData.ZThresholdPair->exitThreshold)); |
|
1274 break; |
|
1275 case EWsClOpSetHighPressureThresholds: |
|
1276 if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(), |
|
1277 __PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetHighPressureThresholds"))) |
|
1278 { |
|
1279 User::Leave(KErrPermissionDenied); |
|
1280 } |
|
1281 SetReply(TWsPointer::SetHighPressureThresholds(pData.ZThresholdPair->enterThreshold, |
|
1282 pData.ZThresholdPair->exitThreshold)); |
|
1283 break; |
|
1284 case EWsClOpGetEnterCloseProximityThreshold: |
|
1285 SetReply(TWsPointer::GetEnterCloseProximityThreshold()); |
|
1286 break; |
|
1287 case EWsClOpGetExitCloseProximityThreshold: |
|
1288 SetReply(TWsPointer::GetExitCloseProximityThreshold()); |
|
1289 break; |
|
1290 case EWsClOpGetEnterHighPressureThreshold: |
|
1291 SetReply(TWsPointer::GetEnterHighPressureThreshold()); |
|
1292 break; |
|
1293 case EWsClOpGetExitHighPressureThreshold: |
|
1294 SetReply(TWsPointer::GetExitHighPressureThreshold()); |
|
1295 break; |
|
1296 case EWsClOpCreateDrawableSource: |
|
1297 CreateDrawableSourceL(*pData.CreateDrawableSource); |
|
1298 break; |
|
1299 default: |
|
1300 PPanic(EWservPanicOpcode); |
|
1301 break; |
|
1302 } |
|
1303 } |
|
1304 /** Debug information accessor. |
|
1305 * |
|
1306 * |
|
1307 **/ |
|
1308 void CWsClient::DebugInfoL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const |
|
1309 { |
|
1310 if (aFunction & EWsDebugClassMask) |
|
1311 SetReply(DebugInfoClassifiedL(aFunction,aParam,aHasReplyBuf)); |
|
1312 else |
|
1313 DebugInfoUnclassifiedL(aFunction,aParam,aHasReplyBuf); |
|
1314 } |
|
1315 |
|
1316 /** A wide variety of generally unconnected debug enquiries. |
|
1317 * |
|
1318 * |
|
1319 **/ |
|
1320 void CWsClient::DebugInfoUnclassifiedL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const |
|
1321 { |
|
1322 switch(aFunction) |
|
1323 { |
|
1324 case EWsDebugInfoHeap: |
|
1325 if (aHasReplyBuf) |
|
1326 { |
|
1327 TWsDebugHeapInfo heapInfo; |
|
1328 RHeap& heap=User::Heap(); |
|
1329 heapInfo.iCount=heap.AllocSize(heapInfo.iTotal); |
|
1330 heapInfo.iAvailable=heap.Available(heapInfo.iLargestAvailable); |
|
1331 ReplyBuf(&heapInfo,sizeof(heapInfo)); |
|
1332 } |
|
1333 SetReply(KErrArgument); |
|
1334 break; |
|
1335 case EWsDebugSetCheckHeapOnDisconnectClient: |
|
1336 if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::DebugInfo API"))) |
|
1337 { |
|
1338 User::Leave(KErrPermissionDenied); |
|
1339 } |
|
1340 CWsTop::SetCheckHeapOnDisconnectClient(this); |
|
1341 break; |
|
1342 case EWsDebugSetCheckHeapOnDisconnectMode: |
|
1343 if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::DebugInfo API"))) |
|
1344 { |
|
1345 User::Leave(KErrPermissionDenied); |
|
1346 } |
|
1347 CWsTop::SetCheckHeapOnDisconnectMode(STATIC_CAST(TWsCheckHeapOnDisconnectMode,aParam)); |
|
1348 break; |
|
1349 case EWsDebugFetchCheckHeapResult: |
|
1350 SetReply(CWsTop::FetchCheckHeapResult()); |
|
1351 break; |
|
1352 case EWsDebugSetEventQueueTest: |
|
1353 CWsWindowGroup::SetEventQueueTestState(aParam); |
|
1354 break; |
|
1355 default: |
|
1356 SetReply(KErrNotSupported); |
|
1357 break; |
|
1358 } |
|
1359 } |
|
1360 |
|
1361 /** Selects a debug function based on the class of debug query. |
|
1362 * |
|
1363 * |
|
1364 **/ |
|
1365 TInt CWsClient::DebugInfoClassifiedL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const |
|
1366 {//Duplicating the meanings of Classified... this would be a good place for a security check |
|
1367 //first part of param is always screen number |
|
1368 TInt buffSpace=aHasReplyBuf?ReplyBufSpace():0; |
|
1369 if (buffSpace<0) |
|
1370 return (buffSpace); |
|
1371 |
|
1372 const TInt screenNumber = (aParam&EWsDebugArgScreenMask)>>EWsDebugArgScreenShift; |
|
1373 const TInt functionClass = (aFunction&EWsDebugClassMask); |
|
1374 CScreen* screen = NULL; |
|
1375 if (functionClass<EWsDebugClassNonScreen) |
|
1376 { |
|
1377 if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens()) |
|
1378 return (KErrArgument); |
|
1379 |
|
1380 screen = CWsTop::Screen(screenNumber); |
|
1381 } |
|
1382 WS_ASSERT_DEBUG(screen, EWsPanicNoScreen); |
|
1383 switch (aFunction&EWsDebugClassMask) |
|
1384 { |
|
1385 case EWsDebugClassScreenUiElement: |
|
1386 return DebugInfoScreenUiL(aFunction,aParam,buffSpace,*screen); |
|
1387 case EWsDebugClassScreenElementSet: |
|
1388 return DebugInfoScreenElementSetL(aFunction, aParam, buffSpace, *screen); |
|
1389 case EWsDebugClassElementSetWindow: |
|
1390 return DebugInfoElementSetWindowL(aFunction, aParam, buffSpace, *screen); |
|
1391 case EWsDebugClassElementSetElement: |
|
1392 return DebugInfoElementSetElementL(aFunction, aParam, buffSpace, *screen); |
|
1393 |
|
1394 case EWsDebugClassClientWindow: |
|
1395 default: |
|
1396 return (KErrNotSupported); |
|
1397 } |
|
1398 } |
|
1399 |
|
1400 /** Returns debug info about the UIElement entries for a screen. |
|
1401 * This describes the general state or size of the element set. |
|
1402 * It is indexed via screen num, and optionally element index. |
|
1403 * Element index MUST BE 0 when not required. |
|
1404 * @return size of buffer required or error code. |
|
1405 **/ |
|
1406 TInt CWsClient::DebugInfoScreenUiL(TInt aFunction, TInt /* aParam */, TInt aReplyBufSize, CScreen& aScreen) const |
|
1407 { |
|
1408 switch(aFunction) |
|
1409 { |
|
1410 case EWsDebugGetFastpathMode: |
|
1411 { |
|
1412 // obsolete through preq2669 |
|
1413 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1414 return KErrNotSupported; |
|
1415 } |
|
1416 |
|
1417 case EWsDebugSetFastpathMode: |
|
1418 { |
|
1419 // obsolete through preq2669 |
|
1420 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1421 return KErrNotSupported; |
|
1422 } |
|
1423 |
|
1424 case EWsDebugGetUIElementInfoList: |
|
1425 { |
|
1426 // obsolete through preq2669 |
|
1427 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1428 return KErrNotSupported; |
|
1429 } |
|
1430 |
|
1431 case EWsDebugGetUIElementBase: |
|
1432 { |
|
1433 // obsolete through preq2669 |
|
1434 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1435 return KErrNotSupported; |
|
1436 } |
|
1437 |
|
1438 case EWsDebugGetUIElementIds: |
|
1439 { |
|
1440 // obsolete through preq2669 |
|
1441 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1442 return KErrNotSupported; |
|
1443 } |
|
1444 |
|
1445 case EWsDebugGetSceneElementIdOrder: |
|
1446 { |
|
1447 // obsolete through preq2669 |
|
1448 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1449 return KErrNotSupported; |
|
1450 } |
|
1451 case EWsDebugSetFastpathTestMode: |
|
1452 { |
|
1453 // obsolete through preq2669 |
|
1454 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1455 return KErrNotSupported; |
|
1456 } |
|
1457 |
|
1458 case EWsDebugSetFastpathOomMode: |
|
1459 { |
|
1460 // obsolete through preq2669 |
|
1461 WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState); |
|
1462 return KErrNotSupported; |
|
1463 } |
|
1464 case EWsDebugGetUIElementConfig: |
|
1465 { |
|
1466 return DebugReturnConfig(aReplyBufSize,&aScreen.UiElement(),0); |
|
1467 |
|
1468 } |
|
1469 default: |
|
1470 return (KErrNotSupported); |
|
1471 } |
|
1472 } |
|
1473 |
|
1474 /** Returns debug info about the CWindowElementSet entry for a screen. |
|
1475 * This describes the general state or size of the element set |
|
1476 * It is indexed via screen num. |
|
1477 * @return size of buffer required or error code. |
|
1478 **/ |
|
1479 TInt CWsClient::DebugInfoScreenElementSetL(TInt aFunction, TInt /*aParam*/, TInt aReplyBufSize, const CScreen& aScreen) const |
|
1480 { |
|
1481 const CWindowElementSet& elementSet = aScreen.WindowElements(); |
|
1482 switch (aFunction) |
|
1483 { |
|
1484 case EWsDebugSerialSurfacesUpdated: |
|
1485 return 0; |
|
1486 |
|
1487 case EWsDebugSurfaceWindowList: |
|
1488 { |
|
1489 TInt outSize = elementSet.Count() * sizeof(TWsDebugWindowId); |
|
1490 if (outSize<=aReplyBufSize) |
|
1491 {//can stream, so I shall! |
|
1492 for (TInt index = 0; index < elementSet.Count(); index++) |
|
1493 { |
|
1494 const CWsClientWindow& win = *elementSet.DebugWindowAt(index); |
|
1495 TWsDebugWindowId id= |
|
1496 { |
|
1497 win.ClientHandle(), 0 |
|
1498 }; |
|
1499 if (win.WsOwner()!=this) |
|
1500 id.iOtherGroupId=win.WinGroup()->Identifier(); |
|
1501 ReplyBuf(&id, sizeof(id)); |
|
1502 } |
|
1503 } |
|
1504 return outSize; |
|
1505 } |
|
1506 default: |
|
1507 return (KErrNotSupported); |
|
1508 |
|
1509 } |
|
1510 } |
|
1511 |
|
1512 /** Returns debug info about a CWindowElement entry. |
|
1513 * This describes the window or the background element(s) |
|
1514 * It is indexed via screen num, and index in elementset. |
|
1515 * @return size of buffer required or error code. |
|
1516 **/ |
|
1517 TInt CWsClient::DebugInfoElementSetWindowL(TInt aFunction, TInt aParam, |
|
1518 TInt aReplyBufSize, const CScreen& aScreen) const |
|
1519 { |
|
1520 const CWindowElementSet& elementSet = aScreen.WindowElements(); |
|
1521 TUint winIndex = (aParam & EWsDebugArgWindowMask) >> EWsDebugArgWindowShift; |
|
1522 const TAttributes* winElement = elementSet.DebugBackgroundAt(winIndex); |
|
1523 if (winElement == NULL) |
|
1524 { |
|
1525 return KErrArgument; |
|
1526 } |
|
1527 |
|
1528 MWsElement* backElement = winElement->iElement; |
|
1529 TInt placedCount = elementSet.DebugPlacedCountAt(winIndex); |
|
1530 switch (aFunction) |
|
1531 { |
|
1532 case EWsDebugElementIdList: |
|
1533 { |
|
1534 TInt retVal = (placedCount + 1) * sizeof(MWsElement*); |
|
1535 if (retVal<aReplyBufSize) |
|
1536 { |
|
1537 ReplyBuf(&backElement, sizeof(MWsElement*)); |
|
1538 for (TInt index=0; index<placedCount; index++) |
|
1539 ReplyBuf(&elementSet.DebugPlacedAt(winIndex, index)->iElement, sizeof(MWsElement*)); |
|
1540 } |
|
1541 return retVal; |
|
1542 } |
|
1543 case EWsDebugBackgroundConfig: |
|
1544 if (backElement == NULL) |
|
1545 return KErrNotFound; |
|
1546 else |
|
1547 return DebugReturnConfig(aReplyBufSize, backElement, |
|
1548 winElement->DebugFlags()); |
|
1549 case EWsDebugBackgroundBase: |
|
1550 if (backElement == NULL) |
|
1551 return KErrNotFound; |
|
1552 else |
|
1553 return DebugReturnBase(aReplyBufSize, backElement); |
|
1554 case EWsDebugBackgroundFlags: |
|
1555 return DebugReturnFlags(aReplyBufSize, backElement, |
|
1556 winElement->DebugFlags()); |
|
1557 default: |
|
1558 return KErrNotSupported; |
|
1559 //This method can also be extended to return region and state information from the associated window |
|
1560 } |
|
1561 } |
|
1562 |
|
1563 /** Returns debug info about a placed element. |
|
1564 * It is indexed via screen num, index in elementset, and index in placed element array. |
|
1565 * @return size of buffer required or error code. |
|
1566 **/ |
|
1567 TInt CWsClient::DebugInfoElementSetElementL(TInt aFunction, TInt aParam, |
|
1568 TInt aReplyBufSize, const CScreen& aScreen) const |
|
1569 { |
|
1570 const CWindowElementSet& elementSet = aScreen.WindowElements(); |
|
1571 TUint winIndex = (aParam & EWsDebugArgWindowMask) >> EWsDebugArgWindowShift; |
|
1572 TUint placeIndex = (aParam & EWsDebugArgElementMask) >> EWsDebugArgElementShift; |
|
1573 const TAttributes* placedElement = elementSet.DebugPlacedAt(winIndex, placeIndex); |
|
1574 if (placedElement == NULL) |
|
1575 { |
|
1576 return KErrArgument; |
|
1577 } |
|
1578 |
|
1579 MWsElement* element = placedElement->iElement; |
|
1580 if (element == NULL) |
|
1581 { |
|
1582 return KErrNotFound; |
|
1583 } |
|
1584 |
|
1585 switch (aFunction) |
|
1586 { |
|
1587 case EWsDebugPlacedConfig: |
|
1588 return DebugReturnConfig(aReplyBufSize, element, |
|
1589 placedElement->DebugFlags()); |
|
1590 case EWsDebugPlacedBase: |
|
1591 return DebugReturnBase(aReplyBufSize, element); |
|
1592 case EWsDebugPlacedFlags: |
|
1593 return DebugReturnFlags(aReplyBufSize, element, |
|
1594 placedElement->DebugFlags()); |
|
1595 default: |
|
1596 return KErrNotSupported; |
|
1597 } |
|
1598 } |
|
1599 |
|
1600 /** Returns a filled in TSurfaceConfiguration from an MWsElement. |
|
1601 * Data is usually copied if the buffer is big enough |
|
1602 * @return the size of buffer required, or zero if the buffer is acceptable |
|
1603 **/ |
|
1604 TInt CWsClient::DebugReturnConfig(TInt aReplyBufSize, MWsElement* aElement, TInt /*aFlags*/) const |
|
1605 { |
|
1606 if (aElement == NULL) |
|
1607 { |
|
1608 return KErrNotReady; |
|
1609 } |
|
1610 |
|
1611 TSurfaceConfiguration config(aReplyBufSize); |
|
1612 TInt retVal=config.Size(); |
|
1613 if (aReplyBufSize) |
|
1614 { |
|
1615 retVal = CWindowElementSet::GetConfiguration(config, *aElement); |
|
1616 if (retVal==KErrNone) |
|
1617 { |
|
1618 ReplyBuf(&config, config.Size()); //return code is 0 = "just right" |
|
1619 } |
|
1620 } |
|
1621 return retVal; |
|
1622 } |
|
1623 |
|
1624 /** Returns the base region of the element. |
|
1625 * This region is element relative. There are a number of ways that this does not match the input region: |
|
1626 * First, if no region is specified then the extent rectangle is returned |
|
1627 * Any region returned has all negative ordinate values clipped. |
|
1628 * Positive values may exceed the extent, but negative values are never returned. |
|
1629 * Internally, a region which is only negative is "remembered illegally", but an empty region is returned. |
|
1630 **/ |
|
1631 TInt CWsClient::DebugReturnBase(TInt /*aReplyBufSize*/, const MWsElement* /*aElement*/)const |
|
1632 { |
|
1633 return KErrNotSupported; |
|
1634 } |
|
1635 |
|
1636 /** Returns the flags associated with the given element. |
|
1637 * 2 words are inserted. |
|
1638 * One represents the MWsElement flags, the other represents CWindowElement or UIElement flags |
|
1639 * @return length of two words |
|
1640 **/ |
|
1641 TInt CWsClient::DebugReturnFlags(TInt aReplyBufSize, const MWsElement* /*aElement*/, TInt aFlags)const |
|
1642 { |
|
1643 const TInt KArraySize=2; |
|
1644 if (aReplyBufSize>KArraySize*sizeof(TInt)) |
|
1645 { |
|
1646 // First field is for flags from scene element if any |
|
1647 TInt returns[KArraySize]= |
|
1648 { |
|
1649 0, aFlags |
|
1650 }; |
|
1651 ReplyBuf(returns,KArraySize*sizeof(TInt)); |
|
1652 } |
|
1653 return KArraySize*sizeof(TInt); |
|
1654 } |
|
1655 |
|
1656 /** Packages a region for return ans an array of rectangles. |
|
1657 * If the buffer is big enough the data is transferred |
|
1658 * @return the buffer size required, or an error code if an empty or null pointer is passed in |
|
1659 **/ |
|
1660 TInt CWsClient::DebugReturnRegion(TInt aReplyBufSize, const TRegion* aRegion, TInt aErrCodeIfEmpty)const |
|
1661 { |
|
1662 if (aRegion==NULL) |
|
1663 return KErrNotReady; |
|
1664 |
|
1665 const TInt returnSize=aRegion->Count()*sizeof(TRect); |
|
1666 if (returnSize==0) |
|
1667 return aErrCodeIfEmpty; |
|
1668 |
|
1669 if (returnSize<=aReplyBufSize) |
|
1670 ReplyBuf(aRegion->RectangleList(),returnSize); |
|
1671 |
|
1672 return returnSize; |
|
1673 } |
|
1674 |
|
1675 void CWsClient::ReplyGroupName(HBufC* aName, TInt aMaxLength) // static |
|
1676 { |
|
1677 if (aName) |
|
1678 { |
|
1679 if (aName->Length()>aMaxLength) |
|
1680 { |
|
1681 ReplyBuf(aName->Left(aMaxLength)); |
|
1682 SetReply(KErrOverflow); |
|
1683 } |
|
1684 else |
|
1685 ReplyBuf(*aName); |
|
1686 } |
|
1687 else |
|
1688 ReplyBuf(KNullDesC); |
|
1689 } |
|
1690 |
|
1691 void CWsClient::TriggerRedraw() |
|
1692 { |
|
1693 RedrawQueue()->TriggerRedraw(); |
|
1694 } |
|
1695 |
|
1696 void CWsClient::UpdateWindowOrdinalPrioritys() |
|
1697 { |
|
1698 for(CWsWindowGroup* win=iScreen->RootWindow()->Child();win;win=win->NextSibling()) |
|
1699 { |
|
1700 if (win->WsOwner()==this) |
|
1701 win->UpdateOrdinalPriority(ETrue); |
|
1702 } |
|
1703 } |
|
1704 |
|
1705 void CWsClient::DeleteSystemPointerListEntry(TInt aIndex) |
|
1706 { |
|
1707 PointerCursor (aIndex)->Close(); |
|
1708 iSystemPointerCursors->Delete(aIndex); |
|
1709 } |
|
1710 |
|
1711 CWsPointerCursor* CWsClient::SystemPointerCursor(TInt aIndex) |
|
1712 { |
|
1713 TInt arrayIndex; |
|
1714 if (iSystemPointerCursors) |
|
1715 { |
|
1716 if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex)) |
|
1717 return PointerCursor(arrayIndex); |
|
1718 |
|
1719 // Cursor not defined so try for default cursor |
|
1720 if (FindCursorArrayItem(iSystemPointerCursors, 0, arrayIndex)) |
|
1721 return PointerCursor(arrayIndex); |
|
1722 } |
|
1723 |
|
1724 // If that fails simply return NULL for no cursor |
|
1725 return NULL; |
|
1726 } |
|
1727 |
|
1728 void CWsClient::SetSystemPointerCursorL(TInt aIndex, CWsPointerCursor* aCursor) |
|
1729 { |
|
1730 if (iSystemPointerCursorListOwner!=this) |
|
1731 PPanic(EWservPanicNotSystemPointerCursorListOwner); |
|
1732 |
|
1733 TInt arrayIndex = KErrNotFound; |
|
1734 if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex)) |
|
1735 { |
|
1736 PointerCursor(arrayIndex)->Close(); |
|
1737 PointerCursor(arrayIndex) = aCursor; |
|
1738 } |
|
1739 else |
|
1740 { |
|
1741 TWsCursorArrayItem entry; |
|
1742 entry.iIndex=aIndex; |
|
1743 entry.iCursor=aCursor; |
|
1744 iSystemPointerCursors->InsertIsqL(entry, iCursorKey); |
|
1745 } |
|
1746 |
|
1747 aCursor->Open(); |
|
1748 if (aIndex==iDefaultSystemPointerCursorIndex) |
|
1749 iDefaultSystemPointerCursor=aCursor; |
|
1750 TWsPointer::UpdatePointerCursor(); |
|
1751 } |
|
1752 |
|
1753 void CWsClient::ClearSystemPointerCursor(TInt aIndex) |
|
1754 { |
|
1755 if (iSystemPointerCursorListOwner!=this) |
|
1756 PPanic(EWservPanicNotSystemPointerCursorListOwner); |
|
1757 |
|
1758 TInt arrayIndex; |
|
1759 if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex)) |
|
1760 { |
|
1761 DeleteSystemPointerListEntry(arrayIndex); |
|
1762 if (aIndex==iDefaultSystemPointerCursorIndex) |
|
1763 iDefaultSystemPointerCursor=NULL; |
|
1764 } |
|
1765 } |
|
1766 |
|
1767 void CWsClient::ClaimSystemPointerCursorListL() |
|
1768 { |
|
1769 if (iSystemPointerCursorListOwner) |
|
1770 User::Leave(KErrInUse); |
|
1771 |
|
1772 const TInt systemPointerCursorGranularity = 4; |
|
1773 iSystemPointerCursors = new(ELeave) CArrayFixFlat<TWsCursorArrayItem> (systemPointerCursorGranularity); |
|
1774 iSystemPointerCursorListOwner=this; |
|
1775 } |
|
1776 |
|
1777 void CWsClient::FreeSystemPointerCursorList() |
|
1778 { |
|
1779 if(iSystemPointerCursorListOwner == this) |
|
1780 { |
|
1781 iSystemPointerCursorListOwner = NULL; |
|
1782 |
|
1783 while(iSystemPointerCursors->Count()>0) |
|
1784 DeleteSystemPointerListEntry(0); |
|
1785 |
|
1786 iDefaultSystemPointerCursor = NULL; |
|
1787 iDefaultSystemPointerCursorIndex = 0; |
|
1788 |
|
1789 delete iSystemPointerCursors; |
|
1790 iSystemPointerCursors = NULL; |
|
1791 } |
|
1792 } |
|
1793 |
|
1794 void CWsClient::SetDefaultSystemPointerCursor(TInt aIndex) |
|
1795 { |
|
1796 TInt arrayIndex; |
|
1797 if (iSystemPointerCursorListOwner != this) |
|
1798 PPanic(EWservPanicNotSystemPointerCursorListOwner); |
|
1799 |
|
1800 iDefaultSystemPointerCursorIndex = aIndex; |
|
1801 iDefaultSystemPointerCursor = NULL; |
|
1802 |
|
1803 if (aIndex != ENoDefaultSystemPointerCursor && |
|
1804 FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex)) |
|
1805 iDefaultSystemPointerCursor = PointerCursor (arrayIndex); |
|
1806 else |
|
1807 iDefaultSystemPointerCursor = NULL; |
|
1808 |
|
1809 TWsPointer::UpdatePointerCursor(); |
|
1810 } |
|
1811 |
|
1812 TBool CWsClient::FindCursorArrayItem(CArrayFixFlat<TWsCursorArrayItem>* aCursorArray, |
|
1813 TInt aIndex,TInt& aPosition) |
|
1814 { |
|
1815 if (!aCursorArray) |
|
1816 return EFalse; // No hit if the array isn't even allocated |
|
1817 |
|
1818 TWsCursorArrayItem entry; |
|
1819 entry.iIndex = aIndex; |
|
1820 return aCursorArray->FindIsq(entry, iCursorKey, aPosition)==KErrNone; |
|
1821 } |
|
1822 |
|
1823 void CWsClient::SetClientPriority() |
|
1824 { |
|
1825 if (iComputeMode!=RWsSession::EPriorityControlDisabled) |
|
1826 { |
|
1827 Client().SetProcessPriority( |
|
1828 iComputeMode==RWsSession::EPriorityControlComputeOn |
|
1829 || CWsTop::FocusWindowGroupOwner()!=this |
|
1830 ? EPriorityBackground |
|
1831 : EPriorityForeground); |
|
1832 } |
|
1833 } |
|
1834 |
|
1835 void CWsClient::SetComputeMode(RWsSession::TComputeMode aComputeMode) |
|
1836 { |
|
1837 if (aComputeMode!=RWsSession::EPriorityControlDisabled |
|
1838 && aComputeMode !=RWsSession::EPriorityControlComputeOn |
|
1839 && aComputeMode !=RWsSession::EPriorityControlComputeOff) |
|
1840 PPanic(EWservPanicSetComputeMode); |
|
1841 iComputeMode=aComputeMode; |
|
1842 SetClientPriority(); |
|
1843 } |
|
1844 |
|
1845 void CWsClient::CompleteMessage(const RMessage2& aMessage,TInt aReason) |
|
1846 { |
|
1847 WS_ASSERT_DEBUG(!aMessage.IsNull(),EWsPanicPanicFlagError); |
|
1848 if (iInternalFlags&EPanicClientAsSoonAsPossible) |
|
1849 { |
|
1850 aMessage.Panic(KWSERVSessionPanicCategory,iPanicReason); |
|
1851 iInternalFlags&=~EPanicClientAsSoonAsPossible; |
|
1852 } |
|
1853 else |
|
1854 { |
|
1855 if(!iResponseHandle) |
|
1856 aMessage.Complete(aReason); |
|
1857 else |
|
1858 { |
|
1859 aMessage.Complete(*iResponseHandle); |
|
1860 iResponseHandle=NULL; |
|
1861 } |
|
1862 } |
|
1863 } |
|
1864 |
|
1865 void CWsClient::ServiceError(const RMessage2& /*aMessage*/,TInt aError) |
|
1866 { |
|
1867 CompleteMessage(iClientMessage,aError); // (finish) |
|
1868 } |
|
1869 |
|
1870 void CWsClient::ServiceL(const RMessage2 &aMessage) // (step ##1) |
|
1871 // |
|
1872 // Handle messages for the window server server. |
|
1873 // |
|
1874 { |
|
1875 iClientMessage=aMessage; // from now on use always the message stored in the session |
|
1876 if (iInternalFlags&EPanicClientAsSoonAsPossible) |
|
1877 { |
|
1878 iClientMessage.Panic(KWSERVSessionPanicCategory,iPanicReason); |
|
1879 } |
|
1880 else |
|
1881 { |
|
1882 iPanicReason=KErrNone; |
|
1883 iReply=KErrNone; |
|
1884 TBool completeRequest=ETrue; |
|
1885 DoServiceL(iClientMessage, completeRequest); // (call #2) |
|
1886 if (completeRequest) |
|
1887 CompleteMessage(iClientMessage,iReply); // (finish) |
|
1888 } |
|
1889 } |
|
1890 |
|
1891 void CWsClient::SetResponseHandle(RHandleBase* aHandle) |
|
1892 { |
|
1893 iResponseHandle = aHandle; |
|
1894 } |
|
1895 |
|
1896 void CWsClient::DoServiceL(const RMessage2& aMessage, TBool& aCompleteRequest) // (step #2) |
|
1897 { |
|
1898 if (aMessage.IsNull()) |
|
1899 PPanic(EWservPanicNullMessageFromClient); |
|
1900 |
|
1901 WS_ASSERT_DEBUG(iInternalFlags&EFinishedProcessingCommands,EWsPanicCommandBufferStillBeingProcessed); |
|
1902 |
|
1903 const TInt function = aMessage.Function(); |
|
1904 switch (function) |
|
1905 { |
|
1906 case EWservMessInit: |
|
1907 StartInitializationL(iConnectionId++); |
|
1908 break; |
|
1909 case EWservMessSyncMsgBuf: |
|
1910 case EWservMessCommandBuffer: // Process command buffer containing draw ops |
|
1911 { |
|
1912 if (!IsInitialised()) |
|
1913 PPanic(EWservPanicUninitialisedClient); |
|
1914 |
|
1915 const TInt err = aMessage.Read(KBufferMessageSlot, iCmdBuf); |
|
1916 if (!err) |
|
1917 { |
|
1918 iReplyOffset=0; |
|
1919 iDestObj=NULL; |
|
1920 iNextCmd=iCmdBuf.Ptr(); |
|
1921 DoServiceCommandBuf(); // (call #3.1) |
|
1922 } |
|
1923 else if (err!=KErrDied) |
|
1924 PPanic(EWservPanicDescriptor); |
|
1925 |
|
1926 if(function == EWservMessCommandBuffer && CWsTop::FinishEveryFlush()) |
|
1927 Screen()->DoRedrawNow(); |
|
1928 else |
|
1929 aCompleteRequest=EFalse; |
|
1930 } |
|
1931 break; |
|
1932 case EWservMessShutdown: |
|
1933 { |
|
1934 if(!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for EWservMessShutdown message "))) |
|
1935 PPanic(EWservPanicPermissionDenied); |
|
1936 |
|
1937 if (aMessage.Int0() == EWservShutdownCheck) |
|
1938 CWsTop::Exit(); |
|
1939 else |
|
1940 PPanic(EWservPanicHandle); |
|
1941 } |
|
1942 break; |
|
1943 case EWservMessFinish: |
|
1944 Screen()->DoRedrawNow(); |
|
1945 break; |
|
1946 default: |
|
1947 if (function&EWservMessAsynchronousService) |
|
1948 { |
|
1949 TRAPD(err, ExecuteAsyncClientCommandL((function&~EWservMessAsynchronousService), aMessage)); // (call #3.2) |
|
1950 aCompleteRequest = (err!=KErrNone); |
|
1951 WS_ASSERT_DEBUG((!(iInternalFlags&EPanicClientAsSoonAsPossible))==(!aCompleteRequest), EWsPanicPanicFlagError); |
|
1952 } |
|
1953 else if (function&EWservMessAnimDllAsyncCommand) |
|
1954 { |
|
1955 CWsAnimDll* const animDll = static_cast<CWsAnimDll*>(HandleToObj(aMessage.Int0(), WS_HANDLE_ANIM_DLL)); |
|
1956 if (!animDll) |
|
1957 { |
|
1958 SessionPanic(EWservPanicHandle); |
|
1959 break; |
|
1960 } |
|
1961 |
|
1962 // it looks wrong to call CommandReply here (not AsyncCommandReply, or something, which doesn't exist), but basically, we can't add a virtual AsyncCommandReplyL to CAnim to correspond to RAnim::AsyncCommandReply as that would break binary and source compatibility for Anim plug-ins; instead asynchronous commands are done by the plug-in having to complete the RMessagePtr2 returned by iFunctions->Message() (or a copy of of that object) for asynchronous commands only |
|
1963 TRAPD(err, animDll->AnimObjectL(aMessage.Int1())->CommandReply(function&~EWservMessAnimDllAsyncCommand,NULL)); |
|
1964 aCompleteRequest=(err!=KErrNone); |
|
1965 WS_ASSERT_DEBUG((!(iInternalFlags&EPanicClientAsSoonAsPossible))==(!aCompleteRequest), EWsPanicPanicFlagError); |
|
1966 } |
|
1967 else |
|
1968 SetReply(KErrNotSupported); |
|
1969 } |
|
1970 } |
|
1971 void CWsClient::RemoteRead(TDes16& aDes, TInt aOffset) |
|
1972 { |
|
1973 if (iClientMessage.Read(KRemoteBufferMessageSlot,aDes,aOffset)!=KErrNone) |
|
1974 SessionPanic(EWservPanicDescriptor); |
|
1975 } |
|
1976 |
|
1977 void CWsClient::RemoteRead(TDes8& aDes, TInt aOffset) |
|
1978 { |
|
1979 if (iClientMessage.Read(KRemoteBufferMessageSlot,aDes,aOffset)!=KErrNone) |
|
1980 SessionPanic(EWservPanicDescriptor); |
|
1981 } |
|
1982 |
|
1983 void CWsClient::RemoteReadL(TDes16& aDes, TInt aOffset) |
|
1984 { |
|
1985 iClientMessage.ReadL(KRemoteBufferMessageSlot,aDes,aOffset); |
|
1986 } |
|
1987 |
|
1988 void CWsClient::RemoteReadL(TDes8& aDes, TInt aOffset) |
|
1989 { |
|
1990 iClientMessage.ReadL(KRemoteBufferMessageSlot,aDes,aOffset); |
|
1991 } |
|
1992 |
|
1993 void CWsClient::InitStaticsL() |
|
1994 { |
|
1995 iMoreCommands=CIdle::NewL(EClientBufferPriority); |
|
1996 } |
|
1997 |
|
1998 void CWsClient::DeleteStatics() |
|
1999 { |
|
2000 if (iTextCursorArray) |
|
2001 { |
|
2002 const TInt count = iTextCursorArray->Count(); |
|
2003 for (TInt index=0;index<count;index++) |
|
2004 delete iTextCursorArray->At(index).iCursor; |
|
2005 |
|
2006 delete iTextCursorArray; |
|
2007 iTextCursorArray = NULL; |
|
2008 } |
|
2009 |
|
2010 delete iMoreCommands; |
|
2011 iMoreCommands=NULL; |
|
2012 // coverity[extend_simple_error] |
|
2013 } |
|
2014 |
|
2015 /* CWsClient implementing MWsClient */ |
|
2016 |
|
2017 TBool CWsClient::HasCapability(TCapability aCapability) const |
|
2018 { |
|
2019 return iClient.HasCapability(aCapability); |
|
2020 } |
|
2021 |
|
2022 TSecureId CWsClient::SecureId() const |
|
2023 { |
|
2024 return iClient.SecureId(); |
|
2025 } |
|
2026 |
|
2027 TVendorId CWsClient::VendorId() const |
|
2028 { |
|
2029 return iClient.VendorId(); |
|
2030 } |
|
2031 |
|
2032 /** |
|
2033 Makes a new copy of the aData. so it could be deleted after this call. |
|
2034 */ |
|
2035 TInt CWsClient::SendMessage(const CWsGraphicDrawer* aOnBehalfOf,const TDesC8& aData) |
|
2036 { |
|
2037 CWsGraphicMessageQueue::CMessage* msg = CWsGraphicMessageQueue::CMessage::New(aData); |
|
2038 if(msg) |
|
2039 return SendMessage(aOnBehalfOf, *msg); |
|
2040 |
|
2041 return KErrGeneral; |
|
2042 } |
|
2043 |
|
2044 /** adds a message to the message queue |
|
2045 @return a postive number to uniquely identify the message |
|
2046 */ |
|
2047 TInt CWsClient::SendMessage(const CWsGraphicDrawer* aOnBehalfOf,CWsMessageData& aData) |
|
2048 { |
|
2049 WS_ASSERT_DEBUG(aData.Data().Size(), EWsPanicWsGraphic); |
|
2050 const CWsGraphicDrawerObject* obj = DrawerObject(aOnBehalfOf); |
|
2051 WS_ASSERT_DEBUG(obj, EWsPanicWsGraphic); |
|
2052 if(obj) |
|
2053 { |
|
2054 // assign message id |
|
2055 if(iMessageIdSeq == KMaxTInt) // Wrap if iMessageIdSeq has reached KMaxTInt |
|
2056 iMessageIdSeq = 0; |
|
2057 |
|
2058 iMessageIdSeq++; |
|
2059 // correct other handles |
|
2060 aData.iClientHandle = (obj->ClientHandle() | (EWsGraphMessageTypeUser & 0x03)); |
|
2061 aData.iDrawer = obj->Drawer(); |
|
2062 aData.iId = iMessageIdSeq; |
|
2063 iGraphicMessageQueue.Queue(&aData); |
|
2064 return iMessageIdSeq; |
|
2065 } |
|
2066 |
|
2067 return KErrGeneral; |
|
2068 } |
|
2069 |
|
2070 |
|
2071 CWsGraphicDrawerObject* CWsClient::DrawerObject(const CWsGraphicDrawer* aDrawer) |
|
2072 { |
|
2073 const TInt count = ObjectIndex()->Length(); |
|
2074 for(TInt i=0; i<count; i++) |
|
2075 { |
|
2076 CWsObject* obj = const_cast<CWsObject*>(ObjectIndex()->At(i)); |
|
2077 if(obj && (WS_HANDLE_GRAPHIC_DRAWER == obj->Type())) |
|
2078 { |
|
2079 CWsGraphicDrawerObject* candidate = static_cast<CWsGraphicDrawerObject*>(obj); |
|
2080 if(candidate->Drawer() == aDrawer) |
|
2081 return candidate; |
|
2082 } |
|
2083 } |
|
2084 |
|
2085 return NULL; |
|
2086 } |
|
2087 |
|
2088 const CWsGraphicDrawerObject* CWsClient::DrawerObject(const CWsGraphicDrawer* aDrawer) const |
|
2089 { |
|
2090 CWsObjectIx* objectIndex = const_cast<CWsClient*>(this)->ObjectIndex(); |
|
2091 const TInt count = objectIndex->Length(); |
|
2092 for(TInt i=0; i<count; i++) |
|
2093 { |
|
2094 CWsObject* obj = const_cast<CWsObject*>(objectIndex->At(i)); |
|
2095 if(obj && (WS_HANDLE_GRAPHIC_DRAWER == obj->Type())) |
|
2096 { |
|
2097 const CWsGraphicDrawerObject* candidate = static_cast<CWsGraphicDrawerObject*>(obj); |
|
2098 if(candidate->Drawer() == aDrawer) |
|
2099 return candidate; |
|
2100 } |
|
2101 } |
|
2102 |
|
2103 return NULL; |
|
2104 } |
|
2105 |
|
2106 TInt CWsClient::RegisterSurface(const TWsClCmdUnion& pData) |
|
2107 { |
|
2108 TInt screenNumber = pData.SurfaceRegister->screenNumber; |
|
2109 if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens()) |
|
2110 { |
|
2111 PPanic(EWservPanicScreenNumber); |
|
2112 } |
|
2113 if (pData.SurfaceRegister->surfaceId.Type() == TSurfaceId::EScreenSurface |
|
2114 || pData.SurfaceRegister->surfaceId.IsNull()) |
|
2115 { |
|
2116 PPanic(EWservPanicInvalidSurface); |
|
2117 } |
|
2118 |
|
2119 CRegisteredSurfaceMap* surfaceMap = CWsTop::Screen(screenNumber)->SurfaceMap(); |
|
2120 const TSurfaceId& surfaceId = pData.SurfaceRegister->surfaceId; |
|
2121 TInt err = surfaceMap->Add(*this,surfaceId); |
|
2122 |
|
2123 switch(err) |
|
2124 { |
|
2125 case KErrNone: |
|
2126 case KErrNoMemory: |
|
2127 case KErrInUse: |
|
2128 case KErrArgument: |
|
2129 break; |
|
2130 default: |
|
2131 PPanic(EWservPanicInvalidSurface); |
|
2132 } |
|
2133 return err; |
|
2134 } |
|
2135 |
|
2136 void CWsClient::UnregisterSurface(const TWsClCmdUnion& pData) |
|
2137 { |
|
2138 TInt screenNumber = pData.SurfaceRegister->screenNumber; |
|
2139 if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens()) |
|
2140 { |
|
2141 PPanic(EWservPanicScreenNumber); |
|
2142 } |
|
2143 TInt err = CWsTop::Screen(screenNumber)->SurfaceMap()->Remove(*this,pData.SurfaceRegister->surfaceId); |
|
2144 WS_ASSERT_DEBUG((err==KErrNone||err==KErrNotFound), EWsPanicSurfaceMapError); |
|
2145 } |
|
2146 |
|
2147 void CWsClient::CreateDrawableSourceL(const TWsClCmdCreateDrawableSource& aDrawableSourceData) |
|
2148 { |
|
2149 CWsDrawableSource* drawableSource = new(ELeave) CWsDrawableSource(this); |
|
2150 CleanupStack::PushL(drawableSource); |
|
2151 drawableSource->ConstructL(aDrawableSourceData); |
|
2152 CleanupStack::Pop(); |
|
2153 } |
|
2154 |
|
2155 // |
|
2156 // class CWsCliObj |
|
2157 // |
|
2158 |
|
2159 CWsCliObj* CWsCliObj::NewL(CWsClient* aOwner) |
|
2160 { |
|
2161 CWsCliObj* self = new(ELeave) CWsCliObj(aOwner); |
|
2162 CleanupStack::PushL(self); |
|
2163 self->ConstructL(); |
|
2164 CleanupStack::Pop(self); |
|
2165 return self; |
|
2166 } |
|
2167 |
|
2168 CWsCliObj::CWsCliObj(CWsClient *aOwner) : |
|
2169 CWsObject(aOwner, WS_HANDLE_CLIENT) |
|
2170 { |
|
2171 } |
|
2172 |
|
2173 void CWsCliObj::ConstructL() |
|
2174 { |
|
2175 NewObjL(); |
|
2176 } |
|
2177 |
|
2178 void CWsCliObj::CommandL(TInt aOpcode, const TAny* aCmdData) // (step #5) |
|
2179 { |
|
2180 iWsOwner->ExecuteCommandL(aOpcode,aCmdData); // (call #6) |
|
2181 } |
|
2182 |
|
2183 CWsObject* CWsClient::HandleToObjUntyped(TInt aHandle) |
|
2184 { |
|
2185 return iObjectIndex->HandleToObject(aHandle); |
|
2186 } |
|
2187 |
|
2188 const CWsObject* CWsClient::HandleToObjUntyped(TInt aHandle) const |
|
2189 { |
|
2190 return const_cast<CWsClient*>(this)->HandleToObjUntyped(aHandle); |
|
2191 } |
|
2192 |
|
2193 CWsObject* CWsClient::HandleToObj(TInt aHandle, WH_HANDLES aType) |
|
2194 { |
|
2195 CWsObject* object = HandleToObjUntyped(aHandle); |
|
2196 return (object && object->Type() == aType) ? object : NULL; |
|
2197 } |
|
2198 |
|
2199 |
|
2200 const CWsObject* CWsClient::HandleToObj(TInt aHandle, WH_HANDLES aType) const |
|
2201 { |
|
2202 return const_cast<CWsClient*>(this)->HandleToObj(aHandle, aType); |
|
2203 } |
|
2204 |
|
2205 void CWsClient::SetRetryFlag(TEventCode aEventCode) |
|
2206 { |
|
2207 switch(aEventCode) |
|
2208 { |
|
2209 //To be expanded |
|
2210 case EEventDisplayChanged: |
|
2211 { |
|
2212 iInternalFlags |= ERetryDisplayEvent; |
|
2213 } |
|
2214 break; |
|
2215 |
|
2216 } |
|
2217 } |
|
2218 TBool CWsClient::RetryEvent(TEventCode aEventCode) |
|
2219 { |
|
2220 switch(aEventCode) |
|
2221 {//To be expanded |
|
2222 case EEventDisplayChanged: |
|
2223 { |
|
2224 return (iInternalFlags & ERetryDisplayEvent); |
|
2225 } |
|
2226 } |
|
2227 return EFalse; |
|
2228 } |
|
2229 |
|
2230 void CWsClient::RemoveRetryFlag(TEventCode aEventCode) |
|
2231 { |
|
2232 switch(aEventCode) |
|
2233 {//To be expanded |
|
2234 case EEventDisplayChanged: |
|
2235 { |
|
2236 iInternalFlags &= ~ERetryDisplayEvent; |
|
2237 } |
|
2238 break; |
|
2239 } |
|
2240 } |
|
2241 |