개요
µC/GUI의 윈도우 재그리기(Repaint) 메커니즘은 이벤트 기반 아키텍처를 이해하는 핵심입니다. 이 시스템은 '할리우드 법칙(Hollywood Principle: "저희에게 전화하지 마세요, 저희가 필요할 때 연락하겠습니다")'을 따르며, 그래픽 관리자가 사용자 정의 콜백 함수를 호출하여 화면을 갱신하는 방식을 취합니다. 이러한 구조는 클리핑 알고리즘과 결합하여 효율적인 화면 업데이트를 보장합니다.
핵심 데이터 구조
윈도우 관리는 WM_Obj 구조체를 중심으로 이루어지며, 각 윈도우는 고유의 콜백 함수 포인터와 무효 영역(Invalid Area) 정보를 포함합니다.
typedef struct {
GUI_RECT Rect; // 윈도우 경계 사각형
GUI_RECT InvalidArea; // 다시 그려야 할 영역
WM_CALLBACK* cb; // 사용자 정의 콜백 함수
WM_HWIN hNext; // 형제 윈도우 체인
WM_HWIN hParent; // 부모 윈도우
U16 Status; // 상태 플래그
} WM_Obj;
메시지 처리는 WM_MESSAGE 구조체를 통해 전달됩니다. 핵심 메시지인 WM_PAINT는 윈도우 관리자가 특정 윈도우를 다시 그려야 할 때 시스템 내부에서 발생시키는 이벤트입니다.
재그리기 처리 파이프라인
화면 갱신은 단순히 함수를 호출하는 것이 아니라, 여러 계층을 거쳐 실행되는 비동기적 흐름을 따릅니다. 주요 호출 스택은 다음과 같습니다:
GUI_Exec(): 최상위 루프, 처리가 필요한 모든 메시지 및 타이머를 처리합니다.WM_Exec(): 유효하지 않은 윈도우(Invalidated Windows)를 찾아 업데이트 프로세스를 시작합니다._DrawNext(): 윈도우 체인을 순회하며 재그리기가 필요한 노드를 식별합니다.WM__Paint(): 무효 상태인 윈도우를 선택하고, 실제 드로잉 수행 전 클리핑 영역을 계산합니다.WM__SendMessage(): 최종적으로 등록된 콜백 함수를 실행하여 사용자 정의 그리기 코드를 수행합니다.
메시지 발송 및 콜백 실행
WM__SendMessage 함수는 실제 작업을 수행하는 엔진입니다. 윈도우 객체에 콜백 함수가 등록되어 있다면 이를 직접 호출하고, 없다면 기본 처리 함수를 실행합니다.
void DispatchWindowMessage(WM_HWIN hWin, WM_MESSAGE* pMsg) {
WM_Obj* pObj = GetWindowPointer(hWin);
if (pObj->cb != NULL) {
// 등록된 콜백 함수 호출 (이벤트 처리)
pObj->cb(pMsg);
} else {
// 기본 윈도우 프로세스 실행
DefaultProc(pMsg);
}
}
재그리기 최적화
GUI 시스템은 효율성을 위해 한 번의 사이클에 전체 화면을 다 그리지 않습니다. _DrawNext 함수를 통해 호출되는 렌더링 로직은 다음 특징을 가집니다:
- 무효 영역 갱신:
WM__NumInvalidWindows카운터를 사용하여 변경이 필요한 윈도우만 타겟팅합니다. - 상태 복구:
GUI_SaveContext및GUI_RestoreContext를 사용하여 그래픽 컨텍스트(펜 색상, 폰트 등)가 훼손되지 않도록 보존합니다. - 분할 처리: 복잡한 윈도우의 경우
WM_ITERATE_START매크로를 활용해 클리핑 사각형 단위로 메시지를 분할 발송하여 메모리 부하를 줄입니다.
최종적으로 WM__Paint 내부에서 WM_SF_INVALID 플래그를 해제함으로써, 갱신된 영역이 다시 그려지지 않도록 하여 불필요한 연산을 방지합니다.