Tkinter: winfo_screenmmwidth discussion

josefg at gmail.com josefg at gmail.com
Tue Dec 3 20:33:56 EST 2013


On Tuesday, November 26, 2013 2:13:57 PM UTC-8, jos... at gmail.com wrote:
> I am currently using Windows 7 Sp1, Tkinter 8.5, Python 2.7.4 on a laptop with no attached monitor. I am attempting to use winfo_screenmmwidth, but the returned value is incorrect. Specs state 280 mm. Physical measurement is 275 mm. EDID states 280 mm. Tkinter's winfo_screenmmwidth returns 361 mm. I don't have very much tkinter experience, please bear with me.
> 
> 
> 
> From where does winfo_screenmmheight get this information? I have looked through the source code and can't really find the source. The source code seems to lead to WidthMMOfScreen(Screen(tkwin)) in both tkGet.c and tkObj.c. Xlib.h defines the Screen structure which has mwidth defined in it. Xlib.h also defines WidthMMOfScreen as a macro "#define WidthMMOfScreen(s)	((s)->mwidth)" The X Window System Protocol:8 Connection Setup:Screen Information states "Width-in-millimeters and height-in-millimeters can be used to determine the physical size and the aspect ratio," but I'm not sure where the code is for the request.
> 
> 
> 
> So that's where I stopped on the X Windows side of things. I think I need to look at the source code for _tkinter.lib, but I'm not sure. I downloaded and started to look at the pywin32.exe (win32all) source code, but I'm not sure where to start with that either. I was expecting to see an entry which returns the EDID information, but I have not seen that yet.
> 
> 
> 
> Could somebody point me in the right direction? Or does anyone have any ideas?
> 
> 
> 
> Thank you in advance.

I wrote this to extract the EDID information. It's not very robust and for some reason not all of the subkeys are iterated in a sub key. I also haven't gotten a response from the tcl/tk folks yet.

import _winreg

def screen_wh():
    """Input - none
    Output - Screen's physical (width, height)"""
    hive = _winreg.HKEY_LOCAL_MACHINE
    path = "SYSTEM\\CurrentControlSet\\Enum\\DISPLAY"
    number = 0
    rtpath = None

    def search_subkeys(hive, path, number, rtpath):
        number = number + 1
        key = _winreg.OpenKey(hive, path, 0, _winreg.KEY_READ)
        try:
            i = 0
            while 1:
                name = _winreg.EnumKey(key, i)
                #print(" "*number + name, i) #Used to view registry path
                #for some reason this does not iterate over all registry keys crappy fix
                if i == 2:
                    try:
                        #This works with a direct call, but it's not very portable.
                        name2 = _winreg.EnumKey(key, 3)
                        if name2 == "Control":
                            rtpath = path
                    except WindowsError:
                        pass
                if rtpath == None:
                    rtpath = search_subkeys(hive, path+"\\"+name, number, rtpath)
                i += 1
        except WindowsError:
            pass
        
        return(rtpath)

    monitor = search_subkeys(hive,path, number,rtpath)
    print("EDID registry path: {0}".format(monitor))
    key = _winreg.OpenKey(hive, monitor+"\\Device Parameters")
    try:
        i = 0
        while 1:
            name, data, type = _winreg.EnumValue(key, i)
            if name == 'EDID':
                break
    except WindowsError:
        "EDID not found"
    width  = int(data[21].encode('hex'),16) * 10
    height = int(data[22].encode('hex'),16) * 10
    print("Width: {0} mm\nHeight: {1} mm".format(width,height))
    return((width, height))



More information about the Python-list mailing list