📄 contextnotify.cpp
字号:
/*
002 Copyright (C) 2004 Mika Raento - Renaud Petit
003
004 This program is free software; you can redistribute it and/or modify
005 it under the terms of the GNU General Public License as published by
006 the Free Software Foundation; either version 2 of the License, or
007 (at your option) any later version.
008
009 This program is distributed in the hope that it will be useful,
010 but WITHOUT ANY WARRANTY; without even the implied warranty of
011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 GNU General Public License for more details.
013
014 You should have received a copy of the GNU General Public License
015 along with this program; if not, write to the Free Software
016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017
018
019 email: mraento@cs.helsinki.fi - petit@cs.helsinki.fi
020 */
021
022
023 //CContextNotify.cpp
024 #include "ContextNotify.h"
025 #include "ContextNotifySession.h"
026 #include "NotifyCommon.h"
027 #include <E32SVR.H>
028 #include <basched.h>
029
030 #include <flogger.h>
031
032 void Log(const TDesC& msg);
033
034 bool ClientAlive(TInt ThreadId);
035
036 #pragma warning(disable:4706)
037
038 CContextNotify::CContextNotify(TInt aPriority) : CServer(aPriority)
039 {
040
041 }
042
043 CContextNotify::~CContextNotify()
044 {
045 delete iForeground;
046 delete iDrawer;
047 if (ws_is_open) iWsSession.Close();
048 }
049
050 CContextNotify* CContextNotify::NewL()
051 {
052 CContextNotify* ContextNotifyer = CContextNotify::NewLC();
053 CleanupStack::Pop(ContextNotifyer);
054 return ContextNotifyer;
055 }
056
057 CContextNotify* CContextNotify::NewLC()
058 {
059 CContextNotify* ContextNotifyer = new (ELeave) CContextNotify(EPriorityNormal);
060 CleanupStack::PushL(ContextNotifyer);
061 ContextNotifyer->ConstructL();
062 return ContextNotifyer;
063 }
064
065 void CContextNotify::ConstructL()
066 {
067 User::LeaveIfError(iWsSession.Connect());
068 ws_is_open=true;
069 iDrawer=CDrawer::NewL(iWsSession);
070 iForeground=CForeground::NewL(iWsSession);
071 iForeground->AddObserver(iDrawer);
072
073 StartL(KContextNotifyName);
074 }
075
076 CSharableSession* CContextNotify::NewSessionL(const TVersion& aVersion) const
077 {
078 // check version
079 if (!User::QueryVersionSupported(TVersion(KContextNotifyMajorVersionNumber,
080 KContextNotifyMinorVersionNumber,
081 KContextNotifyBuildVersionNumber),
082 aVersion))
083 {
084 User::Leave(KErrNotSupported);
085 }
086
087 // create new session
088 RThread client = Message().Client();
089 return CContextNotifySession::NewL(client, *const_cast<CContextNotify*> (this));
090 }
091
092
093 void CContextNotify::IncrementSessions()
094 {
095 iSessionCount++;
096 }
097
098 void CContextNotify::DecrementSessions()
099 {
100 iSessionCount--;
101 if (iSessionCount <= 0)
102 {
103 iSessionCount =0;
104 CActiveScheduler::Stop();
105 }
106 }
107
108 TInt CContextNotify::CheckedRunError(TInt aError)
109 {
110 if (aError == KErrBadDescriptor)
111 {
112 // A bad descriptor error implies a badly programmed client, so panic it;
113 // otherwise report the error to the client
114 PanicClient(Message(), EBadDescriptor);
115 }
116 else
117 {
118 Message().Complete(aError);
119 }
120
121 //
122 // The leave will result in an early return from CServer::RunL(), skipping
123 // the call to request another message. So do that now in order to keep the
124 // server running.
125 ReStart();
126
127 return KErrNone; // handled the error fully
128 }
129
130 void CContextNotify::PanicClient(const RMessage& aMessage, TContextNotifyPanic aPanic)
131 {
132 aMessage.Panic(KContextNotify, aPanic);
133 }
134
135 void CContextNotify::PanicServer(TContextNotifyPanic aPanic)
136 {
137 User::Panic(KContextNotify, aPanic);
138 }
139
140 void CContextNotify::RunL()
141 {
142 TRAPD(err, CServer::RunL());
143 if (err!=KErrNone) {
144 TBuf<20> msg;
145 msg.Format(_L("Error in RunL: %d"), err);
146 Log(msg);
147 CheckedRunError(err);
148 }
149 }
150
151 void CContextNotify::ThreadFunctionL()
152 {
153 #if defined (__WINS__)
154 UserSvr::ServerStarted();
155 #endif
156
157 __UHEAP_MARK;
158
159 {
160 CActiveScheduler* activeScheduler = new (ELeave) CBaActiveScheduler;
161
162 CleanupStack::PushL(activeScheduler) ;
163
164 // Install active scheduler
165 // We don't need to check whether an active scheduler is already installed
166 // as this is a new thread, so there won't be one
167 CActiveScheduler::Install(activeScheduler);
168
169 // Construct our server
170 CContextNotify::NewLC();
171
172 RSemaphore semaphore;
173 if (semaphore.CreateGlobal(KContextNotifySemaphoreName, 0)!=KErrNone) {
174 User::LeaveIfError(semaphore.OpenGlobal(KContextNotifySemaphoreName));
175 }
176
177 // Semaphore opened ok
178 semaphore.Signal();
179 semaphore.Close();
180
181 // Start handling requests
182 CActiveScheduler::Start();
183 CleanupStack::PopAndDestroy(2); // CServer, activeScheduler,
184 }
185
186 __UHEAP_MARKEND;
187
188 }
189
190 TInt CContextNotify::ThreadFunction(TAny* /*aNone*/)
191 {
192 CTrapCleanup* cleanupStack = CTrapCleanup::New();
193 if (cleanupStack == NULL)
194 {
195 PanicServer(ECreateTrapCleanup);
196 }
197
198 TRAPD(err, ThreadFunctionL());
199 if (err != KErrNone)
200 {
201 PanicServer(ESrvCreateServer);
202 }
203
204 delete cleanupStack;
205 cleanupStack = NULL;
206
207 return KErrNone;
208 }
209
210
211 //---------------------------------------------------------------------------
212
213 void CContextNotify::TerminateContextNotify()
214 {
215 NotifySessions(ETerminated);
216 //Log();
217 CActiveScheduler::Stop();
218 }
219
220 void CContextNotify::NotifySessions(TEvent aEvent)
221 {
222 CContextNotifySession* session=0;
223
224 iSessionIter.SetToFirst();
225 while( (session = reinterpret_cast<CContextNotifySession*>(iSessionIter++)) ) {
226 session->NotifyEvent(aEvent);
227 }
228 }
229
230 void CContextNotify::ReportError(TContextNotifyRqstComplete aErrorType, TDesC & aErrorCode, TDesC & aErrorValue)
231 {
232 CContextNotifySession* session=0;
233
234 iSessionIter.SetToFirst();
235 while( (session = reinterpret_cast<CContextNotifySession*>(iSessionIter++)) ) {
236 session->ReportError(aErrorType, aErrorCode, aErrorValue);
237 }
238 }
239
240 void CContextNotify::CancelRequest(const RMessage &aMessage)
241 {
242 // there's nothing to cancel (at least yet)
243 switch(aMessage.Function()) {
244 default:
245 break;
246 }
247 }
248
249 TInt CContextNotify::AddIconL(TInt aIconHandle, TInt aMaskHandle)
250 {
251 CFbsBitmap* bm=new (ELeave) CFbsBitmap;
252 CleanupStack::PushL(bm);
253 User::LeaveIfError(bm->Duplicate(aIconHandle));
254 CFbsBitmap* mask=new (ELeave) CFbsBitmap;
255 CleanupStack::PushL(mask);
256 User::LeaveIfError(mask->Duplicate(aMaskHandle));
257 TInt id=iDrawer->AddIconL(bm, mask);
258 CleanupStack::Pop(2);
259 return id;
260 }
261
262 void CContextNotify::ChangeIconL(TInt aId, TInt aIconHandle, TInt aMaskHandle)
263 {
264 CFbsBitmap* bm=new (ELeave) CFbsBitmap;
265 CleanupStack::PushL(bm);
266 User::LeaveIfError(bm->Duplicate(aIconHandle));
267 CFbsBitmap* mask=new (ELeave) CFbsBitmap;
268 CleanupStack::PushL(mask);
269 User::LeaveIfError(mask->Duplicate(aMaskHandle));
270 iDrawer->ChangeIconL(bm, mask, aId);
271 CleanupStack::Pop(2);
272 }
273
274 void CContextNotify::RemoveIcon(TInt aId)
275 {
276 iDrawer->RemoveIcon(aId);
277 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -