|
1 // console.cpp |
|
2 // |
|
3 // Copyright (c) 2008 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #include <e32debug.h> |
|
14 #include "console.h" |
|
15 #include <fshell/consoleextensions.h> |
|
16 |
|
17 _LIT(KWin32ConsPanic, "Win32Console"); |
|
18 #define PANIC() User::Panic(KWin32ConsPanic, 0); |
|
19 |
|
20 //_____________________________________________________________________________ |
|
21 // CWin32Console |
|
22 CWin32Console::CWin32Console() |
|
23 { |
|
24 } |
|
25 |
|
26 CWin32Console::~CWin32Console() |
|
27 { |
|
28 iWin32.FreeConsole(); |
|
29 // when call FreeConsole(), it should cause the reader thread to exit as the |
|
30 // console read handle will become invalid, and windows will complete the |
|
31 // ReadRequest with an error |
|
32 if (iReaderThread.Handle()) |
|
33 { |
|
34 TRequestStatus stat; |
|
35 iReaderThread.Logon(stat); |
|
36 User::WaitForRequest(stat); |
|
37 } |
|
38 iReaderThread.Close(); |
|
39 iKeyQueue.Close(); |
|
40 iThreadParams.iOwner.Close(); |
|
41 } |
|
42 |
|
43 TInt CWin32Console::Create(const TDesC& aTitle, TSize /*aSize*/) |
|
44 { |
|
45 int r = iWin32.AttachConsole(); |
|
46 if (r==0) |
|
47 { |
|
48 return KErrCouldNotConnect; // suitable error code?? |
|
49 } |
|
50 SetTitle(aTitle); |
|
51 |
|
52 _LIT(KReadThreadName, "Win32ConsReader"); |
|
53 |
|
54 TInt err = iKeyQueue.CreateLocal(4); |
|
55 if (err!=KErrNone) return err; |
|
56 |
|
57 err = iThreadParams.iOwner.Open(RThread().Id()); |
|
58 if (err!=KErrNone) return err; |
|
59 iThreadParams.iWin32 = &iWin32; |
|
60 iThreadParams.iKeyQueue = iKeyQueue; |
|
61 err = iReaderThread.Create(KReadThreadName, ReaderThread, 0x800, KMinHeapSize, KMinHeapSize*4, &iThreadParams); |
|
62 if (err!=KErrNone) return err; |
|
63 iReaderThread.Resume(); |
|
64 |
|
65 return KErrNone; |
|
66 } |
|
67 |
|
68 void CWin32Console::Read(TRequestStatus& aStatus) |
|
69 { |
|
70 iReadKp = EFalse; |
|
71 iKeyQueue.NotifyDataAvailable(aStatus); |
|
72 } |
|
73 |
|
74 void CWin32Console::ReadCancel() |
|
75 { |
|
76 iKeyQueue.CancelDataAvailable(); |
|
77 } |
|
78 |
|
79 void CWin32Console::Write(const TDesC& aDes) |
|
80 { |
|
81 iWin32.Write(aDes.Ptr(), aDes.Length()); |
|
82 } |
|
83 |
|
84 void CWin32Console::WriteStdErr(const TDesC& aDes) |
|
85 { |
|
86 iWin32.WriteStdErr(aDes.Ptr(), aDes.Length()); |
|
87 } |
|
88 |
|
89 TPoint CWin32Console::CursorPos() const |
|
90 { |
|
91 TPoint pos; |
|
92 iWin32.GetCursorPos(pos.iX, pos.iY); |
|
93 return pos; |
|
94 } |
|
95 |
|
96 void CWin32Console::SetCursorPosAbs(const TPoint& aPoint) |
|
97 { |
|
98 iWin32.SetCursorPos(aPoint.iX, aPoint.iY); |
|
99 } |
|
100 |
|
101 void CWin32Console::SetCursorPosRel(const TPoint& aPoint) |
|
102 { |
|
103 iWin32.SetCursorPosRel(aPoint.iX, aPoint.iY); |
|
104 } |
|
105 |
|
106 void CWin32Console::SetCursorHeight(TInt aPercentage) |
|
107 { |
|
108 iWin32.SetCursorHeight(aPercentage); |
|
109 } |
|
110 |
|
111 void CWin32Console::SetTitle(const TDesC& aTitle) |
|
112 { |
|
113 RBuf8 title; |
|
114 TInt err = title.Create(aTitle.Length()+1); |
|
115 if (err==KErrNone) |
|
116 { |
|
117 title.Copy(aTitle); |
|
118 iWin32.SetTitle((const char*)title.PtrZ()); |
|
119 title.Close(); |
|
120 } |
|
121 } |
|
122 |
|
123 void CWin32Console::ClearScreen() |
|
124 { |
|
125 iWin32.ClearScreen(); |
|
126 } |
|
127 |
|
128 void CWin32Console::ClearToEndOfLine() |
|
129 { |
|
130 iWin32.ClearToEndOfLine(); |
|
131 } |
|
132 |
|
133 TSize CWin32Console::ScreenSize() const |
|
134 { |
|
135 TSize size; |
|
136 iWin32.GetScreenSize(size.iWidth, size.iHeight); |
|
137 return size; |
|
138 } |
|
139 |
|
140 TKeyCode CWin32Console::KeyCode() const |
|
141 { |
|
142 if (!iReadKp) |
|
143 { |
|
144 iKeyQueue.Receive(iKp); |
|
145 iReadKp = ETrue; |
|
146 } |
|
147 return iKp.iCode; |
|
148 } |
|
149 |
|
150 TUint CWin32Console::KeyModifiers() const |
|
151 { |
|
152 if (!iReadKp) |
|
153 { |
|
154 iKeyQueue.Receive(iKp); |
|
155 iReadKp = ETrue; |
|
156 } |
|
157 return iKp.iModifiers; |
|
158 } |
|
159 |
|
160 TInt CWin32Console::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1) |
|
161 { |
|
162 if (aExtensionId == ConsoleStdErr::KWriteStdErrConsoleExtension) |
|
163 { |
|
164 TDesC* des = (TDesC*)a1; |
|
165 WriteStdErr(*des); |
|
166 return KErrNone; |
|
167 } |
|
168 else if (aExtensionId == ConsoleAttributes::KSetConsoleAttributesExtension) |
|
169 { |
|
170 ConsoleAttributes::TAttributes* attributes = (ConsoleAttributes::TAttributes*)a1; |
|
171 int res = iWin32.SetAttributes(attributes->iAttributes, (TWin32Console::TColor)attributes->iForegroundColor, (TWin32Console::TColor)attributes->iBackgroundColor); |
|
172 return res ? KErrNone : KErrGeneral; // Yay for KErrGeneral! |
|
173 } |
|
174 else |
|
175 { |
|
176 return CConsoleBase::Extension_(aExtensionId, a0, a1); |
|
177 } |
|
178 |
|
179 } |
|
180 |
|
181 //_____________________________________________________________________________ |
|
182 // Reader thread |
|
183 |
|
184 static int ReaderThread(TAny* aParams) |
|
185 { |
|
186 TReaderThreadParams params = *(TReaderThreadParams*)aParams; |
|
187 |
|
188 RMsgQueue<TKeyPress> keyQueue = params.iKeyQueue; |
|
189 TInt err = keyQueue.Duplicate(params.iOwner); |
|
190 |
|
191 while (err==KErrNone) |
|
192 { |
|
193 TKeyPress kp; |
|
194 err = params.iWin32->ReadKey(kp.iCode, kp.iModifiers); |
|
195 |
|
196 if (err==KErrNone) |
|
197 { |
|
198 keyQueue.SendBlocking(kp); |
|
199 } |
|
200 |
|
201 }; |
|
202 |
|
203 keyQueue.Close(); |
|
204 |
|
205 return err; |
|
206 } |
|
207 |
|
208 //_____________________________________________________________________________ |
|
209 // Debugging stuff |
|
210 EXPORT_C TAny* NewConsole() |
|
211 { |
|
212 return new CWin32Console; |
|
213 } |
|
214 |
|
215 class TOverflowTruncate8 : public TDes8Overflow |
|
216 { |
|
217 public: |
|
218 virtual void Overflow(TDes8&) {} |
|
219 }; |
|
220 |
|
221 class TOverflowTruncate16 : public TDes16Overflow |
|
222 { |
|
223 public: |
|
224 virtual void Overflow(TDes16&) {} |
|
225 }; |
|
226 |
|
227 void DebugMsg(const char* aMsg, ...) |
|
228 { |
|
229 VA_LIST list; |
|
230 VA_START(list, aMsg); |
|
231 TBuf8<0x100> buf; |
|
232 TOverflowTruncate8 overflow; |
|
233 buf.AppendFormatList(_L8(aMsg), list, &overflow); |
|
234 |
|
235 RDebug::Printf((const char*)buf.PtrZ()); |
|
236 } |
|
237 |
|
238 void DebugMsg(const TUint16* aMsg, ...) |
|
239 { |
|
240 VA_LIST list; |
|
241 VA_START(list, aMsg); |
|
242 TBuf16<0x100> buf; |
|
243 TOverflowTruncate16 overflow; |
|
244 buf.AppendFormatList(TPtrC((const TText16*)aMsg), list, &overflow); |
|
245 |
|
246 RDebug::Print(buf); |
|
247 } |
|
248 |
|
249 |
|
250 #ifndef EKA2 |
|
251 GLDEF_C TInt E32Dll(TDllReason) |
|
252 { |
|
253 return(KErrNone); |
|
254 } |
|
255 #endif |