Ejemplo n.º 1
0
def main():
    if "--help" in sys.argv[1:] or (not sys.argv[1:] and not gui):
        safe_print("Convert VRML file to X3D")
        safe_print("Author: Florian Hoech, licensed under the GPL version 3")
        safe_print("Usage: %s [OPTION]... FILE..." %
                   os.path.basename(sys.argv[0]))
        safe_print("The output is written to FILENAME.x3d(.html)")
        safe_print("")
        safe_print("  --embed      Embed viewer components in HTML instead of "
                   "referencing them")
        safe_print("  --force      Force fresh download of viewer components")
        safe_print("  --no-cache   Don't use viewer components cache (only "
                   "uses existing cache if")
        safe_print("               embedding components, can be overridden "
                   "with --force)")
        if gui:
            safe_print("  --no-gui     Don't use GUI (console mode)")
        safe_print("  --no-html    Don't generate HTML file")
        safe_print("  --view       View the generated file (if no GUI)")
        if not gui:
            safe_print("  --batch      Don't pause after processing")
        safe_print("  FILE         Filename of VRML file to convert")
        if gui:
            return
    if gui:
        config.initcfg("VRML-to-X3D-converter")
        lang.init()
        lang.update_defaults()
    cache = not "--no-cache" in sys.argv[1:]
    embed = "--embed" in sys.argv
    force = "--force" in sys.argv
    html = not "--no-html" in sys.argv[1:]
    if not gui:
        result = None
        view = "--view" in sys.argv[1:]
        for arg in sys.argv[1:]:
            if not arg.startswith("--"):
                result = vrmlfile2x3dfile(safe_unicode(arg),
                                          html=html,
                                          embed=embed,
                                          view=view,
                                          force=force,
                                          cache=cache,
                                          gui=gui)
        if result is None:
            safe_print("No filename given.")
        if sys.stdout.isatty() and not "--batch" in sys.argv[1:]:
            input("Press RETURN to exit")
        sys.exit(int(not result))
    else:
        view = not "--no-view" in sys.argv[1:]
        app = BaseApp(0)
        app.TopWindow = VRML2X3DFrame(html, embed, view, force, cache)
        if sys.platform == "darwin":
            app.TopWindow.init_menubar()
        wx.CallLater(1, _main, app)
        app.MainLoop()
Ejemplo n.º 2
0
def main():
    config.initcfg()
    lang.init()
    app = BaseApp(0)
    app.TopWindow = MeasureFrame()
    app.TopWindow.Show()
    if "--test-dither" in sys.argv[1:]:
        import threading
        t = threading.Thread(target=test)
        app.TopWindow.show_controls(False)
        t.start()
    app.MainLoop()
Ejemplo n.º 3
0
def main():
    config.initcfg("scripting-client")
    lang.init()
    app = BaseApp(0)
    app.TopWindow = ScriptingClientFrame()
    if sys.platform == "darwin":
        app.TopWindow.init_menubar()
    app.TopWindow.listen()
    app.TopWindow.Show()
    app.MainLoop()
    writecfg(module="scripting-client",
             options=("position.scripting", "size.scripting"))
Ejemplo n.º 4
0
        def abort_subprocess(self):
            self.safe_send("Q")

        def safe_send(self, bytes):
            print("*** Sending %r" % bytes)
            self.subprocess.send(bytes)
            return True

    config.initcfg()
    print("untethered.min_delta", getcfg("untethered.min_delta"))
    print("untethered.min_delta.lightness",
          getcfg("untethered.min_delta.lightness"))
    print("untethered.max_delta.chroma", getcfg("untethered.max_delta.chroma"))
    lang.init()
    lang.update_defaults()
    app = BaseApp(0)
    app.TopWindow = UntetheredFrame(start_timer=False)
    testchart = getcfg("testchart.file")
    if os.path.splitext(testchart)[1].lower() in (".icc", ".icm"):
        try:
            testchart = ICCP.ICCProfile(testchart).tags.targ
        except:
            pass
    try:
        app.TopWindow.cgats = CGATS.CGATS(testchart)
    except:
        app.TopWindow.cgats = CGATS.CGATS("""TI1    
BEGIN_DATA_FORMAT
SAMPLE_ID RGB_R RGB_G RGB_B XYZ_X XYZ_Y XYZ_Z
END_DATA_FORMAT
BEGIN_DATA
Ejemplo n.º 5
0
def vrmlfile2x3dfile(vrmlpath=None,
                     x3dpath=None,
                     html=True,
                     embed=False,
                     view=False,
                     force=False,
                     cache=True,
                     worker=None,
                     gui=True):
    """ Convert VRML to HTML. Output is written to <vrmlfilename>.x3d.html
	unless you set x3dpath to desired output path, or False to be prompted
	for an output path. """
    while not vrmlpath or not os.path.isfile(vrmlpath):
        if not gui:
            if not vrmlpath or vrmlpath.startswith("--"):
                safe_print("No filename given.")
            else:
                safe_print("%r is not a file." % vrmlpath)
            return False
        if not wx.GetApp():
            app = BaseApp(0)
        defaultDir, defaultFile = config.get_verified_path("last_vrml_path")
        dlg = wx.FileDialog(None,
                            lang.getstr("file.select"),
                            defaultDir=defaultDir,
                            defaultFile=defaultFile,
                            wildcard=lang.getstr("filetype.vrml") +
                            "|*.vrml;*.vrml.gz;*.wrl.gz;*.wrl;*.wrz",
                            style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        dlg.Center(wx.BOTH)
        result = dlg.ShowModal()
        vrmlpath = dlg.GetPath()
        dlg.Destroy()
        if result != wx.ID_OK:
            return
        config.setcfg("last_vrml_path", vrmlpath)
        config.writecfg(module="VRML-to-X3D-converter",
                        options=("last_vrml_path", ))
    filename, ext = os.path.splitext(vrmlpath)
    if x3dpath is None:
        x3dpath = filename + ".x3d"
    if x3dpath:
        dirname = os.path.dirname(x3dpath)
    while not x3dpath or not waccess(dirname, os.W_OK):
        if not gui:
            if not x3dpath:
                safe_print("No HTML output filename given.")
            else:
                safe_print("%r is not writable." % dirname)
            return False
        if not wx.GetApp():
            app = BaseApp(0)
        if x3dpath:
            defaultDir, defaultFile = os.path.split(x3dpath)
        else:
            defaultFile = os.path.basename(filename) + ".x3d"
        dlg = wx.FileDialog(None,
                            lang.getstr("error.access_denied.write", dirname),
                            defaultDir=defaultDir,
                            defaultFile=defaultFile,
                            wildcard=lang.getstr("filetype.x3d") + "|*.x3d",
                            style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
        dlg.Center(wx.BOTH)
        result = dlg.ShowModal()
        dlg.Destroy()
        if result != wx.ID_OK:
            return
        x3dpath = dlg.GetPath()
        dirname = os.path.dirname(x3dpath)
    vrmlpath, x3dpath = [safe_unicode(path) for path in (vrmlpath, x3dpath)]
    if sys.platform == "win32":
        vrmlpath = make_win32_compatible_long_path(vrmlpath)
        x3dpath = make_win32_compatible_long_path(x3dpath)
    if html:
        finalpath = x3dpath + ".html"
        if sys.platform == "win32":
            finalpath = make_win32_compatible_long_path(finalpath)
            x3dpath = finalpath[:-5]
    else:
        finalpath = x3dpath
    if worker:
        worker.clear_cmd_output()
        worker.start(
            lambda result: show_result_dialog(result,
                                              wx.GetApp().GetTopWindow())
            if isinstance(result, Exception
                          ) else result and view and launch_file(finalpath),
            x3dom.vrmlfile2x3dfile,
            wargs=(vrmlpath, x3dpath, html, embed, force, cache, worker),
            progress_title=lang.getstr("vrml_to_x3d_converter"),
            progress_start=1,
            resume=worker.progress_wnd
            and worker.progress_wnd.IsShownOnScreen(),
            fancy=False)
    else:
        result = x3dom.vrmlfile2x3dfile(vrmlpath, x3dpath, html, embed, force,
                                        cache, None)
        if not isinstance(result, Exception) and result:
            if view:
                launch_file(finalpath)
        else:
            return False
    return True
Ejemplo n.º 6
0
    class Worker(object):
        def __init__(self):
            self.subprocess = Subprocess()
            self.subprocess_abort = False

        def abort_subprocess(self):
            self.subprocess.send("Q")

        def safe_send(self, bytes):
            self.subprocess.send(bytes)
            return True

    config.initcfg()
    lang.init()
    lang.update_defaults()
    app = BaseApp(0)
    app.TopWindow = DisplayUniformityFrame(start_timer=False, rows=3, cols=3)
    app.TopWindow.worker = Worker()
    app.TopWindow.Show()
    i = 0

    def test(bytes=None):
        global i
        menu = r"""Place instrument on spot to be measured,
and hit [A-Z] to read white and setup FWA compensation (keyed to letter)
[a-z] to read and make FWA compensated reading from keyed reference
'r' to set reference, 's' to save spectrum,
'h' to toggle high res., 'k' to do a calibration
Hit ESC or Q to exit, any other key to take a reading:"""
        if not bytes:
            txt = menu
Ejemplo n.º 7
0
                               round(tf[0][1], 2))
                    # Restore previous gamma if not single gamma profile
                    elif getcfg("measurement_report.trc_gamma.backup", False):
                        setcfg("measurement_report.trc_gamma",
                               getcfg("measurement_report.trc_gamma.backup"))
                        setcfg("measurement_report.trc_gamma.backup", None)
                self.mr_update_trc_controls()
                enable = (tf[0][1] not in (-240, -709)
                          and self.XYZbpin != self.XYZbpout)
            elif update_trc:
                enable = self.XYZbpin != self.XYZbpout
                setcfg("measurement_report.apply_black_offset", int(enable))
                setcfg("measurement_report.apply_trc", 0)
        self.apply_black_offset_ctrl.Enable(bool(sim_profile) and enable)
        self.mr_update_main_controls()

    def use_simulation_profile_as_output_handler(self, event):
        setcfg("measurement_report.use_simulation_profile_as_output",
               int(self.use_simulation_profile_as_output_cb.GetValue()))
        self.mr_update_main_controls()


if __name__ == "__main__":
    config.initcfg()
    lang.init()
    lang.update_defaults()
    app = BaseApp(0)
    app.TopWindow = ReportFrame()
    app.TopWindow.Show()
    app.MainLoop()
Ejemplo n.º 8
0
def _main(module, name, applockfilename, probe_ports=True):
    # Allow multiple instances only for curve viewer, profile info,
    # scripting client, synthetic profile creator and testchart editor
    multi_instance = ("curve-viewer", "profile-info", "scripting-client",
                      "synthprofile", "testchart-editor")
    lock = AppLock(applockfilename, "a+", True, module in multi_instance)
    if not lock:
        # If a race condition occurs, do not start another instance
        safe_print("Not starting another instance.")
        return
    log("=" * 80)
    if verbose >= 1:
        version = VERSION_STRING
        if VERSION > VERSION_BASE:
            version += " Beta"
        safe_print(pyname + runtype, version, build)
    if sys.platform == "darwin":
        # Python's platform.platform output is useless under Mac OS X
        # (e.g. 'Darwin-15.0.0-x86_64-i386-64bit' for Mac OS X 10.11 El Capitan)
        safe_print("Mac OS X %s %s" % (mac_ver()[0], mac_ver()[-1]))
    elif sys.platform == "win32":
        machine = platform.machine()
        safe_print(*[v for v in win_ver() if v] + ({
            "AMD64": "x86_64"
        }.get(machine, machine), ))
    else:
        # Linux
        safe_print(' '.join(platform.dist()), platform.machine())
    safe_print("Python " + sys.version)
    cafile = os.getenv("SSL_CERT_FILE")
    if cafile:
        safe_print("CA file", cafile)
    # Enable faulthandler
    try:
        import faulthandler
    except Exception as exception:
        safe_print(exception)
    else:
        try:
            faulthandler.enable(
                open(os.path.join(logdir, pyname + "-fault.log"), "w"))
        except Exception as exception:
            safe_print(exception)
        else:
            safe_print("Faulthandler", getattr(faulthandler, "__version__",
                                               ""))
    from wxaddons import wx
    if "phoenix" in wx.PlatformInfo:
        # py2exe helper so wx.xml gets picked up
        from wx import xml
    safe_print("wxPython " + wx.version())
    safe_print("Encoding: " + enc)
    safe_print("File system encoding: " + fs_enc)
    if sys.platform == "win32" and sys.getwindowsversion() >= (6, 2):
        # HighDPI support
        try:
            shcore = ctypes.windll.shcore
        except Exception as exception:
            safe_print("Warning - could not load shcore:", exception)
        else:
            if hasattr(shcore, "SetProcessDpiAwareness"):
                try:
                    # 1 = System DPI aware (wxWpython currently does not
                    # support per-monitor DPI)
                    shcore.SetProcessDpiAwareness(1)
                except Exception as exception:
                    safe_print("Warning - SetProcessDpiAwareness() failed:",
                               exception)
            else:
                safe_print(
                    "Warning - SetProcessDpiAwareness not found in shcore")
    initcfg(module)
    host = "127.0.0.1"
    defaultport = getcfg("app.port")
    lock2pids_ports = {}
    opid = os.getpid()
    if probe_ports:
        # Check for currently used ports
        lockfilenames = glob.glob(os.path.join(confighome, "*.lock"))
        for lockfilename in lockfilenames:
            safe_print("Lockfile", lockfilename)
            try:
                if lock and lockfilename == applockfilename:
                    lockfile = lock
                    lock.seek(0)
                else:
                    lockfile = AppLock(lockfilename, "r", True, True)
                if lockfile:
                    if not lockfilename in lock2pids_ports:
                        lock2pids_ports[lockfilename] = []
                    for ln, line in enumerate(lockfile.read().splitlines(), 1):
                        if ":" in line:
                            # DisplayCAL >= 3.8.8.2 with localhost blocked
                            pid, port = line.split(":", 1)
                            if pid:
                                try:
                                    pid = int(pid)
                                except ValueError as exception:
                                    # This shouldn't happen
                                    safe_print("Warning - couldn't parse PID "
                                               "as int: %r (%s line %i)" %
                                               (pid, lockfilename, ln))
                                    pid = None
                                else:
                                    safe_print("Existing client using PID",
                                               pid)
                        else:
                            # DisplayCAL <= 3.8.8.1 or localhost ok
                            pid = None
                            port = line
                        if port:
                            try:
                                port = int(port)
                            except ValueError as exception:
                                # This shouldn't happen
                                safe_print(
                                    "Warning - couldn't parse port as int: %r "
                                    "(%s line %i)" % (port, lockfilename, ln))
                                port = None
                            else:
                                safe_print("Existing client using port", port)
                        if pid or port:
                            lock2pids_ports[lockfilename].append((pid, port))
                if not lock or lockfilename != applockfilename:
                    lockfile.unlock()
            except EnvironmentError as exception:
                # This shouldn't happen
                safe_print(
                    "Warning - could not read lockfile %s:" % lockfilename,
                    exception)
        if module not in multi_instance:
            # Check lockfile(s) and probe port(s)
            for lockfilename in [applockfilename]:
                incoming = None
                pids_ports = lock2pids_ports.get(lockfilename)
                if pids_ports:
                    pid, port = pids_ports[0]
                    appsocket = AppSocket()
                    if appsocket and port:
                        safe_print("Connecting to %s..." % port)
                        if appsocket.connect(host, port):
                            safe_print("Connected to", port)
                            # Other instance already running?
                            # Get appname to check if expected app is actually
                            # running under that port
                            safe_print("Getting instance name")
                            if appsocket.send("getappname"):
                                safe_print(
                                    "Sent scripting request, awaiting response..."
                                )
                                incoming = appsocket.read().rstrip("\4")
                                safe_print("Got response: %r" % incoming)
                                if incoming:
                                    if incoming != pyname:
                                        incoming = None
                                else:
                                    incoming = False
                        while incoming:
                            # Send args as UTF-8
                            if module == "apply-profiles":
                                # Always try to close currently running instance
                                safe_print("Closing existing instance")
                                cmd = "exit" if incoming == pyname else "close"
                                data = [cmd]
                                lock.unlock()
                            else:
                                # Send module/appname to notify running app
                                safe_print("Notifying existing instance")
                                data = [module or appname]
                                if module != "3DLUT-maker":
                                    for arg in sys.argv[1:]:
                                        data.append(
                                            safe_str(safe_unicode(arg),
                                                     "UTF-8"))
                            data = sp.list2cmdline(data)
                            if appsocket.send(data):
                                safe_print(
                                    "Sent scripting request, awaiting response..."
                                )
                                incoming = appsocket.read().rstrip("\4")
                                safe_print("Got response: %r" % incoming)
                                if module == "apply-profiles":
                                    if incoming == "":
                                        # Successfully sent our close request.
                                        incoming = "ok"
                                    elif incoming == "invalid" and cmd == "exit":
                                        # < 3.8.8.1 didn't have exit command
                                        continue
                            break
                        appsocket.close()
                else:
                    pid = None
                if not incoming:
                    if sys.platform == "win32":
                        import pywintypes
                        import win32ts
                        try:
                            osid = win32ts.ProcessIdToSessionId(opid)
                        except pywintypes.error as exception:
                            safe_print("Enumerating processes failed:",
                                       exception)
                            osid = None
                        try:
                            processes = win32ts.WTSEnumerateProcesses()
                        except pywintypes.error as exception:
                            safe_print("Enumerating processes failed:",
                                       exception)
                        else:
                            appname_lower = appname.lower()
                            exename_lower = exename.lower()
                            if module:
                                pyexe_lower = appname_lower + "-" + module + exe_ext
                            else:
                                pyexe_lower = appname_lower + exe_ext
                            incoming = None
                            for (sid, pid2, basename, usid) in processes:
                                basename_lower = basename.lower()
                                if ((pid and pid2 == pid
                                     and basename_lower == exename_lower) or
                                    ((osid is None or sid == osid)
                                     and basename_lower
                                     == pyexe_lower)) and pid2 != opid:
                                    # Other instance running
                                    incoming = False
                                    if module == "apply-profiles":
                                        if not os.path.isfile(lockfilename):
                                            # Create dummy lockfile
                                            try:
                                                with open(lockfilename, "w"):
                                                    pass
                                            except EnvironmentError as exception:
                                                safe_print(
                                                    "Warning - could "
                                                    "not create dummy "
                                                    "lockfile %s: %r" %
                                                    (lockfilename, exception))
                                            else:
                                                safe_print(
                                                    "Warning - had to "
                                                    "create dummy "
                                                    "lockfile", lockfilename)
                                        safe_print(
                                            "Closing existing instance "
                                            "with PID", pid2)
                                        startupinfo = sp.STARTUPINFO()
                                        startupinfo.dwFlags |= sp.STARTF_USESHOWWINDOW
                                        startupinfo.wShowWindow = sp.SW_HIDE
                                        lock.unlock()
                                        try:
                                            p = sp.Popen(
                                                [
                                                    "taskkill", "/PID",
                                                    "%s" % pid2
                                                ],
                                                stdin=sp.PIPE,
                                                stdout=sp.PIPE,
                                                stderr=sp.STDOUT,
                                                startupinfo=startupinfo)
                                            stdout, stderr = p.communicate()
                                        except Exception as exception:
                                            safe_print(exception)
                                        else:
                                            safe_print(stdout)
                                            if not p.returncode:
                                                # Successfully sent our close
                                                # request.
                                                incoming = "ok"
                if incoming == "ok":
                    # Successfully sent our request
                    if module == "apply-profiles":
                        # Wait for lockfile to be removed, in which case
                        # we know the running instance has successfully
                        # closed.
                        safe_print(
                            "Waiting for existing instance to exit and "
                            "delete lockfile", lockfilename)
                        while os.path.isfile(lockfilename):
                            sleep(.05)
                        lock.lock()
                        safe_print("Existing instance exited.")
                        incoming = None
                        if lockfilename in lock2pids_ports:
                            del lock2pids_ports[lockfilename]
                    break
            if incoming is not None:
                # Other instance running?
                import localization as lang
                lang.init()
                if incoming == "ok":
                    # Successfully sent our request
                    safe_print(lang.getstr("app.otherinstance.notified"))
                elif module == "apply-profiles":
                    safe_print("Not starting another instance.")
                else:
                    # Other instance busy?
                    handle_error(lang.getstr("app.otherinstance", name))
                # Exit
                return
    # Use exclusive lock during app startup
    with lock:
        # Create listening socket
        appsocket = AppSocket()
        if appsocket:
            if sys.platform != "win32":
                # https://docs.microsoft.com/de-de/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse#using-so_reuseaddr
                # From the above link: "The SO_REUSEADDR socket option allows
                # a socket to forcibly bind to a port in use by another socket".
                # Note that this is different from the behavior under Linux/BSD,
                # where a socket can only be (re-)bound if no active listening
                # socket is already bound to the address.
                # Consequently, we don't use SO_REUSEADDR under Windows.
                appsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            sys._appsocket = appsocket.socket
            if getcfg("app.allow_network_clients"):
                host = ""
            used_ports = [
                pid_port[1] for pids_ports in list(lock2pids_ports.values())
                for pid_port in pids_ports
            ]
            candidate_ports = [0]
            if not defaultport in used_ports:
                candidate_ports.insert(0, defaultport)
            for port in candidate_ports:
                try:
                    sys._appsocket.bind((host, port))
                except socket.error as exception:
                    if port == 0:
                        safe_print(
                            "Warning - could not bind to %s:%s:" %
                            (host, port), exception)
                        del sys._appsocket
                        break
                else:
                    try:
                        sys._appsocket.settimeout(.2)
                    except socket.error as exception:
                        safe_print(
                            "Warning - could not set socket "
                            "timeout:", exception)
                        del sys._appsocket
                        break
                    try:
                        sys._appsocket.listen(1)
                    except socket.error as exception:
                        safe_print("Warning - could not listen on "
                                   "socket:", exception)
                        del sys._appsocket
                        break
                    try:
                        port = sys._appsocket.getsockname()[1]
                    except socket.error as exception:
                        safe_print(
                            "Warning - could not get socket "
                            "address:", exception)
                        del sys._appsocket
                        break
                    sys._appsocket_port = port
                    break
        if not hasattr(sys, "_appsocket_port"):
            port = ""
        lock.seek(0)
        if module not in multi_instance:
            lock.truncate(0)
        if not port:
            lock.write("%s:%s" % (opid, port))
        else:
            lock.write(port)
        atexit.register(lambda: safe_print("Ran application exit handlers"))
        from wxwindows import BaseApp
        BaseApp.register_exitfunc(_exit, applockfilename, port)
        # Check for required resource files
        mod2res = {
            "3DLUT-maker": ["xrc/3dlut.xrc"],
            "curve-viewer": [],
            "profile-info": [],
            "scripting-client": [],
            "synthprofile": ["xrc/synthicc.xrc"],
            "testchart-editor": [],
            "VRML-to-X3D-converter": []
        }
        for filename in mod2res.get(module, resfiles):
            path = get_data_path(os.path.sep.join(filename.split("/")))
            if not path or not os.path.isfile(path):
                import localization as lang
                lang.init()
                raise ResourceError(
                    lang.getstr("resources.notfound.error") + "\n" + filename)
        # Create main data dir if it does not exist
        if not os.path.exists(datahome):
            try:
                os.makedirs(datahome)
            except Exception as exception:
                handle_error(
                    UserWarning("Warning - could not create "
                                "directory '%s'" % datahome))
        elif sys.platform == "darwin":
            # Check & fix permissions if necessary
            import getpass
            user = getpass.getuser().decode(fs_enc)
            script = []
            for directory in (confighome, datahome, logdir):
                if (os.path.isdir(directory)
                        and not os.access(directory, os.W_OK)):
                    script.append("chown -R '%s' '%s'" % (user, directory))
            if script:
                sp.call([
                    'osascript', '-e',
                    'do shell script "%s" with administrator privileges' %
                    ";".join(script).encode(fs_enc)
                ])
        # Initialize & run
        if module == "3DLUT-maker":
            from wxLUT3DFrame import main
        elif module == "curve-viewer":
            from wxLUTViewer import main
        elif module == "profile-info":
            from wxProfileInfo import main
        elif module == "scripting-client":
            from wxScriptingClient import main
        elif module == "synthprofile":
            from wxSynthICCFrame import main
        elif module == "testchart-editor":
            from wxTestchartEditor import main
        elif module == "VRML-to-X3D-converter":
            from wxVRML2X3D import main
        elif module == "apply-profiles":
            from profile_loader import main
        else:
            from DisplayCAL import main
    # Run main after releasing lock
    main()