--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/localisation/apparchitecture/apgrfx/APGTASK.CPP Thu Jan 21 12:53:44 2010 +0000
@@ -0,0 +1,514 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "APGTASK.H"
+#include "APGWGNAM.H"
+#include <w32std.h>
+
+//
+// class TApatask
+//
+
+
+
+EXPORT_C TApaTask::TApaTask(RWsSession& aWsSession)
+ : iWsSession(aWsSession), iWgId(0)
+/** Constructs an empty task object, taking a reference to a window server session.
+
+An object of this type is constructed by an instance of the TApaTaskList class.
+
+The object represents a task when it is assigned a task's window group ID.
+
+@param aWsSession The window server session.
+@see TApaTaskList */
+ {
+ }
+
+EXPORT_C void TApaTask::SetWgId(TInt aWgId)
+/** Sets this task's window group ID.
+
+@param aWgId The ID to be assigned. */
+ {
+ iWgId=aWgId;
+ }
+
+EXPORT_C TInt TApaTask::WgId() const
+/** Gets the ID of this task's window group.
+
+@return The window group ID. For an empty task object, this is zero. */
+ {
+ return iWgId;
+ }
+
+EXPORT_C TBool TApaTask::Exists() const
+/** Tests whether this TApaTask object is empty. This object represents the
+state of the task at the time at which it was constructed and is not subsequently
+updated. Therefore, this does not indicate that the task itself exists and should not
+be used to test whether or not a particular task is running or not.
+
+@return True, if the task is not empty; false, otherwise.
+@see TApaTaskList::FindDoc()
+@see TApaTaskList::FindApp()
+@see TApaTaskList::FindByPos() */
+ {
+ return(iWgId>0);
+ }
+
+EXPORT_C TThreadId TApaTask::ThreadId() const
+/** Gets the ID of this task's thread
+
+@return The thread ID. */
+ {
+ TThreadId threadId;
+ if (iWsSession.GetWindowGroupClientThreadId(iWgId,threadId)==KErrNotFound)
+ {
+ threadId=TThreadId(KNullThreadId);
+ }
+ return(threadId);
+ }
+
+EXPORT_C void TApaTask::BringToForeground()
+/** Brings this task to the foreground.
+
+If the task uses the View architecture, then the task's top view is activated. */
+ {
+ iWsSession.SetWindowGroupOrdinalPosition(iWgId,0);
+ SendSystemEvent(EApaSystemEventBroughtToForeground);
+ }
+
+EXPORT_C void TApaTask::SendToBackground()
+/** Sends this task to the background.
+
+The task whose window group is at the next ordinal position is brought up
+to the foreground. In addition, the new foreground task's top view is activated,
+if it uses the View architecture. */
+ {
+ iWsSession.SetWindowGroupOrdinalPosition(iWgId,-1);
+ }
+
+EXPORT_C void TApaTask::EndTask()
+/** Requests normal closing of this task.
+
+@capability PowerMgmt is required to close system tasks. */
+ {
+ RProcess client;
+ if (client.HasCapability(ECapabilityPowerMgmt))
+ {
+ SendSystemEvent(EApaSystemEventSecureShutdown, EEventPowerMgmt);
+ }
+
+ // Always send the old shutdown message for backward compatibility. Will not shut down system tasks.
+ SendSystemEvent(EApaSystemEventShutdown);
+ }
+
+EXPORT_C void TApaTask::KillTask()
+/** Kills this task.
+@capability PowerMgmt
+*/
+ {
+ RThread thread;
+ TInt err=thread.Open(ThreadId());
+ if (!err)
+ {
+ RProcess process;
+ thread.Process(process);
+ process.Terminate(0);
+ process.Close();
+ thread.Close();
+ }
+ } //lint !e1762 Suppress Member function 'TApaTask::KillTask(void)' could be made const
+
+
+EXPORT_C TInt TApaTask::SwitchOpenFile(const TDesC& aFilename)
+/** Requests the task to close its existing document, and to open an existing document.
+
+An application (task) may handle the request by overriding CEikAppUi::OpenFileL() if required.
+
+@param aFilename The name of the document to be opened.
+@return KErrNone, if the request was successfully sent to the task; otherwise one of the other
+system-wide error codes. */
+ {
+ TInt err=CheckSwitchFile();
+ if (!err)
+#if defined(_UNICODE)
+ {
+ TPtrC8 messageBuffer((TUint8*) aFilename.Ptr(),aFilename.Length()<<1);
+ err=SendMessage(KUidApaMessageSwitchOpenFile,messageBuffer);
+ }
+#else
+ err=SendMessage(KUidApaMessageSwitchOpenFile,aFilename);
+#endif
+ return err;
+ }
+
+EXPORT_C TInt TApaTask::SwitchCreateFile(const TDesC& aFilename)
+/** Requests the task to close its existing document, and to create and open a new
+document.
+
+An application (task) may handle the request by overriding CEikAppUi::CreateFileL() if required.
+
+@param aFilename The name of the new document.
+@return KErrNone, if the request was successfully sent to the task; otherwise one of the other
+system-wide error codes. */
+ {
+ TInt err=CheckSwitchFile();
+ if (!err)
+#if defined(_UNICODE)
+ {
+ TPtrC8 messageBuffer((TUint8*) aFilename.Ptr(),aFilename.Length()<<1);
+ err=SendMessage(KUidApaMessageSwitchCreateFile,messageBuffer);
+ }
+#else
+ err=SendMessage(KUidApaMessageSwitchCreateFile,aFilename);
+#endif
+ return err;
+ }
+
+TInt TApaTask::CheckSwitchFile() const
+ //
+ // private - checks whether the task will respond to a switch files event
+ //
+ {
+ HBufC* buf=HBufC::NewMax(CApaWindowGroupName::EMaxLength);
+ if (!buf)
+ return KErrNoMemory;
+ TInt err=KErrNone;
+ TPtr des=buf->Des();
+ err=iWsSession.GetWindowGroupNameFromIdentifier(iWgId, des);
+ if (!err)
+ {
+ CApaWindowGroupName* wgName=CApaWindowGroupName::New(iWsSession, buf); // takes ownership (if it succeeds)
+ if (!wgName)
+ {
+ delete buf;
+ return KErrNoMemory;
+ }
+ if (wgName->IsBusy())
+ err=KErrNotReady;
+ if (!(wgName->RespondsToSwitchFilesEvent()))
+ err=KErrNotSupported;
+ delete wgName;
+ }
+ else
+ delete buf;
+ return err;
+ }
+
+EXPORT_C TInt TApaTask::SendMessage(TUid aUid,const TDesC8& aParams)
+/** Sends a message to this task's window group.
+
+The message is handled by the UI framework, specifically by CEikAppUI::ProcessMessageL().
+
+
+@param aUid The UID identifying the message. By default, the UI framework
+recognizes only two messages, KUidApaMessageSwitchOpenFileValue and KUidApaMessageSwitchCreateFileValue.
+@param aParams The message. The format and meaning of the message depends on
+the specific type as identified by the UID.
+@return KErrNone, if successful; otherwise, one of the other system-wide error
+codes.
+@see CEikAppUi::ProcessMessageL()
+@see TEventCode
+@see TWsEvent
+@see RWindowGroup::FetchMessage() */
+ {
+ return iWsSession.SendMessageToWindowGroup(iWgId,aUid,aParams);
+ }
+
+EXPORT_C void TApaTask::SendKey(TInt aKeyCode,TInt aModifiers)
+/** Sends a key event encapsulating the specified character code and specified modifier
+keys state to the task's window group.
+
+Key events are handled by the UI framework, specifically by CCoeAppui::HandleWsEventL().
+
+@capability SwEvent
+@param aKeyCode The character code.
+@param aModifiers State of the modifier keys.
+@see CCoeAppUi::HandleWsEventL() */
+ {
+ TKeyEvent key;
+ key.iCode=aKeyCode;
+ key.iModifiers=aModifiers;
+ key.iRepeats=0;
+ SendKey(key);
+ }
+
+EXPORT_C void TApaTask::SendKey(const TKeyEvent& aKey)
+/** Sends the specified key event to the task's window group.
+
+Key events are handled by the UI framework, specifically by CCoeAppui::HandleWsEventL().
+
+@capability SwEvent
+@param aKey The key event.
+@see CCoeAppUi::HandleWsEventL()
+@see TKeyEvent */
+ {
+ TWsEvent event;
+ event.SetType(EEventKey);
+ *event.Key()=aKey;
+ event.SetTimeNow();
+ iWsSession.SendEventToWindowGroup(iWgId,event);
+ }
+
+EXPORT_C void TApaTask::SendSystemEvent(TApaSystemEvent aEvent)
+/** Sends a system event to this task's window group.
+
+Events are handled by the UI framework, specifically by CEikAppUi::HandleSystemEventL().
+
+@capability SwEvent
+@param aEvent The event type.
+@see CEikAppUi
+@see CCoeAppUi::HandleSystemEventL()
+@see TApaSystemEvent */
+ {
+ SendSystemEvent(aEvent, EEventUser);
+ }
+
+void TApaTask::SendSystemEvent(TApaSystemEvent aEvent, TEventCode aType)
+/**
+@internalTechnology
+*/
+ {
+ TWsEvent event;
+ event.SetType(aType);
+ *(TApaSystemEvent*)(event.EventData())=aEvent;
+ event.SetTimeNow();
+ iWsSession.SendEventToWindowGroup(iWgId,event);
+ }
+
+//
+// class TApaTaskList
+//
+
+
+
+EXPORT_C TApaTaskList::TApaTaskList(RWsSession& aWsSession)
+ : iWsSession(aWsSession)
+/** Constructs the task list object, taking a reference to a window server session.
+
+@param aWsSession The window server session. */
+ {
+ }
+
+EXPORT_C TApaTask TApaTaskList::FindApp(const TDesC& aAppName)
+/** Searches for a task that has the specified caption.
+
+The result of the search depends on the number of tasks that have the specified
+caption.
+
+If there is only one task, then that task is returned.
+
+If there is more than one task, then the task returned depends on whether
+the first one found is in the foreground:
+
+if the first task found is in the foreground, then the task returned by this
+function is the one with the highest window group ordinal value, i.e. the
+task which is furthest from the foreground.
+
+if the first task found is not in the foreground, then that is the task that
+is returned.
+
+If no matching task is found, then the object returned is an empty task, and
+calling TApaTask::Exists() on it returns false.
+
+@param aAppName The caption.
+@return A task having the specified caption, or an empty task. */
+ {
+ TApaTask task(iWsSession);
+ TInt wgId=0;
+ TInt matchId=0;
+ TInt fgWgId=FindByPos(0).WgId();
+ CApaWindowGroupName::FindByCaption(aAppName, iWsSession, wgId);
+ if (wgId==fgWgId)
+ {
+ while (wgId>=0)
+ {
+ matchId=wgId;
+ CApaWindowGroupName::FindByCaption(aAppName, iWsSession, wgId);
+ }
+ }
+ else
+ matchId=wgId;
+ task.SetWgId(matchId);
+ return(task);
+ }
+
+EXPORT_C TApaTask TApaTaskList::FindDoc(const TDesC& aDocName)
+/** Searches for the task that is handling the specified document.
+
+@param aDocName The name of the document.
+@return The task that is handling the specified document. If no such task exists,
+then this is an empty task, i.e. a subsequent call to TApaTask::Exists() returns
+false. */
+ {
+ TInt wgId=0;
+ CApaWindowGroupName::FindByDocName(aDocName, iWsSession, wgId);
+ TApaTask task(iWsSession);
+ task.SetWgId(wgId);
+ return(task);
+ }
+
+EXPORT_C TApaTask TApaTaskList::FindByPos(TInt aPos)
+/** Searches for a task by the ordinal position of its window group.
+
+@param aPos The ordinal position of a task's window group. A zero value refers
+to the foreground task.
+@return The task at the specified position. If there is no task at the specified
+position, or the specified position is invalid, then the object returned is
+an empty task, and calling TApaTask::Exists() on it returns false. */
+ {
+ TApaTask task(iWsSession);
+ TRAP_IGNORE(FindByPosL(task,aPos));
+ return(task);
+ }
+
+void TApaTaskList::FindByPosL(TApaTask& aTask,TInt aPos)
+ {
+ TInt wgId=0;
+ const TInt count=iWsSession.NumWindowGroups(0);
+ if (count)
+ {
+ CArrayFixFlat<TInt>* wgIdArray=new(ELeave) CArrayFixFlat<TInt>(count);
+ CleanupStack::PushL(wgIdArray);
+ CApaWindowGroupName* wgName=CApaWindowGroupName::NewL(iWsSession);
+ CleanupStack::PushL(wgName);
+ User::LeaveIfError(iWsSession.WindowGroupList(0,wgIdArray)); // priority 0 == mostly normal apps but some may be hidden window groups
+
+ for (TInt ii=0; ii<wgIdArray->Count(); ii++) // must ask for count each time as this may change
+ {
+ wgId=(*wgIdArray)[ii];
+ wgName->ConstructFromWgIdL(wgId);
+ if(wgName->Hidden())
+ {
+ wgIdArray->Delete(ii--); // array element removed so now need to do this index again
+ }
+ }
+
+ if (aPos>=count || aPos<0)
+ aPos=count-1;
+
+ if(aPos<wgIdArray->Count())
+ wgId=(*wgIdArray)[aPos];
+
+ CleanupStack::PopAndDestroy(2); // wgIdArray, wgName
+ }
+ aTask.SetWgId(wgId);
+ }
+
+
+EXPORT_C TApaTask TApaTaskList::FindApp(TUid aAppUid)
+/** Searches for a task running the specified application.
+
+The result of the search depends on the number of tasks that are running the
+specified application.
+
+If there is only one task, then that task is returned.
+
+If there is more than one task, then the task returned depends on whether
+the first one found is in the foreground:
+
+if the first task found is in the foreground, then the task returned by this
+function is the one with the highest window group ordinal value, i.e. the
+task which is furthest from the foreground.
+
+if the first task found is not in the foreground, then that is the task that
+is returned.
+
+If no matching task is found, then the object returned is an empty task, and
+calling TApaTask::Exists() on it returns false.
+
+@param aAppUid The application specific UID.
+@return A task having the specified caption, or an empty task. */
+ {
+ TApaTask task(iWsSession);
+ TInt wgId=0;
+ TInt matchId=0;
+ TInt fgWgId=FindByPos(0).WgId();
+ CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
+ if (wgId==fgWgId)
+ {
+ while (wgId>=0)
+ {
+ matchId=wgId;
+ CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
+ }
+ }
+ else
+ matchId=wgId;
+ task.SetWgId(matchId);
+ return task;
+ }
+
+EXPORT_C TInt TApaTaskList::CycleTasks(TUid aAppUid,TCycleDirection aDirection)
+/** Brings the next task in the set of tasks running the specified application to
+the foreground.
+
+If there is only one task, then no change occurs.
+
+If the foremost task in the set is not the foreground task, then this is made
+the foreground task.
+
+Thereafter, successive calls to this function bring the next task in the set
+to the foreground. The direction of the cycling can be specified and has the
+following effect:
+
+for the forwards direction, the foreground task is sent to the background;
+the next foremost task is made the foreground task.
+
+for the backwards direction, the task with the highest window group ordinal
+value, i.e. the task in the set which is furthest from the foreground, is
+brought to the foreground. The task that was the foremost task in the set
+is moved back by one position.
+
+If the task brought to the foreground uses the View architecture, then the
+its top view is activated.
+
+@param aAppUid The application specific UID.
+@param aDirection The direction of cycling.
+@return KErrNone, if successful; KErrNotFound, if there are no tasks running
+the specified application. */
+ {
+ TInt sendToBgWgId=KErrNotFound;
+ TInt wgId=0;
+ TInt fgWgId=FindByPos(0).WgId();
+ CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
+ TInt matchId=wgId;
+ if (wgId==fgWgId) // If first match is at foreground
+ {
+ if (aDirection==EBackwards)
+ {
+ while (wgId>=0) // Go for last match
+ {
+ matchId=wgId;
+ CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
+ }
+ }
+ else
+ {
+ CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
+ if (wgId<0) // If no other match
+ return KErrNone;
+ sendToBgWgId=matchId;
+ matchId=wgId; // Go for second match
+ }
+ }
+ if (matchId>=0)
+ {
+ iWsSession.SetWindowGroupOrdinalPosition(matchId,0);
+ if (sendToBgWgId>=0)
+ iWsSession.SetWindowGroupOrdinalPosition(sendToBgWgId,-1); // Send it to background
+ return KErrNone;
+ }
+ return KErrNotFound;
+ }