|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <fbs.h> |
|
17 #include "fbsdefs.h" |
|
18 #include "UTILS.H" |
|
19 #include "FBSVER.H" |
|
20 #include "FbsRalc.h" |
|
21 #include "fbshelper.h" |
|
22 #include "fbsmessage.h" |
|
23 |
|
24 GLDEF_C void Panic(TFbsPanic aPanic) |
|
25 { |
|
26 _LIT(KFBSERVClientPanicCategory,"FBSCLI"); |
|
27 User::Panic(KFBSERVClientPanicCategory,aPanic); |
|
28 } |
|
29 |
|
30 EXPORT_C TInt FbsStartup() |
|
31 { |
|
32 RChunk sharedchunk; |
|
33 TInt ret = sharedchunk.OpenGlobal(KFBSERVSharedChunkName,EFalse); |
|
34 if (ret == KErrNone) |
|
35 { |
|
36 sharedchunk.Close(); |
|
37 return KErrNone; |
|
38 } |
|
39 |
|
40 RProcess fbs; |
|
41 _LIT(KFBSERVServerExe,"z:\\sys\\bin\\fbserv.exe"); |
|
42 ret = fbs.Create(KFBSERVServerExe,KNullDesC); |
|
43 |
|
44 if (ret!=KErrNone) |
|
45 return ret; |
|
46 |
|
47 |
|
48 TRequestStatus stat; |
|
49 fbs.Rendezvous(stat); |
|
50 if (stat!=KRequestPending) |
|
51 fbs.Kill(0); // abort startup |
|
52 else |
|
53 fbs.Resume(); // logon OK - start the server |
|
54 User::WaitForRequest(stat); // wait for start or death |
|
55 // we can't use the 'exit reason' if the server panicked as this |
|
56 // is the panic 'reason' and may be '0' which cannot be distinguished |
|
57 // from KErrNone |
|
58 ret=(fbs.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); |
|
59 fbs.Close(); |
|
60 return ret; |
|
61 } |
|
62 |
|
63 |
|
64 // |
|
65 // Fontbitmap server client side session |
|
66 // |
|
67 |
|
68 /** |
|
69 @publishedAll |
|
70 @released |
|
71 */ |
|
72 EXPORT_C RFbsSession::RFbsSession(): |
|
73 RSessionBase(), |
|
74 iConnections(0), |
|
75 iCallBack(), |
|
76 iSharedChunk(), |
|
77 iHelper(NULL), |
|
78 iRomFileAddrCache(NULL), |
|
79 iDecompressionBuffer(NULL), |
|
80 iScanLineBuffer(NULL), |
|
81 iSpare(NULL) |
|
82 {} |
|
83 |
|
84 /** Creates a session with the Font and Bitmap server. |
|
85 @param aFileServer A fuly constructed file server session |
|
86 @return KErrNone, if successful; KErrNoMemory if there is not enough memory |
|
87 to create the session; otherwise another of the system-wide error codes. |
|
88 @publishedAll |
|
89 @released |
|
90 */ |
|
91 EXPORT_C TInt RFbsSession::Connect(RFs& aFileServer) |
|
92 { |
|
93 RFbsSession* thisptr = (RFbsSession*)Dll::Tls(); |
|
94 if(thisptr) |
|
95 { |
|
96 thisptr->iConnections++; |
|
97 return KErrNone; |
|
98 } |
|
99 TInt ret = RFbsSession::DoAlloc(thisptr); |
|
100 if(ret!=KErrNone) |
|
101 return ret; |
|
102 return thisptr->DoConnect(aFileServer); |
|
103 } |
|
104 |
|
105 /** Creates a session with the Font and Bitmap server. |
|
106 @return KErrNone, if successful; KErrNoMemory if there is not enough memory |
|
107 to create the session; otherwise another of the system-wide error codes. |
|
108 @publishedAll |
|
109 @released |
|
110 */ |
|
111 EXPORT_C TInt RFbsSession::Connect() |
|
112 { |
|
113 RFbsSession* thisptr = (RFbsSession*)Dll::Tls(); |
|
114 if(thisptr) |
|
115 { |
|
116 thisptr->iConnections++; |
|
117 return KErrNone; |
|
118 } |
|
119 TInt ret = RFbsSession::DoAlloc(thisptr); |
|
120 if (ret!=KErrNone) |
|
121 return ret; |
|
122 ret = thisptr->iFileServer.Connect(); |
|
123 if(ret!=KErrNone) |
|
124 { |
|
125 thisptr->Disconnect(); |
|
126 return ret; |
|
127 } |
|
128 return thisptr->DoConnect(thisptr->iFileServer); |
|
129 } |
|
130 |
|
131 /** Closes the session with the Font and Bitmap server. |
|
132 @publishedAll |
|
133 @released |
|
134 */ |
|
135 EXPORT_C void RFbsSession::Disconnect() |
|
136 { |
|
137 RFbsSession* thisptr=(RFbsSession*)Dll::Tls(); |
|
138 if(thisptr==NULL) return; |
|
139 if(thisptr->iConnections>0) |
|
140 { |
|
141 thisptr->iCallBack.iPtr=NULL; |
|
142 thisptr->iCallBack.CallBack(); |
|
143 // Destructor of CFbsSessionHelper may call SendCommand to cancel an |
|
144 // outstanding request, therefore destruction must be done before |
|
145 // iConnections is 0 to avoid an assertion going off. |
|
146 if(thisptr->iConnections==1) |
|
147 { |
|
148 delete thisptr->iHelper; |
|
149 } |
|
150 thisptr->iConnections--; |
|
151 } |
|
152 if(thisptr->iConnections==0) |
|
153 { |
|
154 thisptr->iSharedChunk.Close(); |
|
155 thisptr->iLargeBitmapChunk.Close(); |
|
156 // Call close on the iFileServer regardless of whether this session owns it: |
|
157 // if we don't own it, close will do nothing if there are still open files, |
|
158 // so always calling close introduces extra safety |
|
159 thisptr->iFileServer.Close(); |
|
160 delete thisptr->iRomFileAddrCache; |
|
161 delete thisptr->iScanLineBuffer; |
|
162 delete thisptr->iDecompressionBuffer; |
|
163 thisptr->Close(); |
|
164 delete thisptr; |
|
165 Dll::FreeTls(); |
|
166 } |
|
167 } |
|
168 |
|
169 /** Gets the current Font and Bitmap server session. |
|
170 @return A pointer to the current session or NULL if Connect() has not been |
|
171 called yet. |
|
172 @publishedAll |
|
173 @released |
|
174 */ |
|
175 EXPORT_C RFbsSession* RFbsSession::GetSession() |
|
176 { |
|
177 return((RFbsSession*)Dll::Tls()); |
|
178 } |
|
179 |
|
180 /** Triggers the most recently registered callback. This is mainly called by |
|
181 bitmaps when their twips size changes and when any FBSERV objects are closed |
|
182 to notify clients of a change that may affect their operation. |
|
183 @publishedAll |
|
184 @released |
|
185 */ |
|
186 EXPORT_C void RFbsSession::CallBack() |
|
187 { |
|
188 iCallBack.CallBack(); |
|
189 iCallBack.iPtr=NULL; |
|
190 } |
|
191 |
|
192 void RFbsSession::SetCallBackPtr(TInt* aBitmapHandle)const |
|
193 { |
|
194 iCallBack.iPtr=aBitmapHandle; |
|
195 } |
|
196 |
|
197 /** Sets the callback. |
|
198 @param aCallBack callback object to be called by CallBack(). Only one may be |
|
199 in use at a time and subsequent calls will displace previous calls. |
|
200 @publishedAll |
|
201 @released |
|
202 */ |
|
203 EXPORT_C void RFbsSession::SetCallBack(TCallBack aCallBack) |
|
204 { |
|
205 iCallBack=aCallBack; |
|
206 } |
|
207 |
|
208 /** Resets the callback. |
|
209 @publishedAll |
|
210 @released |
|
211 */ |
|
212 EXPORT_C void RFbsSession::ResetCallBack() |
|
213 { |
|
214 TCallBack cb(NULL); |
|
215 iCallBack=cb; |
|
216 } |
|
217 |
|
218 /** Returns the number of Font and Bitmap Server objects currently in |
|
219 use by this session. |
|
220 @return The number of resources in use: bitmaps, fonts, typeface stores. |
|
221 @publishedAll |
|
222 @released |
|
223 */ |
|
224 EXPORT_C TInt RFbsSession::ResourceCount() |
|
225 { |
|
226 return(SendCommand(EFbsMessResourceCount)); |
|
227 } |
|
228 |
|
229 /** Utility function for passing commands to the server. |
|
230 @param aMessage Integer code for the message to pass - see TFbsMessage. |
|
231 @param aInt0 Parameter 0 for the message. |
|
232 @param aInt1 Parameter 1 for the message. |
|
233 @param aInt2 Parameter 2 for the message. |
|
234 @param aInt3 Parameter 3 for the message. |
|
235 @return Return code from RSessionBase::SendReceive(). |
|
236 @internalComponent |
|
237 */ |
|
238 EXPORT_C TInt RFbsSession::SendCommand(TInt aMessage,TInt aInt0,TInt aInt1,TInt aInt2,TInt aInt3) const |
|
239 { |
|
240 __ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection)); |
|
241 switch(aMessage) |
|
242 { |
|
243 case EFbsMessShutdown: |
|
244 case EFbsMessClose: |
|
245 SetCallBackPtr(aMessage==EFbsMessClose ? &aInt1 : 0); |
|
246 iCallBack.CallBack(); |
|
247 default: |
|
248 break; |
|
249 } |
|
250 TInt ret = SendReceive(aMessage, TIpcArgs(aInt0,aInt1,aInt2,aInt3)); |
|
251 return(ret); |
|
252 } |
|
253 |
|
254 TInt RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs) const |
|
255 { |
|
256 __ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection)); |
|
257 return SendReceive(aMessage,aArgs); |
|
258 } |
|
259 |
|
260 void RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs, TRequestStatus &aStatus) const |
|
261 { |
|
262 __ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection)); |
|
263 SendReceive(aMessage,aArgs,aStatus); |
|
264 } |
|
265 |
|
266 /** Gets the current Font and Bitmap server version. |
|
267 @return The current version of the server. |
|
268 @publishedAll |
|
269 @released |
|
270 */ |
|
271 EXPORT_C TVersion RFbsSession::Version() |
|
272 { |
|
273 TVersion v(KFbsMajorVersionNumber,KFbsMinorVersionNumber,KFbsBuildVersionNumber); |
|
274 return(v); |
|
275 } |
|
276 |
|
277 /** Gets the address of first location in the global shared heap containing |
|
278 fonts and bitmaps. |
|
279 @return Pointer to the base of the shared heap. |
|
280 @publishedAll |
|
281 @released |
|
282 */ |
|
283 EXPORT_C TUint8* RFbsSession::HeapBase() const |
|
284 { |
|
285 return(iSharedChunk.Base()); |
|
286 } |
|
287 |
|
288 TBool RFbsSession::LookupBitmapInROM(const TDesC& aFilename, TAny*& aAddr) |
|
289 { |
|
290 aAddr = iRomFileAddrCache->Lookup(aFilename); |
|
291 if (aAddr) |
|
292 return ETrue; |
|
293 return EFalse; |
|
294 } |
|
295 |
|
296 TInt RFbsSession::DoAlloc(RFbsSession*& aNewSession) |
|
297 { |
|
298 aNewSession = (RFbsSession*)User::Alloc(sizeof(RFbsSession)); |
|
299 if(!aNewSession) |
|
300 return KErrNoMemory; |
|
301 new(aNewSession) RFbsSession; |
|
302 aNewSession->iConnections = 1; |
|
303 TInt ret = Dll::SetTls(aNewSession); |
|
304 if(ret!=KErrNone) |
|
305 { |
|
306 delete aNewSession; |
|
307 aNewSession = NULL; |
|
308 } |
|
309 return ret; |
|
310 } |
|
311 |
|
312 /** |
|
313 Do actual connect as common to both Connect() and Connect(RFs& aFileServer). Store fully constructed |
|
314 file server session to iSpare member variable |
|
315 @see Connect() |
|
316 @return KErrNone, if successful; KErrNoMemory if there is not enough memory |
|
317 to create the session; otherwise another of the system-wide error codes. |
|
318 @internalComponent |
|
319 */ |
|
320 TInt RFbsSession::DoConnect(RFs& aFileServer) |
|
321 { |
|
322 //Allow this session to be accessed by other process to lead bitmap in server |
|
323 TInt ret = aFileServer.ShareProtected(); |
|
324 if (ret!=KErrNone) |
|
325 { |
|
326 Disconnect(); |
|
327 return ret; |
|
328 } |
|
329 iRomFileAddrCache = CFbsRalCache::New(4, aFileServer); |
|
330 if (!iRomFileAddrCache) |
|
331 { |
|
332 Disconnect(); |
|
333 return KErrNoMemory; |
|
334 } |
|
335 |
|
336 ret = CreateSession(KFBSERVGlobalThreadName,Version(),-1); |
|
337 if(ret!=KErrNone) |
|
338 { |
|
339 Disconnect(); |
|
340 return ret; |
|
341 } |
|
342 const TInt serverAssignedHandle = SendReceive(EFbsMessInit); |
|
343 if(serverAssignedHandle <= 0) |
|
344 { |
|
345 Disconnect(); |
|
346 return serverAssignedHandle; |
|
347 } |
|
348 ret = iSharedChunk.OpenGlobal(KFBSERVSharedChunkName,EFalse); |
|
349 if(ret!=KErrNone) |
|
350 Panic(EFbsPanicChunkError); |
|
351 iHelper = new CFbsSessionHelper(*this); |
|
352 if (!iHelper) |
|
353 { |
|
354 Disconnect(); |
|
355 return KErrNoMemory; |
|
356 } |
|
357 iHelper->iServerSessionHandle = serverAssignedHandle; |
|
358 ret = iLargeBitmapChunk.OpenGlobal(KFBSERVLargeChunkName,EFalse); |
|
359 if(ret!=KErrNone) |
|
360 Panic(EFbsPanicChunkError); |
|
361 |
|
362 iSpare = (TUint32*)&aFileServer; |
|
363 return KErrNone; |
|
364 } |
|
365 |
|
366 /** |
|
367 Allocates the buffer for decoding compressed rom bitmaps. |
|
368 |
|
369 Internal use only. |
|
370 |
|
371 @param aSize Minimum size of the buffer required. |
|
372 If the buffer is too small an attempt to resize it will be made. |
|
373 @return KErrNone if successful, |
|
374 KErrNoMemory if the buffer was too small and could |
|
375 not be expanded. |
|
376 @publishedAll |
|
377 @released |
|
378 */ |
|
379 TInt RFbsSession::AllocScanLineBuffer(TInt aSize) |
|
380 { |
|
381 if (iScanLineBuffer && iScanLineBuffer->Des().MaxSize() >= aSize) |
|
382 { |
|
383 return KErrNone; |
|
384 } |
|
385 |
|
386 HBufC8* newBuffer = HBufC8::New(aSize); |
|
387 |
|
388 if (newBuffer) |
|
389 { |
|
390 delete iScanLineBuffer; |
|
391 iScanLineBuffer = newBuffer; |
|
392 return KErrNone; |
|
393 } |
|
394 |
|
395 return KErrNoMemory; |
|
396 } |
|
397 |
|
398 /** |
|
399 Gets a reference to the buffer currently in use for decoding |
|
400 compressed rom bitmaps. |
|
401 |
|
402 Internal use only. |
|
403 |
|
404 @return The buffer area currently in use, |
|
405 @publishedAll |
|
406 @released |
|
407 */ |
|
408 HBufC8* RFbsSession::GetScanLineBuffer() |
|
409 { |
|
410 return iScanLineBuffer; |
|
411 } |
|
412 |
|
413 /** |
|
414 Gets a pointer to the buffer currently in use for decoding |
|
415 compressed mask bitmaps. |
|
416 |
|
417 Internal use only. |
|
418 @param aSize Minimum size of the buffer required. |
|
419 If the buffer is too small an attempt to resize it will be made. |
|
420 @return The buffer area currently in use or NULL if there is no memory. |
|
421 @internalComponent |
|
422 */ |
|
423 HBufC8* RFbsSession::GetDecompressionBuffer(TInt aSize) |
|
424 { |
|
425 if (iDecompressionBuffer) |
|
426 { |
|
427 if (iDecompressionBuffer->Des().MaxSize() < aSize) |
|
428 { |
|
429 HBufC8* tempBuffer = iDecompressionBuffer->ReAlloc(aSize); |
|
430 if (!tempBuffer) |
|
431 { |
|
432 return NULL; |
|
433 } |
|
434 iDecompressionBuffer = tempBuffer; |
|
435 } |
|
436 } |
|
437 else |
|
438 { |
|
439 iDecompressionBuffer = HBufC8::New(aSize); |
|
440 } |
|
441 |
|
442 return iDecompressionBuffer; |
|
443 } |
|
444 |
|
445 /** |
|
446 Gets a pointer to an extra buffer for general use. |
|
447 |
|
448 Internal use only. |
|
449 @param aSize Minimum size of the buffer required. |
|
450 If the buffer is too small an attempt to resize it will be made. |
|
451 @return The buffer area currently in use or NULL if there is no memory. |
|
452 @internalComponent |
|
453 */ |
|
454 HBufC8* RFbsSession::GetExtraBuffer(TInt aSize) |
|
455 { |
|
456 if (iHelper->iExtraBuffer) |
|
457 { |
|
458 if (iHelper->iExtraBuffer->Des().MaxSize() < aSize) |
|
459 { |
|
460 HBufC8* tempBuffer = iHelper->iExtraBuffer->ReAlloc(aSize); |
|
461 if (!tempBuffer) |
|
462 { |
|
463 return NULL; |
|
464 } |
|
465 iHelper->iExtraBuffer = tempBuffer; |
|
466 } |
|
467 } |
|
468 else |
|
469 { |
|
470 iHelper->iExtraBuffer = HBufC8::New(aSize); |
|
471 } |
|
472 |
|
473 return iHelper->iExtraBuffer; |
|
474 } |
|
475 |
|
476 /** |
|
477 Returns a handle assigned to this session by the server upon connection. |
|
478 This method should be used instead of SessionHandle() when passing a session |
|
479 handle to FbServ APIs that require Session handles. |
|
480 @return A handle representing this session on the server. |
|
481 @pre The session has successfully connected to the server. |
|
482 */ |
|
483 TInt RFbsSession::ServerSessionHandle() const |
|
484 { |
|
485 __ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection)); |
|
486 return iHelper->iServerSessionHandle; |
|
487 } |
|
488 |
|
489 /** |
|
490 Returns the current sizes of the FBServ default heap, the heap for large bitmaps, |
|
491 and the heap for small bitmaps. |
|
492 |
|
493 Not supported in release builds. |
|
494 |
|
495 @internalComponent |
|
496 @test |
|
497 @param aDefaultHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ default heap. |
|
498 @param aSmallBmpHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ heap for small bitmaps |
|
499 @param aBigBmpHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ heap for large bitmaps |
|
500 @return KErrNone or one of the system wide error codes in debug mode, or KErrNotSupported in release mode. |
|
501 */ |
|
502 #ifdef _DEBUG |
|
503 EXPORT_C TInt RFbsSession::GetHeapSizes(TInt& aDefaultHeapSize, TInt& aSmallBmpHeapSize, TInt& aBigBmpHeapSize) |
|
504 { |
|
505 TPckgBuf<THeapSizes> data; |
|
506 TIpcArgs args(&data); |
|
507 TInt ret = SendReceive(EFbsMessGetHeapSizes, args); |
|
508 if(ret == KErrNone) |
|
509 { |
|
510 aDefaultHeapSize = data().iDefault; |
|
511 aSmallBmpHeapSize = data().iSmall; |
|
512 aBigBmpHeapSize = data().iBig; |
|
513 } |
|
514 return ret; |
|
515 } |
|
516 #else |
|
517 EXPORT_C TInt RFbsSession::GetHeapSizes(TInt&, TInt&, TInt&) |
|
518 { |
|
519 return KErrNotSupported; |
|
520 } |
|
521 #endif |