diff --git a/psychopy/app/_psychopyApp.py b/psychopy/app/_psychopyApp.py index e66f102cf4..a8b15e02bb 100755 --- a/psychopy/app/_psychopyApp.py +++ b/psychopy/app/_psychopyApp.py @@ -316,16 +316,20 @@ def onInit(self, showSplash=True, testMode=False): args=(True,)) versionsThread.start() - # if we have imageio then try to download ffmpeg try: import imageio haveImageio = True - except: + except ImportError: haveImageio = False + if haveImageio: - # download() returns immediately if we have it already - ffmpegDownloader = threading.Thread(target=imageio.plugins.ffmpeg.download) - ffmpegDownloader.start() + # Use pre-installed ffmpeg if available. + # Otherwise, download ffmpeg binary. + try: + imageio.plugins.ffmpeg.get_exe() + except imageio.core.NeedDownloadError: + ffmpegDownloader = threading.Thread(target=imageio.plugins.ffmpeg.download) + ffmpegDownloader.start() ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed diff --git a/psychopy/hardware/crs/bits.py b/psychopy/hardware/crs/bits.py index b6b8d12ce9..25e66aaf87 100644 --- a/psychopy/hardware/crs/bits.py +++ b/psychopy/hardware/crs/bits.py @@ -581,18 +581,18 @@ def getInfo(self): # get product ('Bits_Sharp'?) self.sendMessage(b'$ProductType\r') time.sleep(0.1) - info['ProductType'] = self.read().replace('#ProductType;', '') - info['ProductType'] = info['ProductType'].replace(';\n\r', '') + info['ProductType'] = self.read().replace(b'#ProductType;', b'') + info['ProductType'] = info['ProductType'].replace(b';\n\r', b'') # get serial number self.sendMessage(b'$SerialNumber\r') time.sleep(0.1) - info['SerialNumber'] = self.read().replace('#SerialNumber;', '') - info['SerialNumber'] = info['SerialNumber'].replace('\x00\n\r', '') + info['SerialNumber'] = self.read().replace(b'#SerialNumber;', b'') + info['SerialNumber'] = info['SerialNumber'].replace(b'\x00\n\r', b'') # get firmware date self.sendMessage(b'$FirmwareDate\r') time.sleep(0.1) - info['FirmwareDate'] = self.read().replace('#FirmwareDate;', '') - info['FirmwareDate'] = info['FirmwareDate'].replace(';\n\r', '') + info['FirmwareDate'] = self.read().replace(b'#FirmwareDate;', b'') + info['FirmwareDate'] = info['FirmwareDate'].replace(b';\n\r', b'') return info @property diff --git a/psychopy/parallel/__init__.py b/psychopy/parallel/__init__.py index ba4f718a49..6220c591df 100644 --- a/psychopy/parallel/__init__.py +++ b/psychopy/parallel/__init__.py @@ -12,7 +12,7 @@ shown below you can use one of the following as drop-in replacements, forcing the use of a specific driver: - - `psychopy.parallel.PParallelInpOut32` + - `psychopy.parallel.PParallelInpOut` - `psychopy.parallel.PParallelDLPortIO` - `psychopy.parallel.PParallelLinux` @@ -31,22 +31,34 @@ import sys from psychopy import logging -# To make life easier, only try drivers which have a hope in heck of working +# To make life easier, only try drivers which have a hope in heck of working. +# Because hasattr() in connection to windll ends up in an OSError trying to +# load 32bit drivers in a 64bit environment, different drivers defined in +# the dictionary 'drivers' are tested. + if sys.platform.startswith('linux'): from ._linux import PParallelLinux ParallelPort = PParallelLinux elif sys.platform == 'win32': + drivers = dict(inpout32=('_inpout', 'PParallelInpOut'), + inpoutx64=('_inpout', 'PParallelInpOut'), + dlportio=('_dlportio', 'PParallelDLPortIO')) from ctypes import windll - if hasattr(windll, 'inpout32'): - from ._inpout32 import PParallelInpOut32 - ParallelPort = PParallelInpOut32 - elif hasattr(windll, 'dlportio'): - from ._dlportio import PParallelDLPortIO - ParallelPort = PParallelDLPortIO - else: + from importlib import import_module + for key, val in drivers.items(): + driver_name, class_name = val + try: + hasattr(windll, key) + ParallelPort = getattr(import_module('.'+driver_name, __name__), + class_name) + break + except (OSError, KeyError, NameError): + ParallelPort = None + continue + if ParallelPort is None: logging.warning("psychopy.parallel has been imported but no " "parallel port driver found. Install either " - "inpout32 or dlportio") + "inpout32, inpoutx64 or dlportio") else: logging.warning("psychopy.parallel has been imported on a Mac " "(which doesn't have a parallel port?)") diff --git a/psychopy/parallel/_inpout32.py b/psychopy/parallel/_inpout.py similarity index 90% rename from psychopy/parallel/_inpout32.py rename to psychopy/parallel/_inpout.py index 269e44e85d..301e21e684 100644 --- a/psychopy/parallel/_inpout32.py +++ b/psychopy/parallel/_inpout.py @@ -3,7 +3,7 @@ from __future__ import absolute_import, print_function -# We deliberately delay importing the inpout32 module until we try +# We deliberately delay importing the inpout32 or inpoutx64 module until we try # to use it - this allows us to import the class on machines # which don't have it and then worry about dealing with # using the right one later @@ -11,9 +11,9 @@ from past.builtins import basestring from builtins import object -class PParallelInpOut32(object): +class PParallelInpOut(object): """This class provides read/write access to the parallel port on a PC - using inpout32 (for instance for Windows 7 64-bit) + using inpout32 or inpoutx64 (for instance for Windows 7 64-bit) """ def __init__(self, address=0x0378): @@ -29,13 +29,18 @@ def __init__(self, address=0x0378): from numpy import uint8 from ctypes import windll + import platform if isinstance(address, basestring) and address.startswith('0x'): # convert u"0x0378" into 0x0378 self.base = int(address, 16) else: self.base = address - self.port = windll.inpout32 + + if platform.architecture()[0] == '32bit': + self.port = getattr(windll, 'inpout32') + elif platform.architecture()[0] == '64bit': + self.port = getattr(windll, 'inpoutx64') BYTEMODEMASK = uint8(1 << 5 | 1 << 6 | 1 << 7) diff --git a/psychopy/visual/backends/pygletbackend.py b/psychopy/visual/backends/pygletbackend.py index fb2eadfb5e..bcce2b2eed 100644 --- a/psychopy/visual/backends/pygletbackend.py +++ b/psychopy/visual/backends/pygletbackend.py @@ -202,9 +202,13 @@ def __init__(self, win, *args, **kwargs): self.winHandle.set_mouse_visible(False) self.winHandle.on_resize = _onResize # avoid circular reference if not win.pos: - # work out where the centre should be - win.pos = [(thisScreen.width - win.size[0]) / 2, - (thisScreen.height - win.size[1]) / 2] + # work out where the centre should be + if win.useRetina: + win.pos = [(thisScreen.width - win.size[0]/2) / 2, + (thisScreen.height - win.size[1]/2) / 2] + else: + win.pos = [(thisScreen.width - win.size[0]) / 2, + (thisScreen.height - win.size[1]) / 2] if not win._isFullScr: # add the necessary amount for second screen self.winHandle.set_location(int(win.pos[0] + thisScreen.x),