/* ------------- normal.c ------------ */ #include "dflat.h" #ifdef INCLUDE_MULTI_WINDOWS static void PaintOverLappers(DFWINDOW wnd); static void PaintUnderLappers(DFWINDOW wnd); #endif static BOOL InsideWindow(DFWINDOW, int, int); static void TerminateMoveSize(void); static void SaveBorder(DFRECT); static void RestoreBorder(DFRECT); static void GetVideoBuffer(DFWINDOW); static void PutVideoBuffer(DFWINDOW); #ifdef INCLUDE_MINIMIZE static DFRECT PositionIcon(DFWINDOW); #endif static void dragborder(DFWINDOW, int, int); static void sizeborder(DFWINDOW, int, int); static int px = -1, py = -1; static int diff; static struct DfWindow dwnd = {DF_DUMMY, NULL, DfNormalProc, {{-1},{-1},{-1},{-1}}}; static PCHAR_INFO Bsave; static int Bht, Bwd; BOOL DfWindowMoving; BOOL DfWindowSizing; /* -------- array of class definitions -------- */ DFCLASSDEFS DfClassDefs[] = { #undef DfClassDef #define DfClassDef(c,b,p,a) {b,p,a}, #include "classes.h" }; DFWINDOW HiddenWindow; /* --------- DFM_CREATE_WINDOW Message ---------- */ static void CreateWindowMsg(DFWINDOW wnd) { DfAppendWindow(wnd); // DfClearAttribute(wnd, DF_VSCROLLBAR | DF_HSCROLLBAR); if (DfTestAttribute(wnd, DF_SAVESELF) && DfIsVisible(wnd)) GetVideoBuffer(wnd); } /* --------- DFM_SHOW_WINDOW Message ---------- */ static void ShowWindowMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2) { if (DfGetParent(wnd) == NULL || DfIsVisible(DfGetParent(wnd))) { DFWINDOW cwnd; if (DfTestAttribute(wnd, DF_SAVESELF) && wnd->videosave == NULL) GetVideoBuffer(wnd); DfSetVisible(wnd); DfSendMessage(wnd, DFM_PAINT, 0, TRUE); DfSendMessage(wnd, DFM_BORDER, 0, 0); /* --- show the children of this window --- */ cwnd = DfFirstWindow(wnd); while (cwnd != NULL) { if (cwnd->condition != DF_ISCLOSING) DfSendMessage(cwnd, DFM_SHOW_WINDOW, p1, p2); cwnd = DfNextWindow(cwnd); } } } /* --------- HIDE_WINDOW Message ---------- */ static void HideWindowMsg(DFWINDOW wnd) { if (DfIsVisible(wnd)) { DfClearVisible(wnd); /* --- paint what this window covered --- */ if (DfTestAttribute(wnd, DF_SAVESELF)) PutVideoBuffer(wnd); #ifdef INCLUDE_MULTI_WINDOWS else PaintOverLappers(wnd); #endif } } /* --------- DFM_KEYBOARD Message ---------- */ static BOOL KeyboardMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2) { if (DfWindowMoving || DfWindowSizing) { /* -- move or size a window with keyboard -- */ int x, y; x=DfWindowMoving?DfGetLeft(&dwnd):DfGetRight(&dwnd); y=DfWindowMoving?DfGetTop(&dwnd):DfGetBottom(&dwnd); switch ((int)p1) { case DF_ESC: TerminateMoveSize(); return TRUE; case DF_UP: if (y) --y; break; case DF_DN: if (y < DfGetScreenHeight()-1) y++; break; case DF_FWD: if (x < DfGetScreenWidth()-1) x++; break; case DF_BS: if (x) --x; break; case '\r': DfSendMessage(wnd, DFM_BUTTON_RELEASED,x,y); default: return TRUE; } /* -- use the mouse functions to move/size - */ DfSendMessage(wnd, MOUSE_MOVED, x, y); return TRUE; } switch ((int)p1) { case DF_F1: DfSendMessage(wnd, DFM_COMMAND, DF_ID_HELP, 0); return TRUE; case ' ': if ((int)p2 & DF_ALTKEY) if (DfTestAttribute(wnd, DF_HASTITLEBAR)) if (DfTestAttribute(wnd, DF_CONTROLBOX)) DfBuildSystemMenu(wnd); return TRUE; case DF_CTRL_F4: if (DfTestAttribute(wnd, DF_CONTROLBOX)) { DfSendMessage(wnd, DFM_CLOSE_WINDOW, 0, 0); DfSkipApplicationControls(); return TRUE; } break; default: break; } return FALSE; } /* --------- COMMAND Message ---------- */ static void CommandMsg(DFWINDOW wnd, DF_PARAM p1) { switch ((int)p1) { case DF_ID_HELP: DfDisplayHelp(wnd,DfClassNames[DfGetClass(wnd)]); break; #ifdef INCLUDE_RESTORE case DF_ID_SYSRESTORE: DfSendMessage(wnd, DFM_RESTORE, 0, 0); break; #endif case DF_ID_SYSMOVE: DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE, (DF_PARAM) &dwnd); DfSendMessage(wnd, DFM_CAPTURE_KEYBOARD, TRUE, (DF_PARAM) &dwnd); DfWindowMoving = TRUE; dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd)); break; case DF_ID_SYSSIZE: DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE, (DF_PARAM) &dwnd); DfSendMessage(wnd, DFM_CAPTURE_KEYBOARD, TRUE, (DF_PARAM) &dwnd); DfWindowSizing = TRUE; dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd)); break; #ifdef INCLUDE_MINIMIZE case DF_ID_SYSMINIMIZE: DfSendMessage(wnd, DFM_MINIMIZE, 0, 0); break; #endif #ifdef INCLUDE_MAXIMIZE case DF_ID_SYSMAXIMIZE: DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0); break; #endif case DF_ID_SYSCLOSE: DfSendMessage(wnd, DFM_CLOSE_WINDOW, 0, 0); DfSkipApplicationControls(); break; default: break; } } /* --------- DFM_SETFOCUS Message ---------- */ static void SetFocusMsg(DFWINDOW wnd, DF_PARAM p1) { DFRECT rc = {0,0,0,0}; if (p1 && wnd != NULL && DfInFocus != wnd) { DFWINDOW this, thispar; DFWINDOW that = NULL, thatpar = NULL; DFWINDOW cwnd = wnd, fwnd = DfGetParent(wnd); /* ---- post focus in ancestors ---- */ while (fwnd != NULL) { fwnd->childfocus = cwnd; cwnd = fwnd; fwnd = DfGetParent(fwnd); } /* ---- de-post focus in self and children ---- */ fwnd = wnd; while (fwnd != NULL) { cwnd = fwnd->childfocus; fwnd->childfocus = NULL; fwnd = cwnd; } this = wnd; that = thatpar = DfInFocus; /* ---- find common ancestor of prev focus and this window --- */ while (thatpar != NULL) { thispar = wnd; while (thispar != NULL) { if (this == DfCaptureMouse || this == DfCaptureKeyboard) { /* ---- don't repaint if this window has capture ---- */ that = thatpar = NULL; break; } if (thispar == thatpar) { /* ---- don't repaint if DF_SAVESELF window had focus ---- */ if (this != that && DfTestAttribute(that, DF_SAVESELF)) that = thatpar = NULL; break; } this = thispar; thispar = DfGetParent(thispar); } if (thispar != NULL) break; that = thatpar; thatpar = DfGetParent(thatpar); } if (DfInFocus != NULL) DfSendMessage(DfInFocus, DFM_SETFOCUS, FALSE, 0); DfInFocus = wnd; if (that != NULL && DfIsVisible(wnd)) { rc = DfSubRectangle(DfWindowRect(that), DfWindowRect(this)); if (!DfValidRect(rc)) { if (DfApplicationWindow != NULL) { DFWINDOW fwnd = DfFirstWindow(DfApplicationWindow); while (fwnd != NULL) { if (!DfIsAncestor(wnd, fwnd)) { rc = DfSubRectangle(DfWindowRect(wnd),DfWindowRect(fwnd)); if (DfValidRect(rc)) break; } fwnd = DfNextWindow(fwnd); } } } } if (that != NULL && !DfValidRect(rc) && DfIsVisible(wnd)) { DfSendMessage(wnd, DFM_BORDER, 0, 0); this = NULL; } DfReFocus(wnd); if (this != NULL) DfSendMessage(this, DFM_SHOW_WINDOW, 0, 0); } else if (!p1 && DfInFocus == wnd) { /* clearing focus */ DfInFocus = NULL; DfSendMessage(wnd, DFM_BORDER, 0, 0); } } /* --------- DOUBLE_CLICK Message ---------- */ static void DoubleClickMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2) { int mx = (int) p1 - DfGetLeft(wnd); int my = (int) p2 - DfGetTop(wnd); if (!DfWindowSizing && !DfWindowMoving) { if (DfHitControlBox(wnd, mx, my)) { DfPostMessage(wnd, DFM_CLOSE_WINDOW, 0, 0); DfSkipApplicationControls(); } } } /* --------- DFM_LEFT_BUTTON Message ---------- */ static void LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2) { int mx = (int) p1 - DfGetLeft(wnd); int my = (int) p2 - DfGetTop(wnd); if (DfWindowSizing || DfWindowMoving) return; if (DfHitControlBox(wnd, mx, my)) { DfBuildSystemMenu(wnd); return; } if (my == 0 && mx > -1 && mx < DfWindowWidth(wnd)) { /* ---------- hit the top border -------- */ if (DfTestAttribute(wnd, DF_MINMAXBOX) && DfTestAttribute(wnd, DF_HASTITLEBAR)) { if (mx == DfWindowWidth(wnd)-2) { if (wnd->condition != DF_SRESTORED) /* --- hit the restore box --- */ DfSendMessage(wnd, DFM_RESTORE, 0, 0); #ifdef INCLUDE_MAXIMIZE else /* --- hit the maximize box --- */ DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0); #endif return; } #ifdef INCLUDE_MINIMIZE if (mx == DfWindowWidth(wnd)-3) { /* --- hit the minimize box --- */ if (wnd->condition != DF_ISMINIMIZED) DfSendMessage(wnd, DFM_MINIMIZE, 0, 0); return; } #endif } #ifdef INCLUDE_MAXIMIZE if (wnd->condition == DF_ISMAXIMIZED) return; #endif if (DfTestAttribute(wnd, DF_MOVEABLE)) { DfWindowMoving = TRUE; px = mx; py = my; diff = (int) mx; DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE, (DF_PARAM) &dwnd); dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd)); } return; } if (mx == DfWindowWidth(wnd)-1 && my == DfWindowHeight(wnd)-1) { /* ------- hit the resize corner ------- */ #ifdef INCLUDE_MINIMIZE if (wnd->condition == DF_ISMINIMIZED) return; #endif if (!DfTestAttribute(wnd, DF_SIZEABLE)) return; #ifdef INCLUDE_MAXIMIZE if (wnd->condition == DF_ISMAXIMIZED) { if (DfGetParent(wnd) == NULL) return; if (DfTestAttribute(DfGetParent(wnd),DF_HASBORDER)) return; /* ----- resizing a maximized window over a borderless parent ----- */ wnd = DfGetParent(wnd); } #endif DfWindowSizing = TRUE; DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE, (DF_PARAM) &dwnd); dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd)); } } /* --------- MOUSE_MOVED Message ---------- */ static BOOL MouseMovedMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2) { if (DfWindowMoving) { int leftmost = 0, topmost = 0, bottommost = DfGetScreenHeight()-2, rightmost = DfGetScreenWidth()-2; int x = (int) p1 - diff; int y = (int) p2; if (DfGetParent(wnd) != NULL && !DfTestAttribute(wnd, DF_NOCLIP)) { DFWINDOW wnd1 = DfGetParent(wnd); topmost = DfGetClientTop(wnd1); leftmost = DfGetClientLeft(wnd1); bottommost = DfGetClientBottom(wnd1); rightmost = DfGetClientRight(wnd1); } if (x < leftmost || x > rightmost || y < topmost || y > bottommost) { x = max(x, leftmost); x = min(x, rightmost); y = max(y, topmost); y = min(y, bottommost); } if (x != px || y != py) { px = x; py = y; dragborder(wnd, x, y); } return TRUE; } if (DfWindowSizing) { sizeborder(wnd, (int) p1, (int) p2); return TRUE; } return FALSE; } #ifdef INCLUDE_MAXIMIZE /* --------- DFM_MAXIMIZE Message ---------- */ static void MaximizeMsg(DFWINDOW wnd) { DFRECT rc = {0, 0, 0, 0}; DFRECT holdrc; holdrc = wnd->RestoredRC; rc.rt = DfGetScreenWidth()-1; rc.bt = DfGetScreenHeight()-1; if (DfGetParent(wnd)) rc = DfClientRect(DfGetParent(wnd)); wnd->oldcondition = wnd->condition; wnd->condition = DF_ISMAXIMIZED; DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); DfSendMessage(wnd, DFM_MOVE, DfRectLeft(rc), DfRectTop(rc)); DfSendMessage(wnd, DFM_DFM_SIZE, DfRectRight(rc), DfRectBottom(rc)); if (wnd->restored_attrib == 0) wnd->restored_attrib = wnd->attrib; DfClearAttribute(wnd, DF_SHADOW); DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0); wnd->RestoredRC = holdrc; } #endif #ifdef INCLUDE_MINIMIZE /* --------- DFM_MINIMIZE Message ---------- */ static void MinimizeMsg(DFWINDOW wnd) { DFRECT rc; DFRECT holdrc; holdrc = wnd->RestoredRC; rc = PositionIcon(wnd); wnd->oldcondition = wnd->condition; wnd->condition = DF_ISMINIMIZED; DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); DfSendMessage(wnd, DFM_MOVE, DfRectLeft(rc), DfRectTop(rc)); DfSendMessage(wnd, DFM_DFM_SIZE, DfRectRight(rc), DfRectBottom(rc)); if (wnd == DfInFocus) DfSetNextFocus(); if (wnd->restored_attrib == 0) wnd->restored_attrib = wnd->attrib; DfClearAttribute(wnd, DF_SHADOW | DF_SIZEABLE | DF_HASMENUBAR | DF_VSCROLLBAR | DF_HSCROLLBAR); DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0); wnd->RestoredRC = holdrc; } #endif #ifdef INCLUDE_RESTORE /* --------- DFM_RESTORE Message ---------- */ static void RestoreMsg(DFWINDOW wnd) { DFRECT holdrc; holdrc = wnd->RestoredRC; wnd->oldcondition = wnd->condition; wnd->condition = DF_SRESTORED; DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); wnd->attrib = wnd->restored_attrib; wnd->restored_attrib = 0; DfSendMessage(wnd, DFM_MOVE, wnd->RestoredRC.lf, wnd->RestoredRC.tp); wnd->RestoredRC = holdrc; DfSendMessage(wnd, DFM_DFM_SIZE, wnd->RestoredRC.rt, wnd->RestoredRC.bt); if (wnd != DfInFocus) DfSendMessage(wnd, DFM_SETFOCUS, TRUE, 0); else DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0); } #endif /* --------- DFM_MOVE Message ---------- */ static void MoveMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2) { DFWINDOW cwnd; BOOL wasVisible = DfIsVisible(wnd); int xdif = (int) p1 - wnd->rc.lf; int ydif = (int) p2 - wnd->rc.tp; if (xdif == 0 && ydif == 0) return; if (wasVisible) DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); wnd->rc.lf = (int) p1; wnd->rc.tp = (int) p2; wnd->rc.rt = DfGetLeft(wnd)+DfWindowWidth(wnd)-1; wnd->rc.bt = DfGetTop(wnd)+DfWindowHeight(wnd)-1; if (wnd->condition == DF_SRESTORED) wnd->RestoredRC = wnd->rc; cwnd = DfFirstWindow(wnd); while (cwnd != NULL) { DfSendMessage(cwnd, DFM_MOVE, cwnd->rc.lf+xdif, cwnd->rc.tp+ydif); cwnd = DfNextWindow(cwnd); } if (wasVisible) DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0); } /* --------- SIZE Message ---------- */ static void SizeMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2) { BOOL wasVisible = DfIsVisible(wnd); DFWINDOW cwnd; DFRECT rc; int xdif = (int) p1 - wnd->rc.rt; int ydif = (int) p2 - wnd->rc.bt; if (xdif == 0 && ydif == 0) return; if (wasVisible) DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); wnd->rc.rt = (int) p1; wnd->rc.bt = (int) p2; wnd->ht = DfGetBottom(wnd)-DfGetTop(wnd)+1; wnd->wd = DfGetRight(wnd)-DfGetLeft(wnd)+1; if (wnd->condition == DF_SRESTORED) wnd->RestoredRC = DfWindowRect(wnd); #ifdef INCLUDE_MAXIMIZE rc = DfClientRect(wnd); cwnd = DfFirstWindow(wnd); while (cwnd != NULL) { if (cwnd->condition == DF_ISMAXIMIZED) DfSendMessage(cwnd, DFM_DFM_SIZE, DfRectRight(rc), DfRectBottom(rc)); cwnd = DfNextWindow(cwnd); } #endif if (wasVisible) DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0); } /* --------- DFM_CLOSE_WINDOW Message ---------- */ static void CloseWindowMsg(DFWINDOW wnd) { DFWINDOW cwnd; wnd->condition = DF_ISCLOSING; if (wnd->PrevMouse != NULL) DfSendMessage(wnd, DFM_RELEASE_MOUSE, 0, 0); if (wnd->PrevKeyboard != NULL) DfSendMessage(wnd, DFM_RELEASE_KEYBOARD, 0, 0); /* ----------- hide this window ------------ */ DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); /* --- close the children of this window --- */ cwnd = DfLastWindow(wnd); while (cwnd != NULL) { if (DfInFocus == cwnd) DfInFocus = wnd; DfSendMessage(cwnd,DFM_CLOSE_WINDOW,0,0); cwnd = DfLastWindow(wnd); } /* --- change focus if this window had it -- */ if (wnd == DfInFocus) DfSetPrevFocus(); /* -- free memory allocated to this window - */ if (wnd->title != NULL) free(wnd->title); if (wnd->videosave != NULL) free(wnd->videosave); /* -- remove window from parent's list of children -- */ DfRemoveWindow(wnd); if (wnd == DfInFocus) DfInFocus = NULL; free(wnd); } /* ---- Window-processing module for DF_NORMAL window class ---- */ int DfNormalProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2) { switch (msg) { case DFM_CREATE_WINDOW: CreateWindowMsg(wnd); break; case DFM_SHOW_WINDOW: ShowWindowMsg(wnd, p1, p2); break; case DFM_HIDE_WINDOW: HideWindowMsg(wnd); break; case DFM_DISPLAY_HELP: DfDisplayHelp(wnd, (char *)p1); break; case DFM_INSIDE_WINDOW: return InsideWindow(wnd, (int) p1, (int) p2); case DFM_KEYBOARD: if (KeyboardMsg(wnd, p1, p2)) return TRUE; /* ------- fall through ------- */ case DFM_ADDSTATUS: case DFM_SHIFT_CHANGED: if (DfGetParent(wnd) != NULL) DfPostMessage(DfGetParent(wnd), msg, p1, p2); break; case DFM_PAINT: if (DfIsVisible(wnd)) DfClearWindow(wnd, (DFRECT *)p1, ' '); break; case DFM_BORDER: if (DfIsVisible(wnd)) { if (DfTestAttribute(wnd, DF_HASBORDER)) DfRepaintBorder(wnd, (DFRECT *)p1); else if (DfTestAttribute(wnd, DF_HASTITLEBAR)) DfDisplayTitle(wnd, (DFRECT *)p1); } break; case DFM_COMMAND: CommandMsg(wnd, p1); break; case DFM_SETFOCUS: SetFocusMsg(wnd, p1); break; case DFM_DOUBLE_CLICK: DoubleClickMsg(wnd, p1, p2); break; case DFM_LEFT_BUTTON: LeftButtonMsg(wnd, p1, p2); break; case MOUSE_MOVED: if (MouseMovedMsg(wnd, p1, p2)) return TRUE; break; case DFM_BUTTON_RELEASED: if (DfWindowMoving || DfWindowSizing) { if (DfWindowMoving) DfPostMessage(wnd,DFM_MOVE,dwnd.rc.lf,dwnd.rc.tp); else DfPostMessage(wnd, DFM_DFM_SIZE,dwnd.rc.rt,dwnd.rc.bt); TerminateMoveSize(); } break; #ifdef INCLUDE_MAXIMIZE case DFM_MAXIMIZE: if (wnd->condition != DF_ISMAXIMIZED) MaximizeMsg(wnd); break; #endif #ifdef INCLUDE_MINIMIZE case DFM_MINIMIZE: if (wnd->condition != DF_ISMINIMIZED) MinimizeMsg(wnd); break; #endif #ifdef INCLUDE_RESTORE case DFM_RESTORE: if (wnd->condition != DF_SRESTORED) { #ifdef INCLUDE_MAXIMIZE if (wnd->oldcondition == DF_ISMAXIMIZED) DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0); else #endif RestoreMsg(wnd); } break; #endif case DFM_MOVE: MoveMsg(wnd, p1, p2); break; case DFM_DFM_SIZE: { SizeMsg(wnd, p1, p2); break; } case DFM_CLOSE_WINDOW: CloseWindowMsg(wnd); break; default: break; } return TRUE; } #ifdef INCLUDE_MINIMIZE /* ---- compute lower right icon space in a rectangle ---- */ static DFRECT LowerRight(DFRECT prc) { DFRECT rc; DfRectLeft(rc) = DfRectRight(prc) - DF_ICONWIDTH; DfRectTop(rc) = DfRectBottom(prc) - DF_ICONHEIGHT; DfRectRight(rc) = DfRectLeft(rc)+DF_ICONWIDTH-1; DfRectBottom(rc) = DfRectTop(rc)+DF_ICONHEIGHT-1; return rc; } /* ----- compute a position for a minimized window icon ---- */ static DFRECT PositionIcon(DFWINDOW wnd) { DFWINDOW pwnd = DfGetParent(wnd); DFRECT rc; DfRectLeft(rc) = DfGetScreenWidth()-DF_ICONWIDTH; DfRectTop(rc) = DfGetScreenHeight()-DF_ICONHEIGHT; DfRectRight(rc) = DfGetScreenWidth()-1; DfRectBottom(rc) = DfGetScreenHeight()-1; if (pwnd != NULL) { DFRECT prc = DfWindowRect(pwnd); DFWINDOW cwnd = DfFirstWindow(pwnd); rc = LowerRight(prc); /* - search for icon available location - */ while (cwnd != NULL) { if (cwnd->condition == DF_ISMINIMIZED) { DFRECT rc1; rc1 = DfWindowRect(cwnd); if (DfRectLeft(rc1) == DfRectLeft(rc) && DfRectTop(rc1) == DfRectTop(rc)) { DfRectLeft(rc) -= DF_ICONWIDTH; DfRectRight(rc) -= DF_ICONWIDTH; if (DfRectLeft(rc) < DfRectLeft(prc)+1) { DfRectLeft(rc) = DfRectRight(prc)-DF_ICONWIDTH; DfRectRight(rc) = DfRectLeft(rc)+DF_ICONWIDTH-1; DfRectTop(rc) -= DF_ICONHEIGHT; DfRectBottom(rc) -= DF_ICONHEIGHT; if (DfRectTop(rc) < DfRectTop(prc)+1) return LowerRight(prc); } break; } } cwnd = DfNextWindow(cwnd); } } return rc; } #endif /* ----- terminate the move or size operation ----- */ static void TerminateMoveSize(void) { px = py = -1; diff = 0; DfSendMessage(&dwnd, DFM_RELEASE_MOUSE, TRUE, 0); DfSendMessage(&dwnd, DFM_RELEASE_KEYBOARD, TRUE, 0); RestoreBorder(dwnd.rc); DfWindowMoving = DfWindowSizing = FALSE; } /* ---- build a dummy window border for moving or sizing --- */ static void dragborder(DFWINDOW wnd, int x, int y) { RestoreBorder(dwnd.rc); /* ------- build the dummy window -------- */ dwnd.rc.lf = x; dwnd.rc.tp = y; dwnd.rc.rt = dwnd.rc.lf+DfWindowWidth(wnd)-1; dwnd.rc.bt = dwnd.rc.tp+DfWindowHeight(wnd)-1; dwnd.ht = DfWindowHeight(wnd); dwnd.wd = DfWindowWidth(wnd); dwnd.parent = DfGetParent(wnd); dwnd.attrib = DF_VISIBLE | DF_HASBORDER | DF_NOCLIP; DfInitWindowColors(&dwnd); SaveBorder(dwnd.rc); DfRepaintBorder(&dwnd, NULL); } /* ---- write the dummy window border for sizing ---- */ static void sizeborder(DFWINDOW wnd, int rt, int bt) { int leftmost = DfGetLeft(wnd)+10; int topmost = DfGetTop(wnd)+3; int bottommost = DfGetScreenHeight()-1; int rightmost = DfGetScreenWidth()-1; if (DfGetParent(wnd)) { bottommost = min(bottommost, DfGetClientBottom(DfGetParent(wnd))); rightmost = min(rightmost, DfGetClientRight(DfGetParent(wnd))); } rt = min(rt, rightmost); bt = min(bt, bottommost); rt = max(rt, leftmost); bt = max(bt, topmost); if (rt != px || bt != py) RestoreBorder(dwnd.rc); /* ------- change the dummy window -------- */ dwnd.ht = bt-dwnd.rc.tp+1; dwnd.wd = rt-dwnd.rc.lf+1; dwnd.rc.rt = rt; dwnd.rc.bt = bt; if (rt != px || bt != py) { px = rt; py = bt; SaveBorder(dwnd.rc); DfRepaintBorder(&dwnd, NULL); } } #ifdef INCLUDE_MULTI_WINDOWS /* ----- adjust a rectangle to include the shadow ----- */ static DFRECT adjShadow(DFWINDOW wnd) { DFRECT rc; rc = wnd->rc; if (DfTestAttribute(wnd, DF_SHADOW)) { if (DfRectRight(rc) < DfGetScreenWidth()-1) DfRectRight(rc)++; if (DfRectBottom(rc) < DfGetScreenHeight()-1) DfRectBottom(rc)++; } return rc; } /* --- repaint a rectangular subsection of a window --- */ static void PaintOverLap(DFWINDOW wnd, DFRECT rc) { if (DfIsVisible(wnd)) { int isBorder, isTitle, isData; isBorder = isTitle = FALSE; isData = TRUE; if (DfTestAttribute(wnd, DF_HASBORDER)) { isBorder = DfRectLeft(rc) == 0 && DfRectTop(rc) < DfWindowHeight(wnd); isBorder |= DfRectLeft(rc) < DfWindowWidth(wnd) && DfRectRight(rc) >= DfWindowWidth(wnd)-1 && DfRectTop(rc) < DfWindowHeight(wnd); isBorder |= DfRectTop(rc) == 0 && DfRectLeft(rc) < DfWindowWidth(wnd); isBorder |= DfRectTop(rc) < DfWindowHeight(wnd) && DfRectBottom(rc) >= DfWindowHeight(wnd)-1 && DfRectLeft(rc) < DfWindowWidth(wnd); } else if (DfTestAttribute(wnd, DF_HASTITLEBAR)) isTitle = DfRectTop(rc) == 0 && DfRectRight(rc) > 0 && DfRectLeft(rc)= DfWindowWidth(wnd)-DfBorderAdj(wnd)) isData = FALSE; if (DfRectTop(rc) >= DfWindowHeight(wnd)-DfBottomBorderAdj(wnd)) isData = FALSE; if (DfTestAttribute(wnd, DF_HASBORDER)) { if (DfRectRight(rc) == 0) isData = FALSE; if (DfRectBottom(rc) == 0) isData = FALSE; } if (DfTestAttribute(wnd, DF_SHADOW)) isBorder |= DfRectRight(rc) == DfWindowWidth(wnd) || DfRectBottom(rc) == DfWindowHeight(wnd); if (isData) DfSendMessage(wnd, DFM_PAINT, (DF_PARAM) &rc, TRUE); if (isBorder) DfSendMessage(wnd, DFM_BORDER, (DF_PARAM) &rc, 0); else if (isTitle) DfDisplayTitle(wnd, &rc); } } /* ------ paint the part of a window that is overlapped by another window that is being hidden ------- */ static void PaintOver(DFWINDOW wnd) { DFRECT wrc, rc; wrc = adjShadow(HiddenWindow); rc = adjShadow(wnd); rc = DfSubRectangle(rc, wrc); if (DfValidRect(rc)) PaintOverLap(wnd, DfRelativeWindowRect(wnd, rc)); } /* --- paint the overlapped parts of all children --- */ static void PaintOverChildren(DFWINDOW pwnd) { DFWINDOW cwnd = DfFirstWindow(pwnd); while (cwnd != NULL) { if (cwnd != HiddenWindow) { PaintOver(cwnd); PaintOverChildren(cwnd); } cwnd = DfNextWindow(cwnd); } } /* -- recursive overlapping paint of parents -- */ static void PaintOverParents(DFWINDOW wnd) { DFWINDOW pwnd = DfGetParent(wnd); if (pwnd != NULL) { PaintOverParents(pwnd); PaintOver(pwnd); PaintOverChildren(pwnd); } } /* - paint the parts of all windows that a window is over - */ static void PaintOverLappers(DFWINDOW wnd) { HiddenWindow = wnd; PaintOverParents(wnd); } /* --- paint those parts of a window that are overlapped --- */ static void PaintUnderLappers(DFWINDOW wnd) { DFWINDOW hwnd = DfNextWindow(wnd); while (hwnd != NULL) { /* ------- test only at document window level ------ */ DFWINDOW pwnd = DfGetParent(hwnd); /* if (pwnd == NULL || DfGetClass(pwnd) == DF_APPLICATION) */ { /* ---- don't bother testing self ----- */ if (DfIsVisible(hwnd) && hwnd != wnd) { /* --- see if other window is descendent --- */ while (pwnd != NULL) { if (pwnd == wnd) break; pwnd = DfGetParent(pwnd); } /* ----- don't test descendent overlaps ----- */ if (pwnd == NULL) { /* -- see if other window is ancestor --- */ pwnd = DfGetParent(wnd); while (pwnd != NULL) { if (pwnd == hwnd) break; pwnd = DfGetParent(pwnd); } /* --- don't test ancestor overlaps --- */ if (pwnd == NULL) { HiddenWindow = DfGetAncestor(hwnd); DfClearVisible(HiddenWindow); PaintOver(wnd); DfSetVisible(HiddenWindow); } } } } hwnd = DfNextWindow(hwnd); } /* --------- repaint all children of this window the same way ----------- */ hwnd = DfFirstWindow(wnd); while (hwnd != NULL) { PaintUnderLappers(hwnd); hwnd = DfNextWindow(hwnd); } } #endif /* #ifdef INCLUDE_MULTI_WINDOWS */ /* --- save video area to be used by dummy window border --- */ static void SaveBorder(DFRECT rc) { Bht = DfRectBottom(rc) - DfRectTop(rc) + 1; Bwd = DfRectRight(rc) - DfRectLeft(rc) + 1; Bsave = DfRealloc(Bsave, Bht * Bwd * sizeof(CHAR_INFO)); DfGetVideo(rc,Bsave); } /* ---- restore video area used by dummy window border ---- */ static void RestoreBorder(DFRECT rc) { if (Bsave != NULL) { DfStoreVideo(rc, Bsave); free(Bsave); Bsave = NULL; } } /* ----- test if screen coordinates are in a window ---- */ static BOOL InsideWindow(DFWINDOW wnd, int x, int y) { DFRECT rc; rc = DfWindowRect(wnd); if (!DfTestAttribute(wnd, DF_NOCLIP)) { DFWINDOW pwnd = DfGetParent(wnd); while (pwnd != NULL) { rc = DfSubRectangle(rc, DfClientRect(pwnd)); pwnd = DfGetParent(pwnd); } } return DfInsideRect(x, y, rc); } BOOL DfIsDerivedFrom(DFWINDOW wnd, DFCLASS class) { DFCLASS tclass = DfGetClass(wnd); while (tclass != -1) { if (tclass == class) return TRUE; tclass = (DfClassDefs[tclass].base); } return FALSE; } /* -- find the oldest document window ancestor of a window -- */ DFWINDOW DfGetAncestor(DFWINDOW wnd) { if (wnd != NULL) { while (DfGetParent(wnd) != NULL) { if (DfGetClass(DfGetParent(wnd)) == DF_APPLICATION) break; wnd = DfGetParent(wnd); } } return wnd; } BOOL DfIsVisible(DFWINDOW wnd) { while (wnd != NULL) { if (isHidden(wnd)) return FALSE; wnd = DfGetParent(wnd); } return TRUE; } /* -- adjust a window's rectangle to clip it to its parent - */ static DFRECT ClipRect(DFWINDOW wnd) { DFRECT rc; rc = DfWindowRect(wnd); if (DfTestAttribute(wnd, DF_SHADOW)) { DfRectBottom(rc)++; DfRectRight(rc)++; } return DfClipRectangle(wnd, rc); } /* -- get the video memory that is to be used by a window -- */ static void GetVideoBuffer(DFWINDOW wnd) { DFRECT rc; int ht; int wd; rc = ClipRect(wnd); ht = DfRectBottom(rc) - DfRectTop(rc) + 1; wd = DfRectRight(rc) - DfRectLeft(rc) + 1; wnd->videosave = DfRealloc(wnd->videosave, (ht * wd * sizeof(CHAR_INFO))); DfGetVideo(rc, wnd->videosave); } /* -- put the video memory that is used by a window -- */ static void PutVideoBuffer(DFWINDOW wnd) { if (wnd->videosave != NULL) { DFRECT rc; rc = ClipRect(wnd); DfStoreVideo(rc, wnd->videosave); free(wnd->videosave); wnd->videosave = NULL; } } /* ------- return TRUE if awnd is an ancestor of wnd ------- */ BOOL DfIsAncestor(DFWINDOW wnd, DFWINDOW awnd) { while (wnd != NULL) { if (wnd == awnd) return TRUE; wnd = DfGetParent(wnd); } return FALSE; } /* EOF */