OSDN Git Service

Merge 2013.1.
[nvdajp/nvdajp.git] / source / mouseHandler.py
1 #mouseHandler.py\r
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
6 \r
7 import time\r
8 import tones\r
9 import ctypes\r
10 import winUser\r
11 import queueHandler\r
12 import api\r
13 import screenBitmap\r
14 import speech\r
15 import globalVars\r
16 import eventHandler\r
17 from logHandler import log\r
18 import config\r
19 import winInputHook\r
20 \r
21 WM_MOUSEMOVE=0x0200\r
22 WM_LBUTTONDOWN=0x0201\r
23 WM_LBUTTONUP=0x0202\r
24 WM_LBUTTONDBLCLK=0x0203\r
25 WM_RBUTTONDOWN=0x0204\r
26 WM_RBUTTONUP=0x0205\r
27 WM_RBUTTONDBLCLK=0x0206\r
28 \r
29 curMousePos=(0,0)\r
30 mouseMoved=False\r
31 curMouseShape=""\r
32 mouseShapeChanged=0\r
33 scrBmpObj=None\r
34 #: The time (in seconds) at which the last mouse event occurred.\r
35 #: @type: float\r
36 lastMouseEventTime=0\r
37 \r
38 def updateMouseShape(name):\r
39         global curMouseShape, mouseShapeChanged\r
40         if not name or name==curMouseShape:\r
41                 return\r
42         curMouseShape=name\r
43         mouseShapeChanged=1\r
44 \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
59         else:\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
64 \r
65 #Internal mouse event\r
66 \r
67 def internal_mouseEvent(msg,x,y,injected):\r
68         global mouseMoved, curMousePos, lastMouseEventTime\r
69         lastMouseEventTime=time.time()\r
70         if injected:\r
71                 return True\r
72         if not config.conf['mouse']['enableMouseTracking']:\r
73                 return True\r
74         try:\r
75                 curMousePos=(x,y)\r
76                 if msg==WM_MOUSEMOVE: \r
77                         mouseMoved=True\r
78                 elif msg in (WM_LBUTTONDOWN,WM_RBUTTONDOWN):\r
79                         queueHandler.queueFunction(queueHandler.eventQueue,speech.cancelSpeech)\r
80         except:\r
81                 log.error("", exc_info=True)\r
82         return True\r
83 \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
96         if not mouseObject:\r
97                 return\r
98         if oldMouseObject==mouseObject:\r
99                 mouseObject=oldMouseObject\r
100         else:\r
101                 api.setMouseObject(mouseObject)\r
102         try:\r
103                 eventHandler.executeEvent("mouseMove",mouseObject,x=x,y=y)\r
104                 oldMouseObject=mouseObject\r
105         except:\r
106                 log.error("api.notifyMouseMoved", exc_info=True)\r
107 \r
108 #Register internal mouse event\r
109 \r
110 def initialize():\r
111         global curMousePos, scrBmpObj\r
112         scrBmpObj=screenBitmap.ScreenBitmap(1,1)\r
113         (x,y)=winUser.getCursorPos()\r
114         desktopObject=api.getDesktopObject()\r
115         try:\r
116                 mouseObject=desktopObject.objectFromPoint(x,y)\r
117         except:\r
118                 log.exception("Error retrieving initial mouse object")\r
119                 mouseObject=None\r
120         if not mouseObject:\r
121                 mouseObject=api.getDesktopObject()\r
122         api.setMouseObject(mouseObject)\r
123         curMousePos=(x,y)\r
124         winInputHook.initialize()\r
125         winInputHook.setCallbacks(mouse=internal_mouseEvent)\r
126 \r
127 def pumpAll():\r
128         global mouseMoved, curMousePos, mouseShapeChanged, curMouseShape\r
129         if mouseMoved:\r
130                 mouseMoved=False\r
131                 (x,y)=curMousePos\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
138                 else:\r
139                         mouseShapeChanged+=1\r
140 \r
141 def terminate():\r
142         global scrBmpObj\r
143         scrBmpObj=None\r
144         winInputHook.terminate()\r