
    m5j)                    p   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
mZ ddlmZ ddlmZ ddlZ	 ddlZddlZn# e$ r dZdZY nw xY we
 G d d                      Zd dZd!dZd"dZd"dZd"dZd#dZd$dZd!dZd%dZd&d'dZedk    r  e            Z  e! ee                      dS dS )(u  
yjm_monitor_probe.py

Windows 다중 모니터 진단 공통 모듈.

목적:
- mss가 보는 원본 모니터 목록을 그대로 확인한다.
- Win32 EnumDisplayMonitors가 보는 목록을 같이 확인한다.
- DPI awareness 적용 전/후 차이를 줄인다.
- yjm_win2rtc 본 프로그램과 별도 진단 GUI가 같은 함수를 사용하게 한다.

중요 원칙:
- 실제 캡처 기준은 mss.monitors 원본 순서를 우선한다.
- Win32 목록은 진단/비교용이다. mss 목록과 임의 병합하지 않는다.
    )annotationsN)	dataclassasdict)Path)Anyc                      e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<   ded
<   dZded<   dZded<   dZded<   dZded<   edd            Z	ddZ
ddZdS )MonitorInfostrapiintindexlefttopwidthheightrightbottomFboolprimary devicenameNzdict[str, Any] | Noneextrareturntuple[int, int, int, int]c                6    | j         | j        | j        | j        fS N)r   r   r   r   selfs    >   D:\_St\__마우스\yjm_in2rtc_mouse_debug\yjm_monitor_probe.pyrectzMonitorInfo.rect7   s    y$(DJ;;    dict[str, Any]c                     t          |           S r   )r   r   s    r    to_dictzMonitorInfo.to_dict;   s    d||r"   c                    | j         rdnd}| j        r
d| j         nd}| j        r
d| j         nd}| j         d| j         d| j         d| j         d| j         d| j         d	| j	         d
| j
         | | | S )Nz
 / PRIMARYr    / [] xz @ left=z, top=z, right=z	, bottom=)r   r   r   r   r   r   r   r   r   r   r   )r   r   devr   s       r    labelzMonitorInfo.label>   s    "&,6,,B%)[8!DK!!!b$(I5 TY   2x $ $$* $ $
 $ $T[ $ $i$ $'+x$ $9=$ $NRk$$$!$ $	
r"   )r   r   r   r#   r   r
   )__name__
__module____qualname____annotations__r   r   r   r   propertyr!   r%   r,    r"   r    r	   r	   (   s         HHHJJJIIIHHHJJJKKKJJJKKKGFDNNNN#'E''''< < < X<   
 
 
 
 
 
r"   r	   r   r
   c                 <   t           j        dk    rdS 	 t          j        j                            d           dS # t          $ rW} 	 t          j        j                                         d|  cY d} ~ S # t          $ r}d|  d| cY d}~cY d} ~ S d}~ww xY wd} ~ ww xY w)	u`   프로세스를 DPI aware로 만든다. 이미 설정되어 있으면 실패해도 무시한다.ntnot-windows   zSetProcessDpiAwareness(2) OKz'SetProcessDPIAware OK / shcore failed: NzDPI awareness failed: shcore=z	, user32=)	osr   ctypeswindllshcoreSetProcessDpiAwareness	Exceptionuser32SetProcessDPIAware)exc1exc2s     r    set_dpi_awarenessrC   I   s    	w$}	I33A666-- I I I	IM 33555CTCCCCCCCC 	I 	I 	IH4HH$HHHHHHHHHHHHH	IIsE   $: 
B'A2,B2
B<BBBBBBBr#   c                 \   i } t           j        dk    rddiS 	 t          j        j                                        | d<   n)# t          $ r}t          |          | d<   Y d }~nd }~ww xY w	 t          j        j                            d          }t          j        j	        
                    |d          | d<   t          j        j	        
                    |d	          | d
<   t          j        j                            d|           n)# t          $ r}t          |          | d<   Y d }~nd }~ww xY w| S )Nr6   platformr7   system_dpi_xsystem_dpi_x_errorr   X   device_caps_logpixelsxZ   device_caps_logpixelsydevice_caps_error)r9   r   r:   r;   r?   GetDpiForSystemr>   r
   GetDCgdi32GetDeviceCaps	ReleaseDC)infoexcdcs      r    get_dpi_inforU   [   s@   D	w$M**.%}3CCEE^ . . .%(XX!"""""".-]!''**)/)<)J)J2r)R)R%&)/)<)J)J2r)R)R%&&&q"---- - - -$'HH !!!!!!- Ks.   &? 
A%	A  A%)BD 
D)D$$D)list[MonitorInfo]c                    g } t          j                     5 }t          |j                  D ]\  }}t          |d                   }t          |d                   }t          |d                   }t          |d                   }|                     t          d|||||||z   ||z   |dk    o|dk    o|dk    |dk    rdnd	t          |          
                     	 ddd           n# 1 swxY w Y   | S )uS   mss.monitors 원본 순서 그대로 반환. index 0은 전체 가상 바탕화면.r   r   r   r   mss   r   virtualr   r   r   r   r   r   r   r   r   r   r   r   N)rX   	enumeratemonitorsr   appendr	   dict)resultsctidxmonr   r   r   r   s           r    list_mss_monitorsrd   q   sN    "F	 c!#,// 	 	HCs6{##Dc%j//CG%%EX''FMM!,< AX@$!)@q(+q99bs))     	              * Ms   CC**C.1C.c                 .    t                      dd         S )uU   캡처 소스 콤보박스용. mss[1:]만 반환하되 원본 순서를 유지한다.rY   N)rd   r4   r"   r    list_mss_physical_displaysrf      s    qrr""r"   c                    g } t           | S 	 t          j                    }n# t          $ r | cY S w xY wt          |          D ]F\  }}	 |d         }|d         }t          j        |          }|                    d|          \  }}}	}
|                    d          }t          |                    dd                    }t          |                    dd                    }|                     t          d|t          |          t          |          t          |	|z
            t          |
|z
            t          |	          t          |
          t          |d	z            |||d
                     7# t          $ r Y Dw xY w| S )Nr   r8   MonitorWorkFlagsDevicer   win32rY   )workflagsr[   )win32apiEnumDisplayMonitorsr>   r\   GetMonitorInfogetr   r
   r^   r	   r   )r`   r]   rb   itemhmonfallback_rectrR   r   r   r   r   rm   rn   r   s                 r    list_win32_monitorsrv      s    "F/11    x((  	T	7D GM*400D'+xx	='I'I$D#uf88F##D!,,--E(B//00FMMTCedl++v|,,e**v;; OO!#'%88       	 	 	H	Ms   ! 00	D.E99
FFlist[dict[str, Any]]c                 J   g } t           | S 	 d}	 t          j        d|d          }|                     |t          |dd          t          |dd          t          |dd          t          |dd          t          |d	d          d
           |dz  }# t          $ r Y nw xY w| S )u7   EnumDisplayDevices 정보. DISPLAY1/2 이름 확인용.Nr   T
DeviceNamer   DeviceString
StateFlagsDeviceID	DeviceKey)r   ry   rz   r{   r|   r}   rY   )ro   EnumDisplayDevicesr^   getattrr>   )r`   ir+   s      r    list_display_devicesr      s    #%F	-dAq99CMM")#|R"@"@$+C$D$D")#|Q"?"? 'Z < <!(k2!>!> 	 	 	 FA	    Ms   BB 
B B r]   dict[str, int]c                    | s	dddddddS t          d | D                       }t          d | D                       }t          d | D                       }t          d | D                       }||||||z
  ||z
  dS )Nr   )r   r   r   r   r   r   c              3  $   K   | ]}|j         V  d S r   )r   .0ms     r    	<genexpr>z3get_virtual_bounds_from_monitors.<locals>.<genexpr>   s$      ((!qv((((((r"   c              3  $   K   | ]}|j         V  d S r   )r   r   s     r    r   z3get_virtual_bounds_from_monitors.<locals>.<genexpr>   s$      &&ae&&&&&&r"   c              3  $   K   | ]}|j         V  d S r   )r   r   s     r    r   z3get_virtual_bounds_from_monitors.<locals>.<genexpr>   s$      **A******r"   c              3  $   K   | ]}|j         V  d S r   )r   r   s     r    r   z3get_virtual_bounds_from_monitors.<locals>.<genexpr>   s$      ,,a,,,,,,r"   )minmax)r]   r   r   r   r   s        r     get_virtual_bounds_from_monitorsr      s     W!a1qTUVVV((x(((((D
&&X&&&
&
&C*******E,,8,,,,,F3,  r"   c                    t                      } t                      }t                      }t                      }t	          j        d          t          j        t          j        t          j	                    | t                      d |D             t          |dd                    d |D             t          |          |dS )Nz%Y-%m-%d %H:%M:%Sc                6    g | ]}|                                 S r4   r%   r   s     r    
<listcomp>z%make_probe_report.<locals>.<listcomp>   s     ;;;;;;r"   rY   c                6    g | ]}|                                 S r4   r   r   s     r    r   z%make_probe_report.<locals>.<listcomp>   s     ???1199;;???r"   )	timestamppython
executablerE   
dpi_statusdpi_infomss_monitors mss_virtual_bounds_from_physicalwin32_monitorswin32_virtual_boundsdisplay_devices)rC   rd   rv   r   timestrftimesysversionr   rE   rU   r   )r   r   r   devicess       r    make_probe_reportr      s    "$$J$&&L(**N"$$G]#677+n%''  NN;;l;;;,L\Z[Z\Z\M],^,^????? @ P P"  r"   reportc                   g }|                     d           |                     d|                     d                      |                     d|                     d                      |                     d|                     d                      |                     d|                     d	                      |                     d
|                     d                      |                     d|                     d                      |                     d           |                     d           |                     d           |                     dg           D ]}t          |                    dd          t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t	          |                    dd                    t          |                    dd                    t          |                    dd                    |                    d           !          }|                     d"|                                z              |                     d#|                     d$                      |                     d           |                     d%           |                     d&g           D ]}t          |                    dd'          t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t          |                    dd                    t	          |                    dd                    t          |                    dd                    t          |                    dd                    |                    d           !          }|                     d"|                                z              |                     d(|                     d)                      |                     d           |                     d*           |                     d+g           D ]o}|                     d,|                    d           d-|                    d.           d/|                    d0           d1|                    d2                      p|                     d           d3                    |          S )4Nz# yjm_monitor_probe reportztimestamp: r   zpython: r   zexecutable: r   z
platform: rE   zdpi_status: r   z
dpi_info: r   r   z## MSS monitorsu`   주의: mss[0]은 전체 가상 바탕화면, mss[1:]가 실제 디스플레이 후보입니다.r   r   rX   r   r   r   r   r   r   r   r   r   Fr   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   z  z"mss_virtual_bounds_from_physical: r   z## Win32 monitorsr   rl   zwin32_virtual_bounds: r   z## Display devicesr   z  [r)   ry   r'   rz   z	 / flags=r{   
)r^   rr   r	   r   r   r
   r,   join)r   linesr   rc   ds        r    format_report_textr      sa   E	LL-...	LL8vzz+6688999	LL2FJJx0022333	LL:

< 8 8::;;;	LL6fjj4466777	LL:

< 8 8::;;;	LL6fjj4466777	LL	LL"###	LLstttZZ++ ) )eU##aeeGQ''((QUU61%%&&AEE%OO$$aeeGQ''((quuXq))**aeeGQ''((quuXq))**y%0011quuXr**++QUU62&&''%%..
 
 
 	TCIIKK'((((	LLffjjAc6d6dffggg	LL	LL$%%%ZZ("-- ) )eW%%aeeGQ''((QUU61%%&&AEE%OO$$aeeGQ''((quuXq))**aeeGQ''((quuXq))**y%0011quuXr**++QUU62&&''%%..
 
 
 	TCIIKK'((((	LLN&**5K*L*LNNOOO	LL	LL%&&&ZZ)2.. 
 
q!%%..qqAEE,$7$7qqAEE.<Q<Qqq\]\a\abn\o\oqq	
 	
 	
 	
 
LL99Ur"   _monitor_probe_outputout_dir
str | Pathtuple[Path, Path]c                &   t          |           }|                    dd           t                      }|dz  }|dz  }|                    t	          j        |dd          d	           |                    t          |          d	           ||fS )
NT)parentsexist_okzmonitor_report.jsonzmonitor_report.txtFr8   )ensure_asciiindentzutf-8)encoding)r   mkdirr   
write_textjsondumpsr   )r   outr   	json_pathtxt_paths        r    save_probe_reportr   4  s    
w--CIIdTI***  F++I))HFqIIIT[\\\*622WEEEhr"   __main__r.   r-   )r   rV   )r   rw   )r]   rV   r   r   )r   r#   r   r
   )r   )r   r   r   r   )"__doc__
__future__r   r:   r   r9   rE   r   r   dataclassesr   r   pathlibr   typingr   rX   ro   win32guir>   r	   rC   rU   rd   rf   rv   r   r   r   r   r   r/   r   printr4   r"   r    <module>r      s-     # " " " " "   				  



  ) ) ) ) ) ) ) )             



OOOOOOO   HHHH
 
 
 
 
 
 
 
 
@I I I I$   ,   6# # # #
$ $ $ $N   2   "   (; ; ; ;|     z  F	E

V
$
$%%%%% s   A 	AA