def create_flutter_window(initial_width, initial_height, main_path,
                          assets_path, packages_path, icu_data_path):
    """window"""
    window = glfw.create_window(initial_width, initial_height, "Flutter", None,
                                None)
    if not window:
        return None
    """engine"""
    engine = run_flutter_engine(window, main_path, assets_path, packages_path,
                                icu_data_path)
    if not engine:
        return None
    """state"""
    state = ffi.new('FlutterEmbedderState*')
    """防止state被gc掉"""
    flutter_global.prevent_gc(state)
    flutter_global.get_text_model().notifyState = lambda: update_editing_state(
        window)
    state.engine = engine
    glfw.set_window_user_pointer(window, state)
    state.monitor_screen_coordinates_per_inch = get_screen_coordinates_per_inch(
    )
    width_px = ffi.new('int*')
    height_px = ffi.new('int*')
    glfw.get_framebuffer_size(window, width_px, height_px)
    glfw.set_framebuffer_size_callback(window, glfw_framebuffer_size_callback)
    glfw_framebuffer_size_callback(window, width_px[0], height_px[0])

    glfw_assign_event_callbacks(window)
    return window
Пример #2
0
    def __init_window(self):
        if not glfw.init():
            raise ParticleSystemException('glfw.init() failed')

        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 0)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT,
                         True)  # needed on Mac OS X

        glfw.window_hint(glfw.RESIZABLE, False)

        self.window = glfw.create_window(SCREEN_WIDTH, SCREEN_HEIGHT,
                                         'Particle System', None, None)
        if self.window is None:
            raise ParticlSystemException('glfw.create_window() failed')

        glfw.set_window_pos(self.window, 0, 0)
        glfw.make_context_current(self.window)
        glfw.swap_interval(0)  # gotta go fast

        glfw.set_window_user_pointer(self.window, self)
        glfw.set_key_callback(self.window, key_callback)
        glfw.set_cursor_pos_callback(self.window, mouse_callback)
Пример #3
0
    def __init__(self, win, *args, **kwargs):
        """Set up the backend window according the params of the PsychoPy win

        Before PsychoPy 1.90.0 this code was executed in Window._setupPygame()

        :param win: a PsychoPy Window (usually not fully created yet)
        :param share: a PsychoPy Window to share a context with
        :param bpc: list-like, bits per color (R, G, B)
        :param refreshHz: int, refresh rate
        :param depthBits: int, framebuffer depth bits
        :param stencilBits: int, framebuffer stencil bits
        :param swapInterval: int, screen updates before swapping buffers
        :param winTitle: str, optional window title

        """
        BaseBackend.__init__(self, win)

        # window to share a context with
        share_win = kwargs.get('share', None)
        if share_win is not None:
            if share_win.winType == 'glfw':
                share_context = share_win.winHandle
            else:
                logging.warning(
                    'Cannot share a context with a non-GLFW window. Disabling.'
                )
                share_context = None
        else:
            share_context = None

        if sys.platform == 'darwin' and not win.useRetina and pyglet.version >= "1.3":
            raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be "
                             "set to useRetina=True (or remove the argument). "
                             "Pyglet 1.3 appears to be forcing "
                             "us to use retina on any retina-capable screen "
                             "so setting to False has no effect.")

        # window framebuffer configuration
        win.bpc = kwargs.get('bpc', (8, 8, 8))  # nearly all displays use 8 bpc
        win.refreshHz = int(kwargs.get('refreshHz', 60))
        win.depthBits = int(kwargs.get('depthBits', 8))
        win.stencilBits = int(kwargs.get('stencilBits', 8))

        # TODO - make waitBlanking set this too, independent right now
        win.swapInterval = int(kwargs.get('swapInterval', 1))  # vsync ON if 1

        # get monitors, with GLFW the primary display is ALWAYS at index 0
        allScrs = glfw.get_monitors()
        if len(allScrs) < int(win.screen) + 1:
            logging.warn("Requested an unavailable screen number - "
                         "using first available.")
            win.screen = 0

        this_screen = allScrs[win.screen]
        if win.autoLog:
            logging.info('configured GLFW screen %i' % win.screen)

        # find a matching video mode (can we even support this configuration?)
        vidmode_is_supported = False
        for vidmode in glfw.get_video_modes(this_screen):
            _size, _bpc, _hz = vidmode
            if win._isFullScr:  # size and refresh rate are ignored if windowed
                has_size = _size == tuple(win.size)
                has_hz = _hz == win.refreshHz
            else:
                has_size = has_hz = True
            has_bpc = _bpc == tuple(win.bpc)
            if has_size and has_bpc and has_hz:
                vidmode_is_supported = True
                break

        _size, _bpc, _hz = glfw.get_video_mode(this_screen)
        if not vidmode_is_supported:
            # the requested video mode is not supported, use current
            logging.warning(
                ("The specified video mode is not supported by this display, "
                 "using native mode ..."))
            logging.warning(
                ("Overriding user video settings: size {} -> {}, bpc {} -> "
                 "{}, refreshHz {} -> {}".format(tuple(win.size), _size,
                                                 tuple(win.bpc), _bpc,
                                                 win.refreshHz, _hz)))
            # change the window settings
            win.bpc = _bpc
            win.refreshHz = _hz
            win.size = _size

        if win._isFullScr:
            use_display = this_screen
        else:
            use_display = None

        # configure stereo
        use_stereo = 0
        if win.stereo:
            # provide warning if stereo buffers are requested but unavailable
            if not glfw.extension_supported('GL_STEREO'):
                logging.warning(
                    'A stereo window was requested but the graphics '
                    'card does not appear to support GL_STEREO')
                win.stereo = False
            else:
                use_stereo = 1

        # setup multisampling
        # This enables multisampling on the window backbuffer, not on other
        # framebuffers.
        msaa_samples = 0
        if win.multiSample:
            max_samples = (GL.GLint)()
            GL.glGetIntegerv(GL.GL_MAX_SAMPLES, max_samples)
            if (win.numSamples & (win.numSamples - 1)) != 0:
                # power of two?
                logging.warning(
                    'Invalid number of MSAA samples provided, must be '
                    'power of two. Disabling.')
            elif 0 > win.numSamples > max_samples.value:
                # check if within range
                logging.warning(
                    'Invalid number of MSAA samples provided, outside of valid '
                    'range. Disabling.')
            else:
                msaa_samples = win.numSamples
        win.multiSample = msaa_samples > 0

        # disable stencil buffer
        if win.allowStencil:
            win.stencilBits = 0

        # set buffer configuration hints
        glfw.window_hint(glfw.RED_BITS, win.bpc[0])
        glfw.window_hint(glfw.GREEN_BITS, win.bpc[1])
        glfw.window_hint(glfw.BLUE_BITS, win.bpc[2])
        glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz)
        glfw.window_hint(glfw.STEREO, use_stereo)
        glfw.window_hint(glfw.SAMPLES, msaa_samples)
        glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits)
        glfw.window_hint(glfw.DEPTH_BITS, win.depthBits)

        # window appearance and behaviour hints
        if not win.allowGUI:
            glfw.window_hint(glfw.DECORATED, 0)
        glfw.window_hint(glfw.AUTO_ICONIFY, 0)

        # window title
        title_text = str(kwargs.get('winTitle', "PsychoPy (GLFW)"))

        # create the window
        self.winHandle = glfw.create_window(width=win.size[0],
                                            height=win.size[1],
                                            title=title_text,
                                            monitor=use_display,
                                            share=share_context)

        # set the window icon
        glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_)

        # The window's user pointer maps the Python Window object to its GLFW
        # representation.
        glfw.set_window_user_pointer(self.winHandle, win)
        glfw.make_context_current(self.winHandle)  # ready to use

        # set the window size to the framebuffer size
        win.size = np.array(glfw.get_framebuffer_size(self.winHandle))

        if win.useFBO:  # check for necessary extensions
            if not glfw.extension_supported('GL_EXT_framebuffer_object'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_EXT_framebuffer_object is not supported. Disabled")
                logging.warn(msg)
                win.useFBO = False
            if not glfw.extension_supported('GL_ARB_texture_float'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_ARB_texture_float is not supported. Disabling")
                logging.warn(msg)
                win.useFBO = False

        # Assign event callbacks, these are dispatched when 'poll_events' is
        # called.
        glfw.set_mouse_button_callback(self.winHandle,
                                       event._onGLFWMouseButton)
        glfw.set_scroll_callback(self.winHandle, event._onGLFWMouseScroll)
        glfw.set_key_callback(self.winHandle, event._onGLFWKey)
        glfw.set_char_mods_callback(self.winHandle, event._onGLFWText)

        # enable vsync, GLFW has additional setting for this that might be
        # useful.
        glfw.swap_interval(win.swapInterval)

        # give the window class GLFW specific methods
        win.setMouseType = self.setMouseType
        if not win.allowGUI:
            self.setMouseVisibility(False)

        #glfw.set_window_size_callback(self.winHandle, _onResize)
        #self.winHandle.on_resize = _onResize  # avoid circular reference

        # TODO - handle window resizing

        # Set the position of the window if not fullscreen.
        if not win.pos:
            # work out where the centre should be
            win.pos = [(_size[0] - win.size[0]) / 2.0,
                       (_size[1] - win.size[1]) / 2.0]
        if not win._isFullScr:
            # get the virtual position of the monitor, apply offset to pos
            _px, _py = glfw.get_monitor_pos(this_screen)
            glfw.set_window_pos(self.winHandle, int(win.pos[0] + _px),
                                int(win.pos[1] + _py))
Пример #4
0
    def __init__(self, win, *args, **kwargs):
        """Set up the backend window according the params of the PsychoPy win

        Before PsychoPy 1.90.0 this code was executed in Window._setupPygame()

        Parameters
        ----------
        win : psychopy.visual.Window instance
            PsychoPy Window (usually not fully created yet).
        share : psychopy.visual.Window instance
            PsychoPy Window to share a context with
        bpc : array_like
            Bits per color (R, G, B).
        refreshHz : int
            Refresh rate in Hertz.
        depthBits : int,
            Framebuffer (back buffer) depth bits.
        swapInterval : int
            Swap interval for the current OpenGL context.
        stencilBits : int
            Framebuffer (back buffer) stencil bits.
        winTitle : str
            Optional window title string.
        *args
            Additional position arguments.
        **kwargs
            Additional keyword arguments.

        """
        BaseBackend.__init__(self, win)

        # window to share a context with
        shareWin = kwargs.get('share', None)
        if shareWin is not None:
            if shareWin.winType == 'glfw':
                shareContext = shareWin.winHandle
            else:
                logging.warning(
                    'Cannot share a context with a non-GLFW window. Disabling.')
                shareContext = None
        else:
            shareContext = None

        if sys.platform=='darwin' and not win.useRetina and pyglet.version >= "1.3":
            raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be "
                             "set to useRetina=True (or remove the argument). "
                             "Pyglet 1.3 appears to be forcing "
                             "us to use retina on any retina-capable screen "
                             "so setting to False has no effect.")

        # window framebuffer configuration
        win.bpc = kwargs.get('bpc', (8, 8, 8))  # nearly all displays use 8 bpc
        win.refreshHz = int(kwargs.get('refreshHz', 60))
        win.depthBits = int(kwargs.get('depthBits', 8))
        win.stencilBits = int(kwargs.get('stencilBits', 8))
        # win.swapInterval = int(kwargs.get('swapInterval', 1))  # vsync ON if 1

        # get monitors, with GLFW the primary display is ALWAYS at index 0
        allScrs = glfw.get_monitors()
        if len(allScrs) < int(win.screen) + 1:
            logging.warn("Requested an unavailable screen number - "
                         "using first available.")
            win.screen = 0

        thisScreen = allScrs[win.screen]
        if win.autoLog:
            logging.info('configured GLFW screen %i' % win.screen)

        # find a matching video mode (can we even support this configuration?)
        isVidmodeSupported = False
        for vidmode in glfw.get_video_modes(thisScreen):
            size, bpc, hz = vidmode
            if win._isFullScr:  # size and refresh rate are ignored if windowed
                hasSize = size == tuple(win.size)
                hasHz = hz == win.refreshHz
            else:
                hasSize = hasHz = True
            hasBpc = bpc == tuple(win.bpc)
            if hasSize and hasBpc and hasHz:
                isVidmodeSupported = True
                break

        nativeVidmode = glfw.get_video_mode(thisScreen)
        if not isVidmodeSupported:
            # the requested video mode is not supported, use current

            logging.warning(
                ("The specified video mode is not supported by this display, "
                 "using native mode ..."))
            logging.warning(
                ("Overriding user video settings: size {} -> {}, bpc {} -> "
                 "{}, refreshHz {} -> {}".format(
                    tuple(win.size),
                    nativeVidmode[0],
                    tuple(win.bpc),
                    nativeVidmode[1],
                    win.refreshHz,
                    nativeVidmode[2])))

            # change the window settings
            win.size, win.bpc, win.refreshHz = nativeVidmode

        if win._isFullScr:
            useDisplay = thisScreen
        else:
            useDisplay = None

        # configure stereo
        useStereo = 0
        if win.stereo:
            # provide warning if stereo buffers are requested but unavailable
            if not glfw.extension_supported('GL_STEREO'):
                logging.warning(
                    'A stereo window was requested but the graphics '
                    'card does not appear to support GL_STEREO')
                win.stereo = False
            else:
                useStereo = 1

        # setup multisampling
        # This enables multisampling on the window backbuffer, not on other
        # framebuffers.
        msaaSamples = 0
        if win.multiSample:
            maxSamples = (GL.GLint)()
            GL.glGetIntegerv(GL.GL_MAX_SAMPLES, maxSamples)
            if (win.numSamples & (win.numSamples - 1)) != 0:
                # power of two?
                logging.warning(
                    'Invalid number of MSAA samples provided, must be '
                    'power of two. Disabling.')
            elif 0 > win.numSamples > maxSamples.value:
                # check if within range
                logging.warning(
                    'Invalid number of MSAA samples provided, outside of valid '
                    'range. Disabling.')
            else:
                msaaSamples = win.numSamples
        win.multiSample = msaaSamples > 0

        # disable stencil buffer
        if not win.allowStencil:
            win.stencilBits = 0

        # set buffer configuration hints
        glfw.window_hint(glfw.RED_BITS, win.bpc[0])
        glfw.window_hint(glfw.GREEN_BITS, win.bpc[1])
        glfw.window_hint(glfw.BLUE_BITS, win.bpc[2])
        glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz)
        glfw.window_hint(glfw.STEREO, useStereo)
        glfw.window_hint(glfw.SAMPLES, msaaSamples)
        glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits)
        glfw.window_hint(glfw.DEPTH_BITS, win.depthBits)
        glfw.window_hint(glfw.AUTO_ICONIFY, 0)

        # window appearance and behaviour hints
        if not win.allowGUI:
            glfw.window_hint(glfw.DECORATED, 0)

        # create the window
        self.winHandle = glfw.create_window(
            width=win.size[0],
            height=win.size[1],
            title=str(kwargs.get('winTitle', "PsychoPy (GLFW)")),
            monitor=useDisplay,
            share=shareContext)

        # The window's user pointer maps the Python Window object to its GLFW
        # representation.
        glfw.set_window_user_pointer(self.winHandle, win)
        glfw.make_context_current(self.winHandle)  # ready to use

        # set the position of the window if not fullscreen
        if not win._isFullScr:
            # if no window position is specified, centre it on-screen
            if win.pos is None:
                size, bpc, hz = nativeVidmode
                win.pos = [(size[0] - win.size[0]) / 2.0,
                           (size[1] - win.size[1]) / 2.0]

            # get the virtual position of the monitor, apply offset to the
            # window position
            px, py = glfw.get_monitor_pos(thisScreen)
            glfw.set_window_pos(self.winHandle,
                                int(win.pos[0] + px),
                                int(win.pos[1] + py))

        elif win._isFullScr and win.pos is not None:
            logging.warn("Ignoring window 'pos' in fullscreen mode.")

        # set the window icon
        glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_)

        # set the window size to the framebuffer size
        win.size = np.array(glfw.get_framebuffer_size(self.winHandle))

        if win.useFBO:  # check for necessary extensions
            if not glfw.extension_supported('GL_EXT_framebuffer_object'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_EXT_framebuffer_object is not supported. Disabled")
                logging.warn(msg)
                win.useFBO = False
            if not glfw.extension_supported('GL_ARB_texture_float'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_ARB_texture_float is not supported. Disabling")
                logging.warn(msg)
                win.useFBO = False

        # Assign event callbacks, these are dispatched when 'poll_events' is
        # called.
        glfw.set_mouse_button_callback(self.winHandle, event._onGLFWMouseButton)
        glfw.set_scroll_callback(self.winHandle, event._onGLFWMouseScroll)
        glfw.set_key_callback(self.winHandle, event._onGLFWKey)
        glfw.set_char_mods_callback(self.winHandle, event._onGLFWText)

        # set swap interval to manual setting, independent of waitBlanking
        self.setSwapInterval(int(kwargs.get('swapInterval', 1)))

        # give the window class GLFW specific methods
        win.setMouseType = self.setMouseType
        if not win.allowGUI:
            self.setMouseVisibility(False)
Пример #5
0
    def __init__(self,
                 width=800,
                 height=600,
                 title="QLibs window",
                 swap_interval=1,
                 hint_conf=default_hint_conf,
                 resizable=True,
                 fullscreen=False,
                 transparent=False):
        self.width = width
        self.height = height
        self.resize_callback = None
        self.mouse_motion_callback = None
        self.mouse_button_callback = None
        self.scroll_callback = None
        self.key_callback = None
        self.spec_key_callback = None
        self.flip_mouse_y = False  #flipped relatively to usual math-y representation

        glfw.init()
        glfw.window_hint(glfw.RESIZABLE, resizable and not fullscreen)
        glfw.window_hint(glfw.TRANSPARENT_FRAMEBUFFER, transparent)
        for k, v in hint_conf.items():
            glfw.window_hint(k, v)
        monitor = None
        if fullscreen:
            monitor = glfw.get_primary_monitor()
            mode = glfw.get_video_mode(monitor)
            width = mode.size.width
            height = mode.size.height
            #width = 1920
            #height = 1080
            glfw.window_hint(glfw.RED_BITS, mode.bits.red)
            glfw.window_hint(glfw.GREEN_BITS, mode.bits.green)
            glfw.window_hint(glfw.BLUE_BITS, mode.bits.blue)
            glfw.window_hint(glfw.REFRESH_RATE, mode.refresh_rate)

        try:
            self.window = glfw.create_window(width, height, title, monitor,
                                             None)
        except glfw.GLFWError:
            logger.warn(
                "Provided config is unavailable, using fallback config")
            glfw.default_window_hints()
            for k, v in fallback_hint_conf.items():
                glfw.window_hint(k, v)
            self.window = glfw.create_window(width, height, title, None, None)

        if fullscreen:
            self.width, self.height = glfw.get_framebuffer_size(
                self.window)  #Required on windows

        glfw.set_window_user_pointer(self.window, id(self.window))
        glfw.make_context_current(self.window)
        glfw.swap_interval(swap_interval)
        #callbacks
        glfw.set_window_size_callback(self.window, self._on_resize)
        glfw.set_framebuffer_size_callback(self.window, self._update_viewport)
        glfw.set_cursor_pos_callback(self.window, self._on_mouse_motion)
        glfw.set_mouse_button_callback(self.window, self._on_mouse_button)
        glfw.set_char_mods_callback(self.window, self._on_key_press)
        glfw.set_key_callback(self.window, self._on_spec_key_press)
        glfw.set_scroll_callback(self.window, self._on_scroll)

        try:
            self.ctx = moderngl.create_context()
        except:
            self.ctx = moderngl.create_context(libgl='libGL.so.1')
Пример #6
0
    def __init__(self, win, backendConf=None):
        """Set up the backend window according the params of the PsychoPy win

        Before PsychoPy 1.90.0 this code was executed in Window._setupPygame()

        Parameters
        ----------
        win : `psychopy.visual.Window` instance
            PsychoPy Window (usually not fully created yet).
        backendConf : `dict` or `None`
            Backend configuration options. Options are specified as a dictionary
            where keys are option names and values are settings. For this
            backend the following options are available:

            * `share` (`psychopy.visual.Window instance`) PsychoPy Window to
              share a context with.
            * `refreshHz` (`int`) Refresh rate in Hertz.
            * `bpc` (`array_like`) Bits per color (R, G, B).
            * `swapInterval` (`int`) Swap interval for the current OpenGL
              context.
            * `depthBits` (`int`) Framebuffer (back buffer) depth bits.
            * `stencilBits` (`int`) Framebuffer (back buffer) stencil bits.
            * `winTitle` (`str`) Optional window title string.

        Examples
        --------
        Create a window using the GLFW backend and specify custom options::

            import psychopy.visual as visual

            options = {'bpc': (8, 8, 8), 'depthBits': 24, 'stencilBits': 8}
            win = visual.Window(winType='glfw', backendOptions=options)

        """
        BaseBackend.__init__(self, win)

        # if `None`, change to `dict` to extract options
        backendConf = backendConf if backendConf is not None else {}

        if not isinstance(backendConf, dict):  # type check on options
            raise TypeError(
                'Object passed to `backendConf` must be type `dict`.')

        # window to share a context with
        shareWin = backendConf.get('share', None)
        if shareWin is not None:
            if shareWin.winType == 'glfw':
                shareContext = shareWin.winHandle
            else:
                logging.warning(
                    'Cannot share a context with a non-GLFW window. Disabling.')
                shareContext = None
        else:
            shareContext = None

        if sys.platform=='darwin' and not win.useRetina and pyglet.version >= "1.3":
            raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be "
                             "set to useRetina=True (or remove the argument). "
                             "Pyglet 1.3 appears to be forcing "
                             "us to use retina on any retina-capable screen "
                             "so setting to False has no effect.")

        # window framebuffer configuration
        bpc = backendConf.get('bpc', (8, 8, 8))
        if isinstance(bpc, int):
            win.bpc = (bpc, bpc, bpc)
        else:
            win.bpc = bpc

        win.refreshHz = int(backendConf.get('refreshHz', 60))
        win.depthBits = int(backendConf.get('depthBits', 8))
        win.stencilBits = int(backendConf.get('stencilBits', 8))
        # win.swapInterval = int(backendConf.get('swapInterval', 1))  # vsync ON if 1

        # get monitors, with GLFW the primary display is ALWAYS at index 0
        allScrs = glfw.get_monitors()
        if len(allScrs) < int(win.screen) + 1:
            logging.warn("Requested an unavailable screen number - "
                         "using first available.")
            win.screen = 0

        thisScreen = allScrs[win.screen]
        if win.autoLog:
            logging.info('configured GLFW screen %i' % win.screen)

        # find a matching video mode (can we even support this configuration?)
        isVidmodeSupported = False
        for vidmode in glfw.get_video_modes(thisScreen):
            size, bpc, hz = vidmode
            if win._isFullScr:  # size and refresh rate are ignored if windowed
                hasSize = size == tuple(win.size)
                hasHz = hz == win.refreshHz
            else:
                hasSize = hasHz = True
            hasBpc = bpc == tuple(win.bpc)
            if hasSize and hasBpc and hasHz:
                isVidmodeSupported = True
                break

        nativeVidmode = glfw.get_video_mode(thisScreen)
        if not isVidmodeSupported:
            # the requested video mode is not supported, use current

            logging.warning(
                ("The specified video mode is not supported by this display, "
                 "using native mode ..."))

            actualWidth, actualHeight = nativeVidmode.size
            redBits, greenBits, blueBits = nativeVidmode.bits
            # change the window settings
            if win._isFullScr:
                logging.warning(
                    ("Overriding user video settings: size {} -> {}, bpc {} -> "
                     "{}, refreshHz {} -> {}".format(
                        tuple(win.size),
                        (actualWidth, actualHeight),
                        tuple(win.bpc),
                        (redBits, greenBits, blueBits),
                        win.refreshHz,
                        nativeVidmode.refresh_rate)))

                win.clientSize = np.array((actualWidth, actualHeight), int)
            else:
                logging.warning(
                    ("Overriding user video settings: bpc {} -> "
                     "{}, refreshHz {} -> {}".format(
                        tuple(win.bpc),
                        (redBits, greenBits, blueBits),
                        win.refreshHz,
                        nativeVidmode.refresh_rate)))

            win.bpc = (redBits, greenBits, blueBits)
            win.refreshHz = nativeVidmode.refresh_rate

        if win._isFullScr:
            useDisplay = thisScreen
        else:
            useDisplay = None

        # configure stereo
        useStereo = 0
        if win.stereo:
            # provide warning if stereo buffers are requested but unavailable
            if not glfw.extension_supported('GL_STEREO'):
                logging.warning(
                    'A stereo window was requested but the graphics '
                    'card does not appear to support GL_STEREO')
                win.stereo = False
            else:
                useStereo = 1

        # setup multisampling
        # This enables multisampling on the window backbuffer, not on other
        # framebuffers.
        msaaSamples = 0
        if win.multiSample:
            maxSamples = (GL.GLint)()
            GL.glGetIntegerv(GL.GL_MAX_SAMPLES, maxSamples)
            if (win.numSamples & (win.numSamples - 1)) != 0:
                # power of two?
                logging.warning(
                    'Invalid number of MSAA samples provided, must be '
                    'power of two. Disabling.')
            elif 0 > win.numSamples > maxSamples.value:
                # check if within range
                logging.warning(
                    'Invalid number of MSAA samples provided, outside of valid '
                    'range. Disabling.')
            else:
                msaaSamples = win.numSamples
        win.multiSample = msaaSamples > 0

        # disable stencil buffer
        if not win.allowStencil:
            win.stencilBits = 0

        # set buffer configuration hints
        glfw.window_hint(glfw.RED_BITS, win.bpc[0])
        glfw.window_hint(glfw.GREEN_BITS, win.bpc[1])
        glfw.window_hint(glfw.BLUE_BITS, win.bpc[2])
        glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz)
        glfw.window_hint(glfw.STEREO, useStereo)
        glfw.window_hint(glfw.SAMPLES, msaaSamples)
        glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits)
        glfw.window_hint(glfw.DEPTH_BITS, win.depthBits)
        glfw.window_hint(glfw.AUTO_ICONIFY, 0)

        # window appearance and behaviour hints
        if not win.allowGUI:
            glfw.window_hint(glfw.DECORATED, 0)

        # create the window
        self.winHandle = glfw.create_window(
            width=win.clientSize[0],
            height=win.clientSize[1],
            title=str(backendConf.get('winTitle', "PsychoPy (GLFW)")),
            monitor=useDisplay,
            share=shareContext)

        # The window's user pointer maps the Python Window object to its GLFW
        # representation.
        glfw.set_window_user_pointer(self.winHandle, win)
        glfw.make_context_current(self.winHandle)  # ready to use

        # set the position of the window if not fullscreen
        if not win._isFullScr:
            # if no window position is specified, centre it on-screen
            if win.pos is None:
                size, bpc, hz = nativeVidmode
                win.pos = [(size[0] - win.clientSize[0]) / 2.0,
                           (size[1] - win.clientSize[1]) / 2.0]

            # get the virtual position of the monitor, apply offset to the
            # window position
            px, py = glfw.get_monitor_pos(thisScreen)
            glfw.set_window_pos(self.winHandle,
                                int(win.pos[0] + px),
                                int(win.pos[1] + py))

        elif win._isFullScr and win.pos is not None:
            logging.warn("Ignoring window 'pos' in fullscreen mode.")

        # set the window icon
        if hasattr(glfw, 'set_window_icon'):
            glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_)

        # set the window size to the framebuffer size
        self._frameBufferSize = np.array(glfw.get_framebuffer_size(self.winHandle))

        if win.useFBO:  # check for necessary extensions
            if not glfw.extension_supported('GL_EXT_framebuffer_object'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_EXT_framebuffer_object is not supported. Disabled")
                logging.warn(msg)
                win.useFBO = False
            if not glfw.extension_supported('GL_ARB_texture_float'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_ARB_texture_float is not supported. Disabling")
                logging.warn(msg)
                win.useFBO = False

        # Assign event callbacks, these are dispatched when 'poll_events' is
        # called.
        glfw.set_mouse_button_callback(self.winHandle, self.onMouseButton)
        glfw.set_cursor_pos_callback(self.winHandle, self.onMouseMove)
        glfw.set_cursor_enter_callback(self.winHandle, self.onMouseEnter)
        glfw.set_scroll_callback(self.winHandle, self.onMouseScroll)
        glfw.set_key_callback(self.winHandle, event._onGLFWKey)
        glfw.set_char_mods_callback(self.winHandle, event._onGLFWText)

        # set swap interval to manual setting, independent of waitBlanking
        self.setSwapInterval(int(backendConf.get('swapInterval', 1)))

        # give the window class GLFW specific methods
        win.setMouseType = self.setMouseType
        if not win.allowGUI:
            self.setMouseVisibility(False)