psychopy 2024.2.1__py3-none-any.whl → 2024.2.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of psychopy might be problematic. Click here for more details.
- psychopy/.DS_Store +0 -0
- psychopy/GIT_SHA +1 -1
- psychopy/VERSION +1 -1
- psychopy/__init__.py +10 -1
- psychopy/__init__.py.orig +65 -0
- psychopy/app/{locale/ar_001/.DS_Store → .DS_Store} +0 -0
- psychopy/app/Resources/.DS_Store +0 -0
- psychopy/app/_psychopyApp.py +11 -3
- psychopy/app/appData.spec +1 -1
- psychopy/app/builder/builder.py +1 -1
- psychopy/app/builder/builder.py.orig +3932 -0
- psychopy/app/builder/dialogs/__init__.py.orig +1679 -0
- psychopy/app/builder/dialogs/paramCtrls.py +1 -1
- psychopy/app/builder/dialogs/paramCtrls.py.orig +713 -0
- psychopy/app/colorpicker/__init__.py.orig +411 -0
- psychopy/app/cortex.log +0 -0
- psychopy/app/jobs.py +8 -1
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +2452 -1731
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.po +6127 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.po +7366 -0
- psychopy/app/plugin_manager/dialog.py +9 -7
- psychopy/app/ribbon.py +2 -1
- psychopy/app/runner/runner.py +7 -5
- psychopy/clock.py +8 -4
- psychopy/core.py.orig +169 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/index.html +23 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks-legacy-browsers.js +423 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks.js +427 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/chooseBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/facesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/housesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.py +330 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +330 -0
- psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xml +298 -0
- psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xsd +120 -0
- psychopy/demos/builder/Tools/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +38 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +3418 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +2 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +15 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.psyexp +323 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.py +562 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +562 -0
- psychopy/demos/builder/Tools/gammaCalibration/questStairs.xlsx +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/readme.md +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/low_contrast.png +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/make_2nd_order_tex.py +59 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/second_order_tex.png +0 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
- psychopy/demos/coder/iohub/.iohpid +1 -0
- psychopy/demos/coder/iohub/eyetracking/.iohpid +1 -0
- psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/radialGratingContracting.py +29 -0
- psychopy/experiment/_experiment.py.orig +1032 -0
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/_base.py +13 -4
- psychopy/experiment/components/_base.py.orig +823 -0
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py +10 -1
- psychopy/experiment/components/microphone/__init__.py.orig +490 -0
- psychopy/experiment/components/polygon/__init__.py +21 -22
- psychopy/experiment/components/settings/__init__.py +13 -14
- psychopy/experiment/components/settings/__init__.py.orig +1337 -0
- psychopy/experiment/components/textbox/__init__.py.orig +310 -0
- psychopy/experiment/components/webcam/.DS_Store +0 -0
- psychopy/experiment/components/webcam/light/.DS_Store +0 -0
- psychopy/experiment/flow.py +10 -8
- psychopy/experiment/loops.py.orig +829 -0
- psychopy/experiment/params.py +8 -3
- psychopy/experiment/params.py.orig +408 -0
- psychopy/experiment/routine.py.orig +503 -0
- psychopy/experiment/routines/_base.py +15 -6
- psychopy/experiment/routines/counterbalance/__init__.py +1 -0
- psychopy/gui/qtgui.py +14 -7
- psychopy/gui/util.py +10 -14
- psychopy/gui/wxgui.py +10 -4
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/brainproducts.py.orig +680 -0
- psychopy/hardware/iolab.py.orig +238 -0
- psychopy/hardware/manager.py +1 -1
- psychopy/hardware/photodiode.py +59 -27
- psychopy/hardware/serialport.py +51 -0
- psychopy/hardware/speaker.py +4 -4
- psychopy/iohub/datastore/__init__.py.orig +443 -0
- psychopy/iohub/datastore/util.py.orig +692 -0
- psychopy/iohub/devices/mouse/darwin.py.orig +427 -0
- psychopy/iohub/devices/mouse/linux2.py.orig +198 -0
- psychopy/preferences/.DS_Store +0 -0
- psychopy/projects/pavlovia.py +10 -3
- psychopy/projects/pavlovia.py.orig +1295 -0
- psychopy/sound/backend_ptb.py +22 -5
- psychopy/sound/transcribe.py +24 -4
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestCircle_fill_local.png +0 -0
- psychopy/tests/data/__test.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
- psychopy/tests/data/aperture1_norm_local.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_height_local.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_norm_local.png +0 -0
- psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
- psychopy/tests/data/blend_add_height_local.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
- psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
- psychopy/tests/data/blend_add_norm_local.png +0 -0
- psychopy/tests/data/blend_add_stencil_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
- psychopy/tests/data/circleHex_height_local.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
- psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
- psychopy/tests/data/circleHex_norm_local.png +0 -0
- psychopy/tests/data/circleHex_stencil_local.png +0 -0
- psychopy/tests/data/color_comparison_local.png +0 -0
- psychopy/tests/data/corrFullRandom_local.csv +16 -0
- psychopy/tests/data/corrFullRandom_local.tsv +6 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/dots_height_local.png +0 -0
- psychopy/tests/data/dots_normAddBlend_local.png +0 -0
- psychopy/tests/data/dots_normHexbackground_local.png +0 -0
- psychopy/tests/data/dots_normNoShade_local.png +0 -0
- psychopy/tests/data/dots_norm_local.png +0 -0
- psychopy/tests/data/dots_stencil_local.png +0 -0
- psychopy/tests/data/elarray1_height_local.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
- psychopy/tests/data/elarray1_norm_local.png +0 -0
- psychopy/tests/data/elarray1_stencil_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
- psychopy/tests/data/gabor1_height_local.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
- psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
- psychopy/tests/data/gabor1_norm_local.png +0 -0
- psychopy/tests/data/gabor1_stencil_local.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_height_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
- psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
- psychopy/tests/data/movFrame1_stencil_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/numpyImage_height_local.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
- psychopy/tests/data/numpyImage_norm_local.png +0 -0
- psychopy/tests/data/numpyImage_stencil_local.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
- psychopy/tests/data/shape2_1_norm_local.png +0 -0
- psychopy/tests/data/shape2_1_stencil_local.png +0 -0
- psychopy/tests/data/testLoopsBlocks.psyexp_local.py +328 -0
- psychopy/tests/data/text1_height_local.png +0 -0
- psychopy/tests/data/text1_normAddBlend_local.png +0 -0
- psychopy/tests/data/text1_normHexbackground_local.png +0 -0
- psychopy/tests/data/text1_norm_local.png +0 -0
- psychopy/tests/data/text1_stencil_local.png +0 -0
- psychopy/tests/data/text2_height.png +0 -0
- psychopy/tests/data/text2_normAddBlend.png +0 -0
- psychopy/tests/data/text2_normHexbackground.png +0 -0
- psychopy/tests/data/text2_stencil.png +0 -0
- psychopy/tests/data/wedge1_height_local.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
- psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
- psychopy/tests/data/wedge1_norm_local.png +0 -0
- psychopy/tests/data/wedge1_stencil_local.png +0 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.csv +9 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +177 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.csv +9 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +168 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
- psychopy/tests/test_data/.DS_Store +0 -0
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +68 -0
- psychopy/tests/test_tools/test_arraytools.py +112 -0
- psychopy/tests/test_visual/test_image.py.orig +219 -0
- psychopy/tools/arraytools.py +47 -0
- psychopy/tools/versionchooser.py +1 -1
- psychopy/visual/backends/pygletbackend.py +26 -8
- psychopy/visual/basevisual.py.orig +1723 -0
- psychopy/visual/form.py.orig +1181 -0
- psychopy/visual/text.py.orig +752 -0
- psychopy/visual/textbox2/textbox2.py.orig +1315 -0
- psychopy/visual/window.py +13 -5
- psychopy/visual/windowwarp.py.orig +463 -0
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/METADATA +9 -9
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/RECORD +244 -78
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/WHEEL +1 -1
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/entry_points.txt +2 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy-2024.2.1.dist-info/licenses/AUTHORS.md +0 -138
- /psychopy/{app/locale/ar_001/LC_MESSAGE → demos/builder}/.DS_Store +0 -0
- /psychopy/{app/locale/es_ES/LC_MESSAGE → demos/builder/Experiments}/.DS_Store +0 -0
- /psychopy/{visual → demos/builder/Tools/gammaCalibration/data}/.DS_Store +0 -0
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Part of the PsychoPy library
|
|
3
|
+
# Copyright (C) 2012-2020 iSolver Software Solutions (C) 2021 Open Science Tools Ltd.
|
|
4
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
|
5
|
+
from copy import copy
|
|
6
|
+
import Quartz as Qz
|
|
7
|
+
from AppKit import NSEvent
|
|
8
|
+
|
|
9
|
+
from . import MouseDevice
|
|
10
|
+
from .. import Keyboard, Computer, Device
|
|
11
|
+
from ...errors import print2err, printExceptionDetailsToStdErr
|
|
12
|
+
from ...constants import EventConstants, MouseConstants
|
|
13
|
+
|
|
14
|
+
currentSec = Computer.getTime
|
|
15
|
+
|
|
16
|
+
pressID = [
|
|
17
|
+
None,
|
|
18
|
+
Qz.kCGEventLeftMouseDown,
|
|
19
|
+
Qz.kCGEventRightMouseDown,
|
|
20
|
+
Qz.kCGEventOtherMouseDown]
|
|
21
|
+
releaseID = [
|
|
22
|
+
None,
|
|
23
|
+
Qz.kCGEventLeftMouseUp,
|
|
24
|
+
Qz.kCGEventRightMouseUp,
|
|
25
|
+
Qz.kCGEventOtherMouseUp]
|
|
26
|
+
dragID = [
|
|
27
|
+
None,
|
|
28
|
+
Qz.kCGEventLeftMouseDragged,
|
|
29
|
+
Qz.kCGEventRightMouseDragged,
|
|
30
|
+
Qz.kCGEventOtherMouseDragged]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Mouse(MouseDevice):
|
|
34
|
+
"""The Mouse class and related events represent a standard computer mouse
|
|
35
|
+
device and the events a standard mouse can produce.
|
|
36
|
+
|
|
37
|
+
Mouse position data is mapped to the coordinate space defined in the
|
|
38
|
+
ioHub configuration file for the Display.
|
|
39
|
+
|
|
40
|
+
Examples:
|
|
41
|
+
|
|
42
|
+
A. Print all mouse events received for 5 seconds::
|
|
43
|
+
|
|
44
|
+
from psychopy.iohub import launchHubServer
|
|
45
|
+
from psychopy.core import getTime
|
|
46
|
+
|
|
47
|
+
# Start the ioHub process. 'io' can now be used during the
|
|
48
|
+
# experiment to access iohub devices and read iohub device events.
|
|
49
|
+
io = launchHubServer()
|
|
50
|
+
|
|
51
|
+
mouse = io.devices.mouse
|
|
52
|
+
|
|
53
|
+
# Check for and print any Mouse events received for 5 seconds.
|
|
54
|
+
stime = getTime()
|
|
55
|
+
while getTime()-stime < 5.0:
|
|
56
|
+
for e in mouse.getEvents():
|
|
57
|
+
print(e)
|
|
58
|
+
|
|
59
|
+
# Stop the ioHub Server
|
|
60
|
+
io.quit()
|
|
61
|
+
|
|
62
|
+
B. Print current mouse position for 5 seconds::
|
|
63
|
+
|
|
64
|
+
from psychopy.iohub import launchHubServer
|
|
65
|
+
from psychopy.core import getTime
|
|
66
|
+
|
|
67
|
+
# Start the ioHub process. 'io' can now be used during the
|
|
68
|
+
# experiment to access iohub devices and read iohub device events.
|
|
69
|
+
io = launchHubServer()
|
|
70
|
+
|
|
71
|
+
mouse = io.devices.mouse
|
|
72
|
+
|
|
73
|
+
# Check for and print any Mouse events received for 5 seconds.
|
|
74
|
+
stime = getTime()
|
|
75
|
+
while getTime()-stime < 5.0:
|
|
76
|
+
print(mouse.getPosition())
|
|
77
|
+
|
|
78
|
+
# Stop the ioHub Server
|
|
79
|
+
io.quit()
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
__slots__ = ['_loop_source', '_tap', '_device_loop', '_CGEventTapEnable',
|
|
83
|
+
'_loop_mode', '_scrollPositionX']
|
|
84
|
+
|
|
85
|
+
_IOHUB_BUTTON_ID_MAPPINGS = {
|
|
86
|
+
Qz.kCGEventLeftMouseDown: MouseConstants.MOUSE_BUTTON_LEFT,
|
|
87
|
+
Qz.kCGEventRightMouseDown: MouseConstants.MOUSE_BUTTON_RIGHT,
|
|
88
|
+
Qz.kCGEventOtherMouseDown: MouseConstants.MOUSE_BUTTON_MIDDLE,
|
|
89
|
+
Qz.kCGEventLeftMouseUp: MouseConstants.MOUSE_BUTTON_LEFT,
|
|
90
|
+
Qz.kCGEventRightMouseUp: MouseConstants.MOUSE_BUTTON_RIGHT,
|
|
91
|
+
Qz.kCGEventOtherMouseUp: MouseConstants.MOUSE_BUTTON_MIDDLE
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
DEVICE_TIME_TO_SECONDS = 0.000000001
|
|
95
|
+
|
|
96
|
+
_EVENT_TEMPLATE_LIST = [0, # experiment id
|
|
97
|
+
0, # session id
|
|
98
|
+
0, # device id
|
|
99
|
+
0, # Device._getNextEventID(),
|
|
100
|
+
0, # ioHub Event type
|
|
101
|
+
0.0, # event device time,
|
|
102
|
+
0.0, # event logged_time,
|
|
103
|
+
0.0, # event iohub Time,
|
|
104
|
+
0.0, # confidence_interval,
|
|
105
|
+
0.0, # delay,
|
|
106
|
+
0, # filtered by ID (always 0 right now)
|
|
107
|
+
0, # Display Index,
|
|
108
|
+
0, # ioHub Button State,
|
|
109
|
+
0, # ioHub Button ID,
|
|
110
|
+
0, # Active Buttons,
|
|
111
|
+
0.0, # x position of mouse in Display device coord's
|
|
112
|
+
0.0, # y position of mouse in Display device coord's
|
|
113
|
+
0, # Wheel dx
|
|
114
|
+
0, # Wheel Absolute x
|
|
115
|
+
0, # Wheel dy
|
|
116
|
+
0, # Wheel Absolute y
|
|
117
|
+
0, # modifiers
|
|
118
|
+
0] # event.Window]
|
|
119
|
+
|
|
120
|
+
def __init__(self, *args, **kwargs):
|
|
121
|
+
MouseDevice.__init__(self, *args, **kwargs['dconfig'])
|
|
122
|
+
|
|
123
|
+
self._tap = Qz.CGEventTapCreate(
|
|
124
|
+
Qz.kCGSessionEventTap,
|
|
125
|
+
Qz.kCGHeadInsertEventTap,
|
|
126
|
+
Qz.kCGEventTapOptionDefault,
|
|
127
|
+
Qz.CGEventMaskBit(Qz.kCGEventMouseMoved) |
|
|
128
|
+
Qz.CGEventMaskBit(Qz.kCGEventLeftMouseDown) |
|
|
129
|
+
Qz.CGEventMaskBit(Qz.kCGEventLeftMouseUp) |
|
|
130
|
+
Qz.CGEventMaskBit(Qz.kCGEventRightMouseDown) |
|
|
131
|
+
Qz.CGEventMaskBit(Qz.kCGEventRightMouseUp) |
|
|
132
|
+
Qz.CGEventMaskBit(Qz.kCGEventLeftMouseDragged) |
|
|
133
|
+
Qz.CGEventMaskBit(Qz.kCGEventRightMouseDragged) |
|
|
134
|
+
Qz.CGEventMaskBit(Qz.kCGEventOtherMouseDragged) |
|
|
135
|
+
Qz.CGEventMaskBit(Qz.kCGEventOtherMouseDown) |
|
|
136
|
+
Qz.CGEventMaskBit(Qz.kCGEventScrollWheel) |
|
|
137
|
+
Qz.CGEventMaskBit(Qz.kCGEventOtherMouseUp),
|
|
138
|
+
self._nativeEventCallback,
|
|
139
|
+
None)
|
|
140
|
+
|
|
141
|
+
self._scrollPositionX = 0
|
|
142
|
+
self._CGEventTapEnable = Qz.CGEventTapEnable
|
|
143
|
+
self._loop_source = Qz.CFMachPortCreateRunLoopSource(
|
|
144
|
+
None, self._tap, 0)
|
|
145
|
+
self._device_loop = Qz.CFRunLoopGetCurrent()
|
|
146
|
+
self._loop_mode = Qz.kCFRunLoopDefaultMode
|
|
147
|
+
|
|
148
|
+
Qz.CFRunLoopAddSource(
|
|
149
|
+
self._device_loop,
|
|
150
|
+
self._loop_source,
|
|
151
|
+
self._loop_mode)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _initialMousePos(self):
|
|
155
|
+
"""If getPosition is called prior to any mouse events being received,
|
|
156
|
+
this method gets the current system cursor pos.
|
|
157
|
+
TODO: Implement OS X version
|
|
158
|
+
"""
|
|
159
|
+
if self._position is None:
|
|
160
|
+
self._position = 0.0, 0.0
|
|
161
|
+
self._lastPosition = 0.0, 0.0
|
|
162
|
+
|
|
163
|
+
def _nativeSetMousePos(self, px, py):
|
|
164
|
+
result = Qz.CGWarpMouseCursorPosition(
|
|
165
|
+
Qz.CGPointMake(float(px), float(py)))
|
|
166
|
+
#print2err('_nativeSetMousePos result: ',result)
|
|
167
|
+
|
|
168
|
+
#def _nativeGetSystemCursorVisibility(self):
|
|
169
|
+
# return Qz.CGCursorIsVisible()
|
|
170
|
+
#
|
|
171
|
+
# def _nativeSetSystemCursorVisibility(self, v):
|
|
172
|
+
# if v and not Qz.CGCursorIsVisible():
|
|
173
|
+
# Qz.CGDisplayShowCursor(Qz.CGMainDisplayID())
|
|
174
|
+
# elif not v and Qz.CGCursorIsVisible():
|
|
175
|
+
# Qz.CGDisplayHideCursor(Qz.CGMainDisplayID())
|
|
176
|
+
|
|
177
|
+
#def _nativeLimitCursorToBoundingRect(self, clip_rect):
|
|
178
|
+
# print2err(
|
|
179
|
+
# 'WARNING: Mouse._nativeLimitCursorToBoundingRect not implemented on OSX yet.')
|
|
180
|
+
# native_clip_rect = None
|
|
181
|
+
# return native_clip_rect
|
|
182
|
+
|
|
183
|
+
def getScroll(self):
|
|
184
|
+
"""
|
|
185
|
+
TODO: Update docs for OSX
|
|
186
|
+
Args: None
|
|
187
|
+
Returns
|
|
188
|
+
"""
|
|
189
|
+
return self._scrollPositionX, self._scrollPositionY
|
|
190
|
+
|
|
191
|
+
def setScroll(self, sp):
|
|
192
|
+
"""
|
|
193
|
+
TODO: Update docs for OSX
|
|
194
|
+
"""
|
|
195
|
+
self._scrollPositionX, self._scrollPositionY = sp
|
|
196
|
+
return self._scrollPositionX, self._scrollPositionY
|
|
197
|
+
|
|
198
|
+
def _poll(self):
|
|
199
|
+
self._last_poll_time = currentSec()
|
|
200
|
+
while Qz.CFRunLoopRunInMode(self._loop_mode, 0.0, True) == Qz.kCFRunLoopRunHandledSource:
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
def _nativeEventCallback(self, *args):
|
|
204
|
+
try:
|
|
205
|
+
proxy, etype, event, refcon = args
|
|
206
|
+
if self.isReportingEvents():
|
|
207
|
+
logged_time = currentSec()
|
|
208
|
+
|
|
209
|
+
if etype == Qz.kCGEventTapDisabledByTimeout:
|
|
210
|
+
print2err('** WARNING: Mouse Tap Disabled due to timeout. Re-enabling....: ', etype)
|
|
211
|
+
Qz.CGEventTapEnable(self._tap, True)
|
|
212
|
+
return event
|
|
213
|
+
else:
|
|
214
|
+
confidence_interval = 0.0
|
|
215
|
+
delay = 0.0
|
|
216
|
+
iohub_time = logged_time
|
|
217
|
+
device_time = Qz.CGEventGetTimestamp(event) * self.DEVICE_TIME_TO_SECONDS
|
|
218
|
+
ioe_type = EventConstants.UNDEFINED
|
|
219
|
+
px, py = Qz.CGEventGetLocation(event)
|
|
220
|
+
multi_click_count = Qz.CGEventGetIntegerValueField(event, Qz.kCGMouseEventClickState)
|
|
221
|
+
mouse_event = NSEvent.eventWithCGEvent_(event)
|
|
222
|
+
|
|
223
|
+
# TODO: window_handle seems to always be 0.
|
|
224
|
+
window_handle = mouse_event.windowNumber()
|
|
225
|
+
|
|
226
|
+
display_index = self.getDisplayIndexForMousePosition((px, py))
|
|
227
|
+
if display_index == -1:
|
|
228
|
+
if self._last_display_index is not None:
|
|
229
|
+
display_index = self._last_display_index
|
|
230
|
+
else:
|
|
231
|
+
# Do not report event to iohub if it does not map to a display
|
|
232
|
+
# ?? Can this ever actually happen ??
|
|
233
|
+
return event
|
|
234
|
+
|
|
235
|
+
<<<<<<< HEAD
|
|
236
|
+
enable_multi_window = self.getConfiguration().get('enable_multi_window', False)
|
|
237
|
+
if enable_multi_window is False:
|
|
238
|
+
px, py = self._display_device._pixel2DisplayCoord(px, py, display_index)
|
|
239
|
+
else:
|
|
240
|
+
wid, wx, wy = self._desktopToWindowPos((px, py))
|
|
241
|
+
if wid:
|
|
242
|
+
px, py = self._pix2windowUnits(wid, (wx, wy))
|
|
243
|
+
window_handle = wid
|
|
244
|
+
else:
|
|
245
|
+
window_handle = 0
|
|
246
|
+
|
|
247
|
+
=======
|
|
248
|
+
# result=self._validateMousePosition((px,py),display_index)
|
|
249
|
+
# if result != True:
|
|
250
|
+
# #print2err("!!! _validateMousePosition made adjustment: {0} to {1}".format((px,py),result))
|
|
251
|
+
# nx,ny=result
|
|
252
|
+
# display_index=self.getDisplayIndexForMousePosition((nx,ny))
|
|
253
|
+
# #print2err("Going to Update mousePosition: {0} => {1} on D {2}".format((px,py),(ny,ny),display_index))
|
|
254
|
+
# px,py=nx,ny
|
|
255
|
+
# self._nativeSetMousePos(px,py)
|
|
256
|
+
|
|
257
|
+
px, py = self._display_device._pixel2DisplayCoord(
|
|
258
|
+
px, py, display_index)
|
|
259
|
+
>>>>>>> release
|
|
260
|
+
self._lastPosition = self._position
|
|
261
|
+
self._position = px, py
|
|
262
|
+
self._last_display_index = self._display_index
|
|
263
|
+
self._display_index = display_index
|
|
264
|
+
|
|
265
|
+
# TO DO: Supported reporting scroll x info for OSX.
|
|
266
|
+
# This also suggests not having scroll up and down events and
|
|
267
|
+
# just having the one scroll event type, regardless of
|
|
268
|
+
# direction / dimension
|
|
269
|
+
scroll_dx = 0
|
|
270
|
+
scroll_dy = 0
|
|
271
|
+
button_state = 0
|
|
272
|
+
if etype in pressID:
|
|
273
|
+
button_state = MouseConstants.MOUSE_BUTTON_STATE_PRESSED
|
|
274
|
+
if multi_click_count > 1:
|
|
275
|
+
ioe_type = EventConstants.MOUSE_MULTI_CLICK
|
|
276
|
+
else:
|
|
277
|
+
ioe_type = EventConstants.MOUSE_BUTTON_PRESS
|
|
278
|
+
elif etype in releaseID:
|
|
279
|
+
button_state = MouseConstants.MOUSE_BUTTON_STATE_RELEASED
|
|
280
|
+
ioe_type = EventConstants.MOUSE_BUTTON_RELEASE
|
|
281
|
+
elif etype in dragID:
|
|
282
|
+
ioe_type = EventConstants.MOUSE_DRAG
|
|
283
|
+
elif etype == Qz.kCGEventMouseMoved:
|
|
284
|
+
ioe_type = EventConstants.MOUSE_MOVE
|
|
285
|
+
elif etype == Qz.kCGEventScrollWheel:
|
|
286
|
+
ioe_type = EventConstants.MOUSE_SCROLL
|
|
287
|
+
scroll_dy = Qz.CGEventGetIntegerValueField(event, Qz.kCGScrollWheelEventPointDeltaAxis1)
|
|
288
|
+
scroll_dx = Qz.CGEventGetIntegerValueField(event, Qz.kCGScrollWheelEventPointDeltaAxis2)
|
|
289
|
+
self._scrollPositionX += scroll_dx
|
|
290
|
+
self._scrollPositionY += scroll_dy
|
|
291
|
+
|
|
292
|
+
iohub_button_id = self._IOHUB_BUTTON_ID_MAPPINGS.get(etype, 0)
|
|
293
|
+
|
|
294
|
+
if iohub_button_id in self.activeButtons:
|
|
295
|
+
abuttons = int(button_state == MouseConstants.MOUSE_BUTTON_STATE_PRESSED)
|
|
296
|
+
self.activeButtons[iohub_button_id] = abuttons
|
|
297
|
+
|
|
298
|
+
pressed_buttons = 0
|
|
299
|
+
for k, v in self.activeButtons.items():
|
|
300
|
+
pressed_buttons += k * v
|
|
301
|
+
|
|
302
|
+
# Create Event List
|
|
303
|
+
# index 0 and 1 are session and exp. ID's
|
|
304
|
+
# index 2 is (yet to be used) device_id
|
|
305
|
+
ioe = self._EVENT_TEMPLATE_LIST
|
|
306
|
+
ioe[3] = Device._getNextEventID()
|
|
307
|
+
ioe[4] = ioe_type # event type code
|
|
308
|
+
ioe[5] = device_time
|
|
309
|
+
ioe[6] = logged_time
|
|
310
|
+
ioe[7] = iohub_time
|
|
311
|
+
ioe[8] = confidence_interval
|
|
312
|
+
ioe[9] = delay
|
|
313
|
+
# index 10 is filter id, not used at this time
|
|
314
|
+
ioe[11] = display_index
|
|
315
|
+
ioe[12] = button_state
|
|
316
|
+
ioe[13] = iohub_button_id
|
|
317
|
+
ioe[14] = pressed_buttons
|
|
318
|
+
ioe[15] = px
|
|
319
|
+
ioe[16] = py
|
|
320
|
+
ioe[17] = int(scroll_dx)
|
|
321
|
+
ioe[18] = int(self._scrollPositionX)
|
|
322
|
+
ioe[19] = int(scroll_dy)
|
|
323
|
+
ioe[20] = int(self._scrollPositionY)
|
|
324
|
+
ioe[21] = Keyboard._modifier_value
|
|
325
|
+
ioe[22] = window_handle
|
|
326
|
+
|
|
327
|
+
self._addNativeEventToBuffer(copy(ioe))
|
|
328
|
+
|
|
329
|
+
self._last_callback_time = logged_time
|
|
330
|
+
except Exception:
|
|
331
|
+
printExceptionDetailsToStdErr()
|
|
332
|
+
Qz.CGEventTapEnable(self._tap, False)
|
|
333
|
+
|
|
334
|
+
# Must return original event or no mouse events will get to OSX!
|
|
335
|
+
return event
|
|
336
|
+
|
|
337
|
+
def _getIOHubEventObject(self, native_event_data):
|
|
338
|
+
#ioHub.print2err('Event: ',native_event_data)
|
|
339
|
+
return native_event_data
|
|
340
|
+
|
|
341
|
+
def _close(self):
|
|
342
|
+
#try:
|
|
343
|
+
# self._nativeSetSystemCursorVisibility(True)
|
|
344
|
+
#except Exception:
|
|
345
|
+
# pass
|
|
346
|
+
|
|
347
|
+
try:
|
|
348
|
+
Qz.CGEventTapEnable(self._tap, False)
|
|
349
|
+
except Exception:
|
|
350
|
+
pass
|
|
351
|
+
|
|
352
|
+
try:
|
|
353
|
+
if Qz.CFRunLoopContainsSource(
|
|
354
|
+
self._device_loop,
|
|
355
|
+
self._loop_source,
|
|
356
|
+
self._loop_mode) is True:
|
|
357
|
+
Qz.CFRunLoopRemoveSource(
|
|
358
|
+
self._device_loop, self._loop_source, self._loop_mode)
|
|
359
|
+
finally:
|
|
360
|
+
self._loop_source = None
|
|
361
|
+
self._tap = None
|
|
362
|
+
self._device_loop = None
|
|
363
|
+
self._loop_mode = None
|
|
364
|
+
|
|
365
|
+
MouseDevice._close(self)
|
|
366
|
+
# END OF OSX MOUSE CLASS
|
|
367
|
+
|
|
368
|
+
"""
|
|
369
|
+
CGEventTapInformation
|
|
370
|
+
Defines the structure used to report information about event taps.
|
|
371
|
+
typedef struct CGEventTapInformation
|
|
372
|
+
{
|
|
373
|
+
uint32_t eventTapID;
|
|
374
|
+
CGEventTapLocation tapPoint;
|
|
375
|
+
CGEventTapOptions options;
|
|
376
|
+
CGEventMask eventsOfInterest;
|
|
377
|
+
pid_t tappingProcess;
|
|
378
|
+
pid_t processBeingTapped;
|
|
379
|
+
bool enabled;
|
|
380
|
+
float minUsecLatency;
|
|
381
|
+
float avgUsecLatency;
|
|
382
|
+
float maxUsecLatency;
|
|
383
|
+
} CGEventTapInformation;
|
|
384
|
+
Fields
|
|
385
|
+
|
|
386
|
+
eventTapID
|
|
387
|
+
The unique identifier for the event tap.
|
|
388
|
+
|
|
389
|
+
tapPoint
|
|
390
|
+
The location of the event tap. See "Event Tap Locations."
|
|
391
|
+
|
|
392
|
+
options
|
|
393
|
+
The type of event tap (passive listener or active filter).
|
|
394
|
+
|
|
395
|
+
eventsOfInterest
|
|
396
|
+
The mask that identifies the set of events to be observed.
|
|
397
|
+
|
|
398
|
+
tappingProcess
|
|
399
|
+
The process ID of the application that created the event tap.
|
|
400
|
+
|
|
401
|
+
processBeingTapped
|
|
402
|
+
The process ID of the target application (non-zero only if the
|
|
403
|
+
event tap was created using the function CGEventTapCreateForPSN.
|
|
404
|
+
|
|
405
|
+
enabled
|
|
406
|
+
TRUE if the event tap is currently enabled; otherwise FALSE.
|
|
407
|
+
|
|
408
|
+
minUsecLatency
|
|
409
|
+
Minimum latency in microseconds. In this data structure,
|
|
410
|
+
latency is defined as the time in microseconds it takes
|
|
411
|
+
for an event tap to process and respond to an event passed to it.
|
|
412
|
+
|
|
413
|
+
avgUsecLatency
|
|
414
|
+
Average latency in microseconds. This is a weighted average
|
|
415
|
+
that gives greater weight to more recent events.
|
|
416
|
+
|
|
417
|
+
maxUsecLatency
|
|
418
|
+
Maximum latency in microseconds.
|
|
419
|
+
|
|
420
|
+
Discussion
|
|
421
|
+
To learn how to obtain information about event taps, see the
|
|
422
|
+
function CGGetEventTapList.
|
|
423
|
+
Availability
|
|
424
|
+
Available in OS X v10.4 and later.
|
|
425
|
+
Declared In
|
|
426
|
+
CGEventTypes.h
|
|
427
|
+
"""
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Part of the PsychoPy library
|
|
3
|
+
# Copyright (C) 2012-2020 iSolver Software Solutions (C) 2021 Open Science Tools Ltd.
|
|
4
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
|
5
|
+
|
|
6
|
+
from ctypes import cdll
|
|
7
|
+
|
|
8
|
+
from . import MouseDevice
|
|
9
|
+
from .. import Keyboard, Computer, Device, xlib
|
|
10
|
+
from ...constants import MouseConstants
|
|
11
|
+
from ...errors import print2err, printExceptionDetailsToStdErr
|
|
12
|
+
|
|
13
|
+
currentSec = Computer.getTime
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Mouse(MouseDevice):
|
|
17
|
+
"""The Mouse class and related events represent a standard computer mouse
|
|
18
|
+
device and the events a standard mouse can produce.
|
|
19
|
+
|
|
20
|
+
Mouse position data is mapped to the coordinate space defined in the
|
|
21
|
+
ioHub configuration file for the Display.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
_xdll = None
|
|
26
|
+
_xfixsdll = None
|
|
27
|
+
_xdisplay = None
|
|
28
|
+
_xscreen_count = None
|
|
29
|
+
|
|
30
|
+
__slots__ = ['_cursorVisible']
|
|
31
|
+
|
|
32
|
+
def __init__(self, *args, **kwargs):
|
|
33
|
+
MouseDevice.__init__(self, *args, **kwargs['dconfig'])
|
|
34
|
+
|
|
35
|
+
self._cursorVisible = True
|
|
36
|
+
|
|
37
|
+
if Mouse._xdll is None:
|
|
38
|
+
try:
|
|
39
|
+
Mouse._xdll = cdll.LoadLibrary('libX11.so')
|
|
40
|
+
try:
|
|
41
|
+
# should use linux cmd:
|
|
42
|
+
# find /usr/lib -name libXfixes.so\*
|
|
43
|
+
# to find full path to the lib (if it exists)
|
|
44
|
+
#
|
|
45
|
+
Mouse._xfixsdll = cdll.LoadLibrary('libXfixes.so')
|
|
46
|
+
except Exception:
|
|
47
|
+
try:
|
|
48
|
+
Mouse._xfixsdll = cdll.LoadLibrary(
|
|
49
|
+
'libXfixes.so.3.1.0')
|
|
50
|
+
except Exception:
|
|
51
|
+
print2err(
|
|
52
|
+
'ERROR: Mouse._xfixsdll is None. libXfixes.so could not be found')
|
|
53
|
+
except Exception:
|
|
54
|
+
print2err(
|
|
55
|
+
'ERROR: Mouse._xdll is None. libX11.so could not be found')
|
|
56
|
+
|
|
57
|
+
Mouse._xdisplay = xlib.XOpenDisplay(None)
|
|
58
|
+
Mouse._xscreen_count = xlib.XScreenCount(Mouse._xdisplay)
|
|
59
|
+
|
|
60
|
+
if Mouse._xfixsdll and self._xdll and self._display_device and self._display_device._xwindow is None:
|
|
61
|
+
self._display_device._xwindow = self._xdll.XRootWindow(
|
|
62
|
+
Mouse._xdisplay, self._display_device.getIndex())
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _initialMousePos(self):
|
|
66
|
+
"""If getPosition is called prior to any mouse events being received,
|
|
67
|
+
this method gets the current system cursor pos.
|
|
68
|
+
TODO: Implement Linux version
|
|
69
|
+
"""
|
|
70
|
+
if self._position is None:
|
|
71
|
+
self._position = 0.0, 0.0
|
|
72
|
+
self._lastPosition = 0.0, 0.0
|
|
73
|
+
|
|
74
|
+
def _nativeSetMousePos(self, px, py):
|
|
75
|
+
Mouse._xdll.XWarpPointer(
|
|
76
|
+
Mouse._xdisplay,
|
|
77
|
+
None,
|
|
78
|
+
self._display_device._xwindow,
|
|
79
|
+
0,
|
|
80
|
+
0,
|
|
81
|
+
0,
|
|
82
|
+
0,
|
|
83
|
+
int(px),
|
|
84
|
+
int(py))
|
|
85
|
+
Mouse._xdll.XFlush(Mouse._xdisplay)
|
|
86
|
+
|
|
87
|
+
<<<<<<< HEAD
|
|
88
|
+
=======
|
|
89
|
+
#def _nativeGetSystemCursorVisibility(self):
|
|
90
|
+
# return self._cursorVisible
|
|
91
|
+
|
|
92
|
+
# def _nativeSetSystemCursorVisibility(self, v):
|
|
93
|
+
# if Mouse._xfixsdll is None:
|
|
94
|
+
# print2err(
|
|
95
|
+
# 'Xfixes DLL could not be loaded. Cursor visibility support is unavailable.')
|
|
96
|
+
# return True
|
|
97
|
+
#
|
|
98
|
+
# if v is True and self._nativeGetSystemCursorVisibility() is False:
|
|
99
|
+
# Mouse._xfixsdll.XFixesShowCursor(
|
|
100
|
+
# Mouse._xdisplay, self._display_device._xwindow)
|
|
101
|
+
# Mouse._xfixsdll.XFlush(Mouse._xdisplay)
|
|
102
|
+
# self._cursorVisible = True
|
|
103
|
+
# elif v is False and self._nativeGetSystemCursorVisibility() is True:
|
|
104
|
+
# Mouse._xfixsdll.XFixesHideCursor(
|
|
105
|
+
# Mouse._xdisplay, self._display_device._xwindow)
|
|
106
|
+
# Mouse._xfixsdll.XFlush(Mouse._xdisplay)
|
|
107
|
+
# self._cursorVisible = False
|
|
108
|
+
#
|
|
109
|
+
# return self._nativeGetSystemCursorVisibility()
|
|
110
|
+
|
|
111
|
+
#def _nativeLimitCursorToBoundingRect(self, clip_rect):
|
|
112
|
+
# print2err(
|
|
113
|
+
# 'WARNING: Mouse._nativeLimitCursorToBoundingRect not implemented on Linux yet.')
|
|
114
|
+
# native_clip_rect = None
|
|
115
|
+
# return native_clip_rect
|
|
116
|
+
|
|
117
|
+
>>>>>>> release
|
|
118
|
+
def _nativeEventCallback(self, event):
|
|
119
|
+
try:
|
|
120
|
+
if self.isReportingEvents():
|
|
121
|
+
logged_time = currentSec()
|
|
122
|
+
event_array = event[0]
|
|
123
|
+
|
|
124
|
+
psychowins = self._iohub_server._psychopy_windows.keys()
|
|
125
|
+
report_all = self.getConfiguration().get('report_system_wide_events', True)
|
|
126
|
+
if report_all is False and psychowins and event_array[-1] not in psychowins:
|
|
127
|
+
return True
|
|
128
|
+
|
|
129
|
+
event_array[3] = Device._getNextEventID()
|
|
130
|
+
|
|
131
|
+
display_index = self.getDisplayIndexForMousePosition((event_array[15], event_array[16]))
|
|
132
|
+
if display_index == -1:
|
|
133
|
+
if self._last_display_index is not None:
|
|
134
|
+
display_index = self._last_display_index
|
|
135
|
+
else:
|
|
136
|
+
# Do not report event to iohub if it does not map to a display
|
|
137
|
+
# ?? Can this ever actually happen ??
|
|
138
|
+
return True
|
|
139
|
+
|
|
140
|
+
enable_multi_window = self.getConfiguration().get('enable_multi_window', False)
|
|
141
|
+
if enable_multi_window is False:
|
|
142
|
+
# convert mouse position to psychopy window coord space
|
|
143
|
+
display_index = self._display_device.getIndex()
|
|
144
|
+
x, y = self._display_device._pixel2DisplayCoord(event_array[15], event_array[16], display_index)
|
|
145
|
+
event_array[15] = x
|
|
146
|
+
event_array[16] = y
|
|
147
|
+
else:
|
|
148
|
+
wid, wx, wy = self._desktopToWindowPos((event_array[15], event_array[16]))
|
|
149
|
+
if wid:
|
|
150
|
+
wx, wy = self._pix2windowUnits(wid, (wx, wy))
|
|
151
|
+
event_array[15], event_array[16] = x, y = wx, wy
|
|
152
|
+
event_array[-1] = wid
|
|
153
|
+
else:
|
|
154
|
+
event_array[-1] = 0
|
|
155
|
+
x = event_array[15]
|
|
156
|
+
y = event_array[16]
|
|
157
|
+
|
|
158
|
+
event_array[-2] = Keyboard._modifier_value
|
|
159
|
+
self._lastPosition = self._position
|
|
160
|
+
self._position = x, y
|
|
161
|
+
|
|
162
|
+
event_array[11] = display_index
|
|
163
|
+
self._last_display_index = self._display_index
|
|
164
|
+
self._display_index = display_index
|
|
165
|
+
|
|
166
|
+
bstate = event_array[-11]
|
|
167
|
+
bnum = event_array[-10]
|
|
168
|
+
|
|
169
|
+
if bnum is not MouseConstants.MOUSE_BUTTON_NONE:
|
|
170
|
+
self.activeButtons[bnum] = int(bstate)
|
|
171
|
+
|
|
172
|
+
self._scrollPositionY = event_array[-3]
|
|
173
|
+
|
|
174
|
+
self._addNativeEventToBuffer(event_array)
|
|
175
|
+
|
|
176
|
+
self._last_callback_time = logged_time
|
|
177
|
+
except Exception:
|
|
178
|
+
printExceptionDetailsToStdErr()
|
|
179
|
+
return True
|
|
180
|
+
|
|
181
|
+
def _getIOHubEventObject(self, native_event_data):
|
|
182
|
+
return native_event_data
|
|
183
|
+
|
|
184
|
+
def _close(self):
|
|
185
|
+
if Mouse._xdll:
|
|
186
|
+
#if Mouse._xfixsdll and self._nativeGetSystemCursorVisibility() is False:
|
|
187
|
+
# Mouse._xfixsdll.XFixesShowCursor(
|
|
188
|
+
# Mouse._xdisplay, self._display_device._xwindow)
|
|
189
|
+
Mouse._xdll.XCloseDisplay(Mouse._xdisplay)
|
|
190
|
+
Mouse._xdll = None
|
|
191
|
+
Mouse._xfixsdll = None
|
|
192
|
+
Mouse._xdisplay = None
|
|
193
|
+
Mouse._xscreen_count = None
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
self._display_device._xwindow = None
|
|
197
|
+
except Exception:
|
|
198
|
+
pass
|
|
Binary file
|
psychopy/projects/pavlovia.py
CHANGED
|
@@ -1208,12 +1208,19 @@ class PavloviaProject(dict):
|
|
|
1208
1208
|
None
|
|
1209
1209
|
"""
|
|
1210
1210
|
localConfig = self.repo.git.config(l=True, local=True) # list local
|
|
1211
|
-
if self.session.user['email'] in localConfig:
|
|
1212
|
-
return # we already have it set up so can return
|
|
1213
1211
|
# set the local config
|
|
1214
|
-
|
|
1212
|
+
config = self.repo.config_writer()
|
|
1213
|
+
# set config values if the user hasn't set them already
|
|
1214
|
+
# the -100 hack is because ConfigParser.get_value allows setting a default
|
|
1215
|
+
# but doing try...except on its custom errors is annoying!
|
|
1216
|
+
if config.get_value("user", "email", default=-100) == -100:
|
|
1215
1217
|
config.set_value("user", "email", self.session.user['email'])
|
|
1216
1218
|
config.set_value("user", "name", self.session.user['name'])
|
|
1219
|
+
if config.get_value("pull", "rebase", default=-100) == -100:
|
|
1220
|
+
config.set_value("pull", "rebase", False)
|
|
1221
|
+
if config.get_value("http", "postBuffer", default=-100) == -100:
|
|
1222
|
+
config.set_value("http", "postBuffer", 524288000)
|
|
1223
|
+
config.release() # saves the changes (not needed if using `with config_writer() as config`)
|
|
1217
1224
|
|
|
1218
1225
|
def fork(self, to=None):
|
|
1219
1226
|
# Sub in current user if none given
|