Esempio n. 1
0
 def _restart_with_recording(rec_dir):
     logger.debug("Starting new session with '{}'".format(rec_dir))
     ipc_pub.notify({
         "subject": "player_drop_process.should_start",
         "rec_dir": rec_dir
     })
     glfw.glfwSetWindowShouldClose(g_pool.main_window, True)
Esempio n. 2
0
 def reset_restart():
     logger.warning("Resetting all settings and restarting Capture.")
     glfw.glfwSetWindowShouldClose(main_window, True)
     ipc_pub.notify({'subject': 'clear_settings_process.should_start'})
     ipc_pub.notify({
         'subject': 'world_process.should_start',
         'delay': 2.
     })
Esempio n. 3
0
 def reset_restart():
     logger.warning("Resetting all settings and restarting Capture.")
     glfw.glfwSetWindowShouldClose(main_window, True)
     self.notify_all({"subject": "clear_settings_process.should_start"})
     self.notify_all({
         "subject": "service_process.should_start",
         "delay": 2.0
     })
Esempio n. 4
0
 def reset_restart():
     logger.warning("Resetting all settings and restarting Player.")
     glfw.glfwSetWindowShouldClose(main_window, True)
     ipc_pub.notify({"subject": "clear_settings_process.should_start"})
     ipc_pub.notify({
         "subject": "player_process.should_start",
         "rec_dir": rec_dir,
         "delay": 2.0,
     })
Esempio n. 5
0
def processInput(window):
    if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS:
        glfw.glfwSetWindowShouldClose()

    if glfw.get_key(window, glfw.KEY_LEFT) == glfw.PRESS:
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)

    if glfw.get_key(window, glfw.KEY_RIGHT) == glfw.PRESS:
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
Esempio n. 6
0
 def on_drop(window, count, paths):
     for x in range(count):
         new_rec_dir = paths[x].decode('utf-8')
         if is_pupil_rec_dir(new_rec_dir):
             logger.debug("Starting new session with '{}'".format(new_rec_dir))
             ipc_pub.notify({"subject": "player_drop_process.should_start", "rec_dir": new_rec_dir})
             glfw.glfwSetWindowShouldClose(window, True)
         else:
             logger.error("'{}' is not a valid pupil recording".format(new_rec_dir))
Esempio n. 7
0
 def on_drop(window, count, paths):
     for x in range(count):
         new_rec_dir = paths[x].decode('utf-8')
         if is_pupil_rec_dir(new_rec_dir):
             logger.debug("Starting new session with '{}'".format(new_rec_dir))
             ipc_pub.notify({"subject": "player_drop_process.should_start", "rec_dir": new_rec_dir})
             glfw.glfwSetWindowShouldClose(window, True)
         else:
             logger.error("'{}' is not a valid pupil recording".format(new_rec_dir))
Esempio n. 8
0
 def reset_restart():
     logger.warning("Resetting all settings and restarting Player.")
     glfw.glfwSetWindowShouldClose(main_window, True)
     ipc_pub.notify({"subject": "clear_settings_process.should_start"})
     ipc_pub.notify(
         {
             "subject": "player_process.should_start",
             "rec_dir": rec_dir,
             "delay": 2.0,
         }
     )
Esempio n. 9
0
 def on_key(self, window, key, scancode, action, mods):
     ### pass keypress events to CEGUI
     if PyCEGUI.System.getSingleton():
         cegui_key = KEYMAPPINGS[key]
         if (not cegui_key==PyCEGUI.Key.Unknown):
             if (action == glfw.GLFW_PRESS):
                PyCEGUI.System.getSingleton().getDefaultGUIContext().injectKeyDown(PyCEGUI.Key.Scan(cegui_key))
             if (action == glfw.GLFW_RELEASE):
                 PyCEGUI.System.getSingleton().getDefaultGUIContext().injectKeyUp(PyCEGUI.Key.Scan(cegui_key))
     ## exit
     if key == glfw.GLFW_KEY_ESCAPE and action == glfw.GLFW_PRESS:
         glfw.glfwSetWindowShouldClose(window,1)
Esempio n. 10
0
 def run(self):
     while 1:
         shouldClose = glfw.glfwWindowShouldClose(self.glfwWindow)
         if shouldClose:
             if self.okToExit():
                 break
             else:
                 glfw.glfwSetWindowShouldClose(self.glfwWindow, 0)
         if self._drawNeeded:
             if self._isFull:
                 glfw.glfwMakeContextCurrent(self.glfwFullscreenWindow)
             else:
                 glfw.glfwMakeContextCurrent(self.glfwWindow)
             self.__draw()
             if self._isFull:
                 glfw.glfwSwapBuffers(self.glfwFullscreenWindow)
             else:
                 glfw.glfwSwapBuffers(self.glfwWindow)
             self._drawNeeded = False
         glfw.glfwPollEvents()
         self.__idle()
     glfw.glfwTerminate()
Esempio n. 11
0
 def on_key(window, key, scancode, action, mods):
     if key == glfw.GLFW_KEY_ESCAPE and action == glfw.GLFW_PRESS:
         glfw.glfwSetWindowShouldClose(window,1)
Esempio n. 12
0
 def reset_restart():
     logger.warning("Resetting all settings and restarting Capture.")
     glfw.glfwSetWindowShouldClose(main_window, True)
     ipc_pub.notify({'subject': 'reset_restart_process.should_start'})
Esempio n. 13
0
 def close(self):
     glfw.glfwSetWindowShouldClose(self.glfwWindow, 1)
Esempio n. 14
0
 def reset_restart():
     logger.warning("Resetting all settings and restarting Capture.")
     glfw.glfwSetWindowShouldClose(main_window, True)
     self.notify_all({"subject": "clear_settings_process.should_start"})
     self.notify_all({"subject": "service_process.should_start", "delay": 2.0})
Esempio n. 15
0
 def on_key(window, key, scancode, action, mods):
     if key == glfw.GLFW_KEY_ESCAPE and action == glfw.GLFW_PRESS:
         glfw.glfwSetWindowShouldClose(window,1)
Esempio n. 16
0
def player_drop(rec_dir, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir,
                app_version, debug):
    # general imports
    import logging

    # networking
    import zmq
    import zmq_tools
    from time import sleep

    # zmq ipc setup
    zmq_ctx = zmq.Context()
    ipc_pub = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url)

    # log setup
    logging.getLogger("OpenGL").setLevel(logging.ERROR)
    logger = logging.getLogger()
    logger.handlers = []
    logger.setLevel(logging.INFO)
    logger.addHandler(zmq_tools.ZMQ_handler(zmq_ctx, ipc_push_url))
    # create logger for the context of this function
    logger = logging.getLogger(__name__)

    try:
        import glfw
        import gl_utils
        from OpenGL.GL import glClearColor
        from version_utils import VersionFormat
        from file_methods import Persistent_Dict
        from pyglui.pyfontstash import fontstash
        from pyglui.ui import get_roboto_font_path
        import player_methods as pm
        from pupil_recording import (
            assert_valid_recording_type,
            InvalidRecordingException,
        )
        from pupil_recording.update import update_recording

        process_was_interrupted = False

        def interrupt_handler(sig, frame):
            import traceback

            trace = traceback.format_stack(f=frame)
            logger.debug(f"Caught signal {sig} in:\n" + "".join(trace))
            nonlocal process_was_interrupted
            process_was_interrupted = True

        signal.signal(signal.SIGINT, interrupt_handler)

        def on_drop(window, count, paths):
            nonlocal rec_dir
            rec_dir = paths[0].decode("utf-8")

        if rec_dir:
            try:
                assert_valid_recording_type(rec_dir)
            except InvalidRecordingException as err:
                logger.error(str(err))
                rec_dir = None
        # load session persistent settings
        session_settings = Persistent_Dict(
            os.path.join(user_dir, "user_settings_player"))
        if VersionFormat(session_settings.get("version",
                                              "0.0")) != app_version:
            logger.info(
                "Session setting are from a  different version of this app. I will not use those."
            )
            session_settings.clear()
        w, h = session_settings.get("window_size", (1280, 720))
        window_pos = session_settings.get("window_position",
                                          window_position_default)

        glfw.glfwInit()
        glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, 0)
        window = glfw.glfwCreateWindow(w, h, "Pupil Player")
        glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, 1)

        glfw.glfwMakeContextCurrent(window)
        glfw.glfwSetWindowPos(window, window_pos[0], window_pos[1])
        glfw.glfwSetDropCallback(window, on_drop)

        glfont = fontstash.Context()
        glfont.add_font("roboto", get_roboto_font_path())
        glfont.set_align_string(v_align="center", h_align="middle")
        glfont.set_color_float((0.2, 0.2, 0.2, 0.9))
        gl_utils.basic_gl_setup()
        glClearColor(0.5, 0.5, 0.5, 0.0)
        text = "Drop a recording directory onto this window."
        tip = "(Tip: You can drop a recording directory onto the app icon.)"

        # text = "Please supply a Pupil recording directory as first arg when calling Pupil Player."

        def display_string(string, font_size, center_y):
            x = w / 2 * hdpi_factor
            y = center_y * hdpi_factor

            glfont.set_size(font_size * hdpi_factor)

            glfont.set_blur(10.5)
            glfont.set_color_float((0.0, 0.0, 0.0, 1.0))
            glfont.draw_text(x, y, string)

            glfont.set_blur(0.96)
            glfont.set_color_float((1.0, 1.0, 1.0, 1.0))
            glfont.draw_text(x, y, string)

        while not glfw.glfwWindowShouldClose(
                window) and not process_was_interrupted:

            fb_size = glfw.glfwGetFramebufferSize(window)
            hdpi_factor = glfw.getHDPIFactor(window)
            gl_utils.adjust_gl_view(*fb_size)

            if rec_dir:
                try:
                    assert_valid_recording_type(rec_dir)
                    logger.info(
                        "Starting new session with '{}'".format(rec_dir))
                    text = "Updating recording format."
                    tip = "This may take a while!"
                except InvalidRecordingException as err:
                    logger.error(str(err))
                    if err.recovery:
                        text = err.reason
                        tip = err.recovery
                    else:
                        text = "Invalid recording"
                        tip = err.reason
                    rec_dir = None

            gl_utils.clear_gl_screen()

            display_string(text, font_size=51, center_y=216)
            for idx, line in enumerate(tip.split("\n")):
                tip_font_size = 42
                center_y = 288 + tip_font_size * idx * 1.2
                display_string(line,
                               font_size=tip_font_size,
                               center_y=center_y)

            glfw.glfwSwapBuffers(window)

            if rec_dir:
                try:
                    update_recording(rec_dir)
                except AssertionError as err:
                    logger.error(str(err))
                    tip = "Oops! There was an error updating the recording."
                    rec_dir = None
                except InvalidRecordingException as err:
                    logger.error(str(err))
                    if err.recovery:
                        text = err.reason
                        tip = err.recovery
                    else:
                        text = "Invalid recording"
                        tip = err.reason
                    rec_dir = None
                else:
                    glfw.glfwSetWindowShouldClose(window, True)

            glfw.glfwPollEvents()

        session_settings["window_position"] = glfw.glfwGetWindowPos(window)
        session_settings.close()
        glfw.glfwDestroyWindow(window)
        if rec_dir:
            ipc_pub.notify({
                "subject": "player_process.should_start",
                "rec_dir": rec_dir
            })

    except Exception:
        import traceback

        trace = traceback.format_exc()
        logger.error(
            "Process player_drop crashed with trace:\n{}".format(trace))

    finally:
        sleep(1.0)
Esempio n. 17
0
 def _restart_with_recording(rec_dir):
     logger.debug("Starting new session with '{}'".format(rec_dir))
     ipc_pub.notify(
         {"subject": "player_drop_process.should_start", "rec_dir": rec_dir}
     )
     glfw.glfwSetWindowShouldClose(g_pool.main_window, True)
Esempio n. 18
0
def player_drop(rec_dir, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir,
                app_version):
    # general imports
    import logging
    # networking
    import zmq
    import zmq_tools
    from time import sleep

    # zmq ipc setup
    zmq_ctx = zmq.Context()
    ipc_pub = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url)

    # log setup
    logging.getLogger("OpenGL").setLevel(logging.ERROR)
    logger = logging.getLogger()
    logger.handlers = []
    logger.setLevel(logging.INFO)
    logger.addHandler(zmq_tools.ZMQ_handler(zmq_ctx, ipc_push_url))
    # create logger for the context of this function
    logger = logging.getLogger(__name__)

    try:

        import glfw
        import gl_utils
        from OpenGL.GL import glClearColor
        from version_utils import VersionFormat
        from file_methods import Persistent_Dict
        from pyglui.pyfontstash import fontstash
        from pyglui.ui import get_roboto_font_path
        from player_methods import is_pupil_rec_dir, update_recording_to_recent

        def on_drop(window, count, paths):
            nonlocal rec_dir
            rec_dir = paths[0].decode('utf-8')

        if rec_dir:
            if not is_pupil_rec_dir(rec_dir):
                rec_dir = None
        # load session persistent settings
        session_settings = Persistent_Dict(
            os.path.join(user_dir, "user_settings_player"))
        if VersionFormat(session_settings.get("version",
                                              '0.0')) != app_version:
            logger.info(
                "Session setting are from a  different version of this app. I will not use those."
            )
            session_settings.clear()
        w, h = session_settings.get('window_size', (1280, 720))
        window_pos = session_settings.get('window_position',
                                          window_position_default)

        glfw.glfwInit()
        glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, 0)
        window = glfw.glfwCreateWindow(w, h, 'Pupil Player')
        glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, 1)

        glfw.glfwMakeContextCurrent(window)
        glfw.glfwSetWindowPos(window, window_pos[0], window_pos[1])
        glfw.glfwSetDropCallback(window, on_drop)

        glfont = fontstash.Context()
        glfont.add_font('roboto', get_roboto_font_path())
        glfont.set_align_string(v_align="center", h_align="middle")
        glfont.set_color_float((0.2, 0.2, 0.2, 0.9))
        gl_utils.basic_gl_setup()
        glClearColor(0.5, .5, 0.5, 0.0)
        text = 'Drop a recording directory onto this window.'
        tip = '(Tip: You can drop a recording directory onto the app icon.)'
        # text = "Please supply a Pupil recording directory as first arg when calling Pupil Player."
        while not glfw.glfwWindowShouldClose(window):

            fb_size = glfw.glfwGetFramebufferSize(window)
            hdpi_factor = float(fb_size[0] / glfw.glfwGetWindowSize(window)[0])
            gl_utils.adjust_gl_view(*fb_size)

            if rec_dir:
                if is_pupil_rec_dir(rec_dir):
                    logger.info(
                        "Starting new session with '{}'".format(rec_dir))
                    text = "Updating recording format."
                    tip = "This may take a while!"
                else:
                    logger.error(
                        "'{}' is not a valid pupil recording".format(rec_dir))
                    tip = "Oops! That was not a valid recording."
                    rec_dir = None

            gl_utils.clear_gl_screen()
            glfont.set_blur(10.5)
            glfont.set_color_float((0.0, 0.0, 0.0, 1.))
            glfont.set_size(w / 25. * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, .3 * h * hdpi_factor, text)
            glfont.set_size(w / 30. * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, .4 * h * hdpi_factor, tip)
            glfont.set_blur(0.96)
            glfont.set_color_float((1., 1., 1., 1.))
            glfont.set_size(w / 25. * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, .3 * h * hdpi_factor, text)
            glfont.set_size(w / 30. * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, .4 * h * hdpi_factor, tip)

            glfw.glfwSwapBuffers(window)

            if rec_dir:
                update_recording_to_recent(rec_dir)
                glfw.glfwSetWindowShouldClose(window, True)

            glfw.glfwPollEvents()

        session_settings['window_position'] = glfw.glfwGetWindowPos(window)
        session_settings.close()
        glfw.glfwDestroyWindow(window)
        if rec_dir:
            ipc_pub.notify({
                "subject": "player_process.should_start",
                "rec_dir": rec_dir
            })

    except:
        import traceback
        trace = traceback.format_exc()
        logger.error(
            'Process player_drop crashed with trace:\n{}'.format(trace))

    finally:
        sleep(1.0)
Esempio n. 19
0
def player_drop(rec_dir, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir, app_version):
    # general imports
    import logging

    # networking
    import zmq
    import zmq_tools
    from time import sleep

    # zmq ipc setup
    zmq_ctx = zmq.Context()
    ipc_pub = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url)

    # log setup
    logging.getLogger("OpenGL").setLevel(logging.ERROR)
    logger = logging.getLogger()
    logger.handlers = []
    logger.setLevel(logging.INFO)
    logger.addHandler(zmq_tools.ZMQ_handler(zmq_ctx, ipc_push_url))
    # create logger for the context of this function
    logger = logging.getLogger(__name__)

    try:

        import glfw
        import gl_utils
        from OpenGL.GL import glClearColor
        from version_utils import VersionFormat
        from file_methods import Persistent_Dict
        from pyglui.pyfontstash import fontstash
        from pyglui.ui import get_roboto_font_path
        import player_methods as pm
        import update_methods as um

        def on_drop(window, count, paths):
            nonlocal rec_dir
            rec_dir = paths[0].decode("utf-8")

        if rec_dir:
            if not pm.is_pupil_rec_dir(rec_dir):
                rec_dir = None
        # load session persistent settings
        session_settings = Persistent_Dict(
            os.path.join(user_dir, "user_settings_player")
        )
        if VersionFormat(session_settings.get("version", "0.0")) != app_version:
            logger.info(
                "Session setting are from a  different version of this app. I will not use those."
            )
            session_settings.clear()
        w, h = session_settings.get("window_size", (1280, 720))
        window_pos = session_settings.get("window_position", window_position_default)

        glfw.glfwInit()
        glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, 0)
        window = glfw.glfwCreateWindow(w, h, "Pupil Player")
        glfw.glfwWindowHint(glfw.GLFW_RESIZABLE, 1)

        glfw.glfwMakeContextCurrent(window)
        glfw.glfwSetWindowPos(window, window_pos[0], window_pos[1])
        glfw.glfwSetDropCallback(window, on_drop)

        glfont = fontstash.Context()
        glfont.add_font("roboto", get_roboto_font_path())
        glfont.set_align_string(v_align="center", h_align="middle")
        glfont.set_color_float((0.2, 0.2, 0.2, 0.9))
        gl_utils.basic_gl_setup()
        glClearColor(0.5, 0.5, 0.5, 0.0)
        text = "Drop a recording directory onto this window."
        tip = "(Tip: You can drop a recording directory onto the app icon.)"
        # text = "Please supply a Pupil recording directory as first arg when calling Pupil Player."
        while not glfw.glfwWindowShouldClose(window):

            fb_size = glfw.glfwGetFramebufferSize(window)
            hdpi_factor = glfw.getHDPIFactor(window)
            gl_utils.adjust_gl_view(*fb_size)

            if rec_dir:
                if pm.is_pupil_rec_dir(rec_dir):
                    logger.info("Starting new session with '{}'".format(rec_dir))
                    text = "Updating recording format."
                    tip = "This may take a while!"
                else:
                    logger.error("'{}' is not a valid pupil recording".format(rec_dir))
                    tip = "Oops! That was not a valid recording."
                    rec_dir = None

            gl_utils.clear_gl_screen()
            glfont.set_blur(10.5)
            glfont.set_color_float((0.0, 0.0, 0.0, 1.0))
            glfont.set_size(w / 25.0 * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, 0.3 * h * hdpi_factor, text)
            glfont.set_size(w / 30.0 * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, 0.4 * h * hdpi_factor, tip)
            glfont.set_blur(0.96)
            glfont.set_color_float((1.0, 1.0, 1.0, 1.0))
            glfont.set_size(w / 25.0 * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, 0.3 * h * hdpi_factor, text)
            glfont.set_size(w / 30.0 * hdpi_factor)
            glfont.draw_text(w / 2 * hdpi_factor, 0.4 * h * hdpi_factor, tip)

            glfw.glfwSwapBuffers(window)

            if rec_dir:
                try:
                    um.update_recording_to_recent(rec_dir)
                except AssertionError as err:
                    logger.error(str(err))
                    rec_dir = None
                else:
                    glfw.glfwSetWindowShouldClose(window, True)

            glfw.glfwPollEvents()

        session_settings["window_position"] = glfw.glfwGetWindowPos(window)
        session_settings.close()
        glfw.glfwDestroyWindow(window)
        if rec_dir:
            ipc_pub.notify(
                {"subject": "player_process.should_start", "rec_dir": rec_dir}
            )

    except:
        import traceback

        trace = traceback.format_exc()
        logger.error("Process player_drop crashed with trace:\n{}".format(trace))

    finally:
        sleep(1.0)
Esempio n. 20
0
File: v.py Progetto: mcolom/pvflip
def keyboard_callback(window, key, scancode, action, mods):
    global V,D

    if V.mute_keyboard: # only mute the spacebar event
       return

    #print key

    # navigate
    winx, winy= glfw.glfwGetFramebufferSize(window)
    if key==glfw.GLFW_KEY_RIGHT and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.translation_update(winx/4/V.zoom_param,0)
    elif key==glfw.GLFW_KEY_UP and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.translation_update(0,-winy/4/V.zoom_param)
    elif key==glfw.GLFW_KEY_LEFT and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.translation_update(-winx/4/V.zoom_param,0)
    elif key==glfw.GLFW_KEY_DOWN and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.translation_update(0,winy/4/V.zoom_param)

    #contrast change
    if key==glfw.GLFW_KEY_E and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.radius_update(1)
    if key==glfw.GLFW_KEY_D and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.radius_update(-1)
    if key==glfw.GLFW_KEY_C and action==glfw.GLFW_PRESS:
       V.reset_scale_bias()
       if V.shift_is_pressed:
         V.TOGGLE_AUTOMATIC_RANGE = (V.TOGGLE_AUTOMATIC_RANGE + 1) % 2
         if V.TOGGLE_AUTOMATIC_RANGE: 
            print("automatic range enabled")
         else: 
            print("automatic range disabled")
         

    if key==glfw.GLFW_KEY_B and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT): 
       V.reset_range_to_8bits()
       V.TOGGLE_AUTOMATIC_RANGE = 0
       print("range set to [0,255]")


    # (SAVE) write current buffer
    if key==glfw.GLFW_KEY_S and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT): 
       import numpy as np
       import piio
       w,h=V.winx,V.winy
       data = glReadPixels (0,0,w,h, GL_RGB,  GL_UNSIGNED_BYTE)
       iimage = np.fromstring(data, dtype=np.uint8, count=w*h*3).reshape((h,w,3))
       n=0     # TODO determine next snapshot
       print('saving' + 'snap%02d.png'%n)
       piio.write('snap%02d.png'%n, iimage[::-1,:,0:3])
       ### from http://nullege.com/codes/show/src@g@[email protected]@[email protected]/313/OpenGL.GL.glReadPixels
       #from PIL import Image
       #image = Image.fromstring('RGBA', (w,h), data)
       #image = image.transpose(Image.FLIP_TOP_BOTTOM)
       #image.save ('save.png')


    # zoom
    if key==glfw.GLFW_KEY_P and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.zoom_update(+1)
    if key==glfw.GLFW_KEY_M and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       V.zoom_update(-1)

    # fit image to window
    if key==glfw.GLFW_KEY_F and action==glfw.GLFW_PRESS:
       V.TOGGLE_FIT_TO_WINDOW_SIZE = (V.TOGGLE_FIT_TO_WINDOW_SIZE + 1) % 2
       if V.TOGGLE_FIT_TO_WINDOW_SIZE:
          print("ENABLE: fit image to window")
          V.update_zoom_position_to_fit_window()
          V.redisp = 1 
       else:
          print("DISABLE: fit image to window")
          #V.reset_zoom()
          V.redisp = 1 


    # reset visualization
    if key==glfw.GLFW_KEY_R and action==glfw.GLFW_PRESS:
       V.reset_zoom()
       V.reset_scale_bias()

    # reset visualization
    if key==glfw.GLFW_KEY_1 and action==glfw.GLFW_PRESS:
       V.TOGGLE_FLOW_COLORS = (V.TOGGLE_FLOW_COLORS + 1) % 5
       V.redisp = 1



    # modifier keys
    if key==glfw.GLFW_KEY_LEFT_SHIFT and action==glfw.GLFW_PRESS:
       V.shift_is_pressed=1
    if key==glfw.GLFW_KEY_LEFT_SHIFT and action==glfw.GLFW_RELEASE:
       V.shift_is_pressed=0
    if key==glfw.GLFW_KEY_Z   and action==glfw.GLFW_PRESS:
       V.alt_is_pressed=1
    if key==glfw.GLFW_KEY_Z   and action==glfw.GLFW_RELEASE:
       V.alt_is_pressed=0


    # CHANGE IMAGE TODO: use DataBackend DD
    global current_image_idx
    new_current_image_idx = current_image_idx
    if key==glfw.GLFW_KEY_SPACE and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       new_current_image_idx = change_image(current_image_idx+1)
       if V.TOGGLE_AUTOMATIC_RANGE: V.reset_scale_bias()
       V.mute_keyboard=1

    if key==glfw.GLFW_KEY_BACKSPACE and (action==glfw.GLFW_PRESS or action==glfw.GLFW_REPEAT):
       new_current_image_idx = change_image(current_image_idx-1)
       if V.TOGGLE_AUTOMATIC_RANGE: V.reset_scale_bias()
       V.mute_keyboard=1

    if not new_current_image_idx == current_image_idx:
       current_image_idx = new_current_image_idx
       V.redisp=1
       V.resize=1

    # display hud
    if key==glfw.GLFW_KEY_U   and action==glfw.GLFW_PRESS:
       V.display_hud=(V.display_hud+1)%2
       V.redisp=1

    # help
    if key==glfw.GLFW_KEY_H   and action==glfw.GLFW_PRESS:
       print("Q     : quit")
       print("U     : show/hide HUD")
       print("arrows: pan image")
       print("P,M   : zoom image in/out")
       print("Z     : zoom modifier for the mouse wheel")
       print("F     : fit image to window size")
       print("C     : reset intensity range")
       print("shiftC: automatically reset range")
       print("B     : set range to [0:255]")
       print("D,E   : range scale up/down")
       print("R     : reset visualization: zoom,pan,range")
       print("1     : toggle optic flow coloring")
       print("S     : capture a snap##.png of the current view")
       print("mouse wheel: contrast center")
       print("mouse wheel+shift: contrast scale")
       print("mouse motion+shift: contrast center")
       print("space/backspace : next/prev image")

    # exit
    if (key==glfw.GLFW_KEY_Q  or key==glfw.GLFW_KEY_ESCAPE ) and action ==glfw.GLFW_PRESS:
       glfw.glfwSetWindowShouldClose(window,1)
       global x0,y0,w0,h0
       print(x0,y0,w0,h0)
       sys.exit(0)