1
2
3
4
5
6
7 import wx
8 import winUser
9 import winKernel
10 import wincon
11 from colors import RGB
12 import eventHandler
13 from logHandler import log
14 import speech
15 import textInfos
16 import api
17 import config
18
19
20 CHECK_DEAD_INTERVAL = 100
21
22 consoleObject=None
23 consoleWinEventHookHandles=[]
24 consoleOutputHandle=None
25 checkDeadTimer=None
26
27 CONSOLE_COLORS_TO_RGB=(
28 RGB(0x00,0x00,0x00),
29 RGB(0x00,0x00,0xAA),
30 RGB(0x00,0xAA,0x00),
31 RGB(0x00,0xAA,0xAA),
32 RGB(0xAA,0x00,0x00),
33 RGB(0xAA,0x00,0xAA),
34 RGB(0xAA,0x55, 0x00),
35 RGB(0xAA,0xAA,0xAA),
36 RGB(0x55,0x55,0x55),
37 RGB(0x55,0x55,0xFF),
38 RGB(0x55,0xFF,0x55),
39 RGB(0x55,0xFF,0xFF),
40 RGB(0xFF,0x55,0x55),
41 RGB(0xFF,0x55,0xFF),
42 RGB(0xFF,0xFF,0x55),
43 RGB(0xFF,0xFF,0xFF),
44 )
45
46 COMMON_LVB_UNDERSCORE=0x8000
55
57 global consoleObject, consoleOutputHandle, checkDeadTimer
58
59 processID,threadID=winUser.getWindowThreadProcessID(obj.windowHandle)
60
61 try:
62 wincon.AttachConsole(processID)
63 except WindowsError as e:
64 log.debugWarning("Could not attach console: %s"%e)
65 return False
66 wincon.SetConsoleCtrlHandler(_consoleCtrlHandler,True)
67 consoleOutputHandle=winKernel.CreateFile(u"CONOUT$",winKernel.GENERIC_READ|winKernel.GENERIC_WRITE,winKernel.FILE_SHARE_READ|winKernel.FILE_SHARE_WRITE,None,winKernel.OPEN_EXISTING,0,None)
68
69 for eventID in (winUser.EVENT_CONSOLE_CARET,winUser.EVENT_CONSOLE_UPDATE_REGION,winUser.EVENT_CONSOLE_UPDATE_SIMPLE,winUser.EVENT_CONSOLE_UPDATE_SCROLL,winUser.EVENT_CONSOLE_LAYOUT):
70 handle=winUser.setWinEventHook(eventID,eventID,0,consoleWinEventHook,0,0,0)
71 if not handle:
72 raise OSError("could not register eventID %s"%eventID)
73 consoleWinEventHookHandles.append(handle)
74 consoleObject=obj
75 checkDeadTimer=wx.PyTimer(_checkDead)
76 checkDeadTimer.Start(CHECK_DEAD_INTERVAL)
77 return True
78
104
111
119
128
129 @winUser.WINEVENTPROC
130 -def consoleWinEventHook(handle,eventID,window,objectID,childID,threadID,timestamp):
145
148
152
153 -class WinConsoleTextInfo(textInfos.offsets.OffsetsTextInfo):
154
155 _cache_consoleScreenBufferInfo=True
158
160 consoleScreenBufferInfo=self.consoleScreenBufferInfo
161 val=y-consoleScreenBufferInfo.srWindow.Top
162 val*=consoleScreenBufferInfo.dwSize.x
163 val+=x
164 return val
165
167 consoleScreenBufferInfo=self.consoleScreenBufferInfo
168 x=offset%consoleScreenBufferInfo.dwSize.x
169 y=offset-x
170 y/=consoleScreenBufferInfo.dwSize.x
171 y+=consoleScreenBufferInfo.srWindow.Top
172 return x,y
173
174 - def _getOffsetFromPoint(self,x,y):
175 consoleScreenBufferInfo=self.consoleScreenBufferInfo
176 screenLeft,screenTop,screenWidth,screenHeight=self.obj.location
177 relativeX=x-screenLeft
178 relativeY=y-screenTop
179 lineLength=(consoleScreenBufferInfo.srWindow.Right+1)-consoleScreenBufferInfo.srWindow.Left
180 numLines=(consoleScreenBufferInfo.srWindow.Bottom+1)-consoleScreenBufferInfo.srWindow.Top
181 characterWidth=screenWidth/lineLength
182 characterHeight=screenHeight/numLines
183 characterX=(relativeX/characterWidth)+consoleScreenBufferInfo.srWindow.Left
184 characterY=(relativeY/characterHeight)+consoleScreenBufferInfo.srWindow.Top
185 return self._offsetFromConsoleCoord(characterX,characterY)
186
187 - def _getPointFromOffset(self,offset):
188 consoleScreenBufferInfo=self.consoleScreenBufferInfo
189 characterX,characterY=self._consoleCoordFromOffset(offset)
190 screenLeft,screenTop,screenWidth,screenHeight=self.obj.location
191 lineLength=(consoleScreenBufferInfo.srWindow.Right+1)-consoleScreenBufferInfo.srWindow.Left
192 numLines=(consoleScreenBufferInfo.srWindow.Bottom+1)-consoleScreenBufferInfo.srWindow.Top
193 characterWidth=screenWidth/lineLength
194 characterHeight=screenHeight/numLines
195 relativeX=(characterX-consoleScreenBufferInfo.srWindow.Left)*characterWidth
196 relativeY=(characterY-consoleScreenBufferInfo.srWindow.Top)*characterHeight
197 x=relativeX+screenLeft
198 y=relativeY+screenTop
199 return textInfos.Point(x,y)
200
201 - def _getCaretOffset(self):
202 consoleScreenBufferInfo=self.consoleScreenBufferInfo
203 return self._offsetFromConsoleCoord(consoleScreenBufferInfo.dwCursorPosition.x,consoleScreenBufferInfo.dwCursorPosition.y)
204
206 selInfo=wincon.GetConsoleSelectionInfo()
207 if selInfo.dwFlags&wincon.CONSOLE_SELECTION_NOT_EMPTY:
208 start=self._offsetFromConsoleCoord(selInfo.srSelection.Left,selInfo.srSelection.Top)
209 end=self._offsetFromConsoleCoord(selInfo.srSelection.Right,selInfo.srSelection.Bottom)
210 else:
211 start=end=self._getCaretOffset()
212 return start,end
213
214 - def getTextWithFields(self,formatConfig=None):
215 commands=[]
216 if self.isCollapsed:
217 return commands
218 if not formatConfig:
219 formatConfig=config.conf["documentFormatting"]
220 left,top=self._consoleCoordFromOffset(self._startOffset)
221 right,bottom=self._consoleCoordFromOffset(self._endOffset-1)
222 rect=wincon.SMALL_RECT(left,top,right,bottom)
223 if bottom-top>0:
224 rect.Left=0
225 rect.Right=self.consoleScreenBufferInfo.dwSize.x-1
226 length=self.consoleScreenBufferInfo.dwSize.x*(bottom-top+1)
227 else:
228 length=self._endOffset-self._startOffset
229 buf=wincon.ReadConsoleOutput(consoleOutputHandle, length, rect)
230 if bottom-top>0:
231 buf=buf[left:len(buf)-(self.consoleScreenBufferInfo.dwSize.x-right)+1]
232 lastAttr=None
233 lastText=[]
234 boundEnd=self._startOffset
235 for i,c in enumerate(buf):
236 if self._startOffset+i==boundEnd:
237 field,(boundStart,boundEnd)=self._getFormatFieldAndOffsets(boundEnd,formatConfig)
238 if lastText:
239 commands.append("".join(lastText))
240 lastText=[]
241 commands.append(textInfos.FieldCommand("formatChange",field))
242 if not c.Attributes==lastAttr:
243 formatField=textInfos.FormatField()
244 if formatConfig['reportColor']:
245 formatField["color"]=CONSOLE_COLORS_TO_RGB[c.Attributes&0x0f]
246 formatField["background-color"]=CONSOLE_COLORS_TO_RGB[(c.Attributes>>4)&0x0f]
247 if formatConfig['reportFontAttributes'] and c.Attributes&COMMON_LVB_UNDERSCORE:
248 formatField['underline']=True
249 if formatField:
250 if lastText:
251 commands.append("".join(lastText))
252 lastText=[]
253 command=textInfos.FieldCommand("formatChange", formatField)
254 commands.append(command)
255 lastAttr=c.Attributes
256 lastText.append(c.Char)
257 commands.append("".join(lastText))
258 return commands
259
263
264 - def _getLineOffsets(self,offset):
265 consoleScreenBufferInfo=self.consoleScreenBufferInfo
266 x,y=self._consoleCoordFromOffset(offset)
267 x=0
268 start=self._offsetFromConsoleCoord(x,y)
269 end=start+consoleScreenBufferInfo.dwSize.x
270 return start,end
271
272 - def _getLineNumFromOffset(self,offset):
273 consoleScreenBufferInfo=self.consoleScreenBufferInfo
274 x,y=self._consoleCoordFromOffset(offset)
275 return y-consoleScreenBufferInfo.srWindow.Top
276
277 - def _getStoryLength(self):
278 consoleScreenBufferInfo=self.consoleScreenBufferInfo
279 return consoleScreenBufferInfo.dwSize.x*((consoleScreenBufferInfo.srWindow.Bottom+1)-consoleScreenBufferInfo.srWindow.Top)
280
282 return "\r\n".join(block.rstrip() for block in self.getTextInChunks(textInfos.UNIT_LINE))
283