FixTk.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import sys, os
  2. # Delay import _tkinter until we have set TCL_LIBRARY,
  3. # so that Tcl_FindExecutable has a chance to locate its
  4. # encoding directory.
  5. # Unfortunately, we cannot know the TCL_LIBRARY directory
  6. # if we don't know the tcl version, which we cannot find out
  7. # without import Tcl. Fortunately, Tcl will itself look in
  8. # <TCL_LIBRARY>\..\tcl<TCL_VERSION>, so anything close to
  9. # the real Tcl library will do.
  10. # Expand symbolic links on Vista
  11. try:
  12. import ctypes
  13. ctypes.windll.kernel32.GetFinalPathNameByHandleW
  14. except (ImportError, AttributeError):
  15. def convert_path(s):
  16. return s
  17. else:
  18. def convert_path(s):
  19. assert isinstance(s, str) # sys.prefix contains only bytes
  20. udir = s.decode("mbcs")
  21. hdir = ctypes.windll.kernel32.\
  22. CreateFileW(udir, 0x80, # FILE_READ_ATTRIBUTES
  23. 1, # FILE_SHARE_READ
  24. None, 3, # OPEN_EXISTING
  25. 0x02000000, # FILE_FLAG_BACKUP_SEMANTICS
  26. None)
  27. if hdir == -1:
  28. # Cannot open directory, give up
  29. return s
  30. buf = ctypes.create_unicode_buffer(u"", 32768)
  31. res = ctypes.windll.kernel32.\
  32. GetFinalPathNameByHandleW(hdir, buf, len(buf),
  33. 0) # VOLUME_NAME_DOS
  34. ctypes.windll.kernel32.CloseHandle(hdir)
  35. if res == 0:
  36. # Conversion failed (e.g. network location)
  37. return s
  38. s = buf[:res].encode("mbcs")
  39. # Ignore leading \\?\
  40. if s.startswith("\\\\?\\"):
  41. s = s[4:]
  42. if s.startswith("UNC"):
  43. s = "\\" + s[3:]
  44. return s
  45. prefix = os.path.join(sys.prefix,"tcl")
  46. if not os.path.exists(prefix):
  47. # devdir/externals/tcltk/lib
  48. tcltk = 'tcltk'
  49. if sys.maxsize > 2**31 - 1:
  50. tcltk = 'tcltk64'
  51. prefix = os.path.join(sys.prefix, "externals", tcltk, "lib")
  52. prefix = os.path.abspath(prefix)
  53. # if this does not exist, no further search is needed
  54. if os.path.exists(prefix):
  55. prefix = convert_path(prefix)
  56. if "TCL_LIBRARY" not in os.environ:
  57. for name in os.listdir(prefix):
  58. if name.startswith("tcl"):
  59. tcldir = os.path.join(prefix,name)
  60. if os.path.isdir(tcldir):
  61. os.environ["TCL_LIBRARY"] = tcldir
  62. # Compute TK_LIBRARY, knowing that it has the same version
  63. # as Tcl
  64. import _tkinter
  65. ver = str(_tkinter.TCL_VERSION)
  66. if "TK_LIBRARY" not in os.environ:
  67. v = os.path.join(prefix, 'tk'+ver)
  68. if os.path.exists(os.path.join(v, "tclIndex")):
  69. os.environ['TK_LIBRARY'] = v
  70. # We don't know the Tix version, so we must search the entire
  71. # directory
  72. if "TIX_LIBRARY" not in os.environ:
  73. for name in os.listdir(prefix):
  74. if name.startswith("tix"):
  75. tixdir = os.path.join(prefix,name)
  76. if os.path.isdir(tixdir):
  77. os.environ["TIX_LIBRARY"] = tixdir