2 #A part of NonVisual Desktop Access (NVDA)
\r
3 #Copyright (C) 2006-2007 NVDA Contributors <http://www.nvda-project.org/>
\r
4 #This file is covered by the GNU General Public License.
\r
5 #See the file COPYING for more details.
\r
17 from logHandler import log
\r
22 WM_LBUTTONDOWN=0x0201
\r
24 WM_LBUTTONDBLCLK=0x0203
\r
25 WM_RBUTTONDOWN=0x0204
\r
27 WM_RBUTTONDBLCLK=0x0206
\r
34 #: The time (in seconds) at which the last mouse event occurred.
\r
36 lastMouseEventTime=0
\r
38 def updateMouseShape(name):
\r
39 global curMouseShape, mouseShapeChanged
\r
40 if not name or name==curMouseShape:
\r
45 def playAudioCoordinates(x, y, screenWidth, screenHeight, detectBrightness=True,blurFactor=0):
\r
46 minPitch=config.conf['mouse']['audioCoordinates_minPitch']
\r
47 maxPitch=config.conf['mouse']['audioCoordinates_maxPitch']
\r
48 curPitch=minPitch+((maxPitch-minPitch)*((screenHeight-y)/float(screenHeight)))
\r
49 if detectBrightness:
\r
50 startX=min(max(x-blurFactor,0),screenWidth)
\r
51 width=min((x+blurFactor+1)-startX,screenWidth)
\r
52 startY=min(max(y-blurFactor,0),screenHeight)
\r
53 height=min((y+blurFactor+1)-startY,screenHeight)
\r
54 grey=screenBitmap.rgbPixelBrightness(scrBmpObj.captureImage(startX,startY,width,height)[0][0])
\r
55 brightness=grey/255.0
\r
56 minBrightness=config.conf['mouse']['audioCoordinates_minVolume']
\r
57 maxBrightness=config.conf['mouse']['audioCoordinates_maxVolume']
\r
58 brightness=(brightness*(maxBrightness-minBrightness))+minBrightness
\r
60 brightness=config.conf['mouse']['audioCoordinates_maxVolume']
\r
61 leftVolume=int((85*((screenWidth-float(x))/screenWidth))*brightness)
\r
62 rightVolume=int((85*(float(x)/screenWidth))*brightness)
\r
63 tones.beep(curPitch,40,left=leftVolume,right=rightVolume)
\r
65 #Internal mouse event
\r
67 def internal_mouseEvent(msg,x,y,injected):
\r
68 global mouseMoved, curMousePos, lastMouseEventTime
\r
69 lastMouseEventTime=time.time()
\r
72 if not config.conf['mouse']['enableMouseTracking']:
\r
76 if msg==WM_MOUSEMOVE:
\r
78 elif msg in (WM_LBUTTONDOWN,WM_RBUTTONDOWN):
\r
79 queueHandler.queueFunction(queueHandler.eventQueue,speech.cancelSpeech)
\r
81 log.error("", exc_info=True)
\r
84 def executeMouseMoveEvent(x,y):
\r
85 global currentMouseWindow
\r
86 desktopObject=api.getDesktopObject()
\r
87 screenLeft,screenTop,screenWidth,screenHeight=desktopObject.location
\r
88 x=min(max(screenLeft,x),(screenLeft+screenWidth)-1)
\r
89 y=min(max(screenTop,y),(screenTop+screenHeight)-1)
\r
90 if config.conf["mouse"]["audioCoordinatesOnMouseMove"]:
\r
91 playAudioCoordinates(x,y,screenWidth,screenHeight,config.conf['mouse']['audioCoordinates_detectBrightness'],config.conf['mouse']['audioCoordinates_blurFactor'])
\r
92 oldMouseObject=api.getMouseObject()
\r
93 mouseObject=desktopObject.objectFromPoint(x,y)
\r
94 while mouseObject and mouseObject.beTransparentToMouse:
\r
95 mouseObject=mouseObject.parent
\r
98 if oldMouseObject==mouseObject:
\r
99 mouseObject=oldMouseObject
\r
101 api.setMouseObject(mouseObject)
\r
103 eventHandler.executeEvent("mouseMove",mouseObject,x=x,y=y)
\r
104 oldMouseObject=mouseObject
\r
106 log.error("api.notifyMouseMoved", exc_info=True)
\r
108 #Register internal mouse event
\r
111 global curMousePos, scrBmpObj
\r
112 scrBmpObj=screenBitmap.ScreenBitmap(1,1)
\r
113 (x,y)=winUser.getCursorPos()
\r
114 desktopObject=api.getDesktopObject()
\r
116 mouseObject=desktopObject.objectFromPoint(x,y)
\r
118 log.exception("Error retrieving initial mouse object")
\r
120 if not mouseObject:
\r
121 mouseObject=api.getDesktopObject()
\r
122 api.setMouseObject(mouseObject)
\r
124 winInputHook.initialize()
\r
125 winInputHook.setCallbacks(mouse=internal_mouseEvent)
\r
128 global mouseMoved, curMousePos, mouseShapeChanged, curMouseShape
\r
132 executeMouseMoveEvent(x,y)
\r
133 if config.conf["mouse"]["reportMouseShapeChanges"] and mouseShapeChanged>0:
\r
134 if mouseShapeChanged==10:
\r
135 mouseShapeChanged=0
\r
136 # Translators: Reported when mouse cursor shape changes (example output: edit cursor).
\r
137 speech.speakMessage(_("%s cursor")%curMouseShape)
\r
139 mouseShapeChanged+=1
\r
144 winInputHook.terminate()
\r