From: Eric Kohl Date: Sun, 5 Mar 2000 19:58:08 +0000 (+0000) Subject: Added D-Flat/32 library X-Git-Tag: backups/prep0016@12448~237 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=79d0e047ebe4bfa921ed559f9c8f40e57f0daa47 Added D-Flat/32 library svn path=/trunk/; revision=1032 --- diff --git a/rosapps/Makefile b/rosapps/Makefile index 03a1c1fbc84..23e905de5af 100644 --- a/rosapps/Makefile +++ b/rosapps/Makefile @@ -13,7 +13,7 @@ include rules.mak # # Available applications # -APPS = cmd cmdutils notevil sysutils +APPS = cmd cmdutils notevil sysutils dflat32 all: $(APPS) .PHONY: all diff --git a/rosapps/dflat32/applicat.c b/rosapps/dflat32/applicat.c new file mode 100644 index 00000000000..270cf06d618 --- /dev/null +++ b/rosapps/dflat32/applicat.c @@ -0,0 +1,621 @@ +/* ------------- applicat.c ------------- */ + +#include "dflat.h" + +static int ScreenHeight; +static BOOL DisplayModified = FALSE; +DFWINDOW ApplicationWindow; + +extern DBOX Display; +extern DBOX Windows; + +#ifdef INCLUDE_LOGGING +extern DBOX Log; +#endif + +#ifdef INCLUDE_SHELLDOS +static void ShellDOS(DFWINDOW); +#endif +static void DfCreateMenu(DFWINDOW); +static void CreateStatusBar(DFWINDOW); +static void SelectColors(DFWINDOW); + +#ifdef INCLUDE_WINDOWOPTIONS +static void SelectTexture(void); +static void SelectBorder(DFWINDOW); +static void SelectTitle(DFWINDOW); +static void SelectStatusBar(DFWINDOW); +#endif + +static DFWINDOW oldFocus; +#ifdef INCLUDE_MULTI_WINDOWS +static void CloseAll(DFWINDOW, int); +static void MoreWindows(DFWINDOW); +static void ChooseWindow(DFWINDOW, int); +static int WindowSel; +static char Menus[9][26] = +{ + "~1. ", + "~2. ", + "~3. ", + "~4. ", + "~5. ", + "~6. ", + "~7. ", + "~8. ", + "~9. " +}; +#endif + +/* --------------- CREATE_WINDOW Message -------------- */ +static int CreateWindowMsg(DFWINDOW wnd) +{ + int rtn; + ApplicationWindow = wnd; + ScreenHeight = SCREENHEIGHT; +#ifdef INCLUDE_WINDOWOPTIONS + if (cfg.Border) + SetCheckBox(&Display, ID_BORDER); + if (cfg.Title) + SetCheckBox(&Display, ID_TITLE); + if (cfg.StatusBar) + SetCheckBox(&Display, ID_STATUSBAR); + if (cfg.Texture) + SetCheckBox(&Display, ID_TEXTURE); +#endif + SelectColors(wnd); +#ifdef INCLUDE_WINDOWOPTIONS + SelectBorder(wnd); + SelectTitle(wnd); + SelectStatusBar(wnd); +#endif + rtn = BaseWndProc(APPLICATION, wnd, CREATE_WINDOW, 0, 0); + if (wnd->extension != NULL) + DfCreateMenu(wnd); + CreateStatusBar(wnd); + return rtn; +} + +/* --------- ADDSTATUS Message ---------- */ +static void AddStatusMsg(DFWINDOW wnd, PARAM p1) +{ + if (wnd->StatusBar != NULL) { + if (p1 && *(char *)p1) + DfSendMessage(wnd->StatusBar, SETTEXT, p1, 0); + else + DfSendMessage(wnd->StatusBar, CLEARTEXT, 0, 0); + DfSendMessage(wnd->StatusBar, PAINT, 0, 0); + } +} + +/* -------- SETFOCUS Message -------- */ +static void SetFocusMsg(DFWINDOW wnd, BOOL p1) +{ + if (p1) + DfSendMessage(inFocus, SETFOCUS, FALSE, 0); + inFocus = p1 ? wnd : NULL; + if (isVisible(wnd)) + DfSendMessage(wnd, BORDER, 0, 0); + else + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); +} + +/* ------- SIZE Message -------- */ +static void SizeMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + BOOL WasVisible; + WasVisible = isVisible(wnd); + if (WasVisible) + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + if (p1-GetLeft(wnd) < 30) + p1 = GetLeft(wnd) + 30; + BaseWndProc(APPLICATION, wnd, DFM_SIZE, p1, p2); + DfCreateMenu(wnd); + CreateStatusBar(wnd); + if (WasVisible) + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); +} + +/* ----------- KEYBOARD Message ------------ */ +static int KeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + if (WindowMoving || WindowSizing || (int) p1 == F1) + return BaseWndProc(APPLICATION, wnd, KEYBOARD, p1, p2); + switch ((int) p1) { + case ALT_F4: + DfPostMessage(wnd, CLOSE_WINDOW, 0, 0); + return TRUE; +#ifdef INCLUDE_MULTI_WINDOWS + case ALT_F6: + SetNextFocus(); + return TRUE; +#endif + case ALT_HYPHEN: + BuildSystemMenu(wnd); + return TRUE; + default: + break; + } + DfPostMessage(wnd->MenuBarWnd, KEYBOARD, p1, p2); + return TRUE; +} + +/* --------- SHIFT_CHANGED Message -------- */ +static void ShiftChangedMsg(DFWINDOW wnd, PARAM p1) +{ + extern BOOL AltDown; + if ((int)p1 & ALTKEY) + AltDown = TRUE; + else if (AltDown) { + AltDown = FALSE; + if (wnd->MenuBarWnd != inFocus) + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + DfSendMessage(wnd->MenuBarWnd, KEYBOARD, F10, 0); + } +} + +/* -------- COMMAND Message ------- */ +static void CommandMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + switch ((int)p1) { + case ID_HELP: + DisplayHelp(wnd, DFlatApplication); + break; + case ID_HELPHELP: + DisplayHelp(wnd, "HelpHelp"); + break; + case ID_EXTHELP: + DisplayHelp(wnd, "ExtHelp"); + break; + case ID_KEYSHELP: + DisplayHelp(wnd, "KeysHelp"); + break; + case ID_HELPINDEX: + DisplayHelp(wnd, "HelpIndex"); + break; +#ifdef TESTING_DFLAT + case ID_LOADHELP: + LoadHelpFile(); + break; +#endif +#ifdef INCLUDE_LOGGING + case ID_LOG: + MessageLog(wnd); + break; +#endif +#ifdef INCLUDE_SHELLDOS + case ID_DOS: + ShellDOS(wnd); + break; +#endif + case ID_EXIT: + case ID_SYSCLOSE: + DfPostMessage(wnd, CLOSE_WINDOW, 0, 0); + break; + case ID_DISPLAY: + if (DfDialogBox(wnd, &Display, TRUE, NULL)) { + if (inFocus == wnd->MenuBarWnd || inFocus == wnd->StatusBar) + oldFocus = ApplicationWindow; + else + oldFocus = inFocus; + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + SelectColors(wnd); +#ifdef INCLUDE_WINDOWOPTIONS + SelectBorder(wnd); + SelectTitle(wnd); + SelectStatusBar(wnd); + SelectTexture(); +#endif + DfCreateMenu(wnd); + CreateStatusBar(wnd); + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); + DfSendMessage(oldFocus, SETFOCUS, TRUE, 0); + } + break; + case ID_SAVEOPTIONS: + SaveConfig(); + break; +#ifdef INCLUDE_MULTI_WINDOWS + case ID_WINDOW: + ChooseWindow(wnd, (int)p2-2); + break; + case ID_CLOSEALL: + CloseAll(wnd, FALSE); + break; + case ID_MOREWINDOWS: + MoreWindows(wnd); + break; +#endif +#ifdef INCLUDE_RESTORE + case ID_SYSRESTORE: +#endif + case ID_SYSMOVE: + case ID_SYSSIZE: +#ifdef INCLUDE_MINIMIZE + case ID_SYSMINIMIZE: +#endif +#ifdef INCLUDE_MAXIMIZE + case ID_SYSMAXIMIZE: +#endif + BaseWndProc(APPLICATION, wnd, DFM_COMMAND, p1, p2); + break; + default: + if (inFocus != wnd->MenuBarWnd && inFocus != wnd) + DfPostMessage(inFocus, DFM_COMMAND, p1, p2); + break; + } +} + +/* --------- CLOSE_WINDOW Message -------- */ +static int CloseWindowMsg(DFWINDOW wnd) +{ + int rtn; +#ifdef INCLUDE_MULTI_WINDOWS + CloseAll(wnd, TRUE); + WindowSel = 0; +#endif + DfPostMessage(NULL, DFM_STOP, 0, 0); + rtn = BaseWndProc(APPLICATION, wnd, CLOSE_WINDOW, 0, 0); + UnLoadHelpFile(); + DisplayModified = FALSE; + ApplicationWindow = NULL; + return rtn; +} + +/* --- APPLICATION Window Class window processing module --- */ +int ApplicationProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) + { + case CREATE_WINDOW: + return CreateWindowMsg(wnd); + case DFM_HIDE_WINDOW: + if (wnd == inFocus) + inFocus = NULL; + break; + case ADDSTATUS: + AddStatusMsg(wnd, p1); + return TRUE; + case SETFOCUS: + if ((int)p1 == (inFocus != wnd)) { + SetFocusMsg(wnd, (BOOL) p1); + return TRUE; + } + break; + case DFM_SIZE: + SizeMsg(wnd, p1, p2); + return TRUE; +#ifdef INCLUDE_MINIMIZE + case MINIMIZE: + return TRUE; +#endif + case KEYBOARD: + return KeyboardMsg(wnd, p1, p2); + case SHIFT_CHANGED: + ShiftChangedMsg(wnd, p1); + return TRUE; + case PAINT: + if (isVisible(wnd)) { +#ifdef INCLUDE_WINDOWOPTIONS + int cl = cfg.Texture ? APPLCHAR : ' '; +#else + int cl = APPLCHAR; +#endif + ClearWindow(wnd, (DFRECT *)p1, cl); + } + return TRUE; + case DFM_COMMAND: + CommandMsg(wnd, p1, p2); + return TRUE; + case CLOSE_WINDOW: + return CloseWindowMsg(wnd); + default: + break; + } + return BaseWndProc(APPLICATION, wnd, msg, p1, p2); +} + +#ifdef INCLUDE_SHELLDOS +static void SwitchCursor(void) +{ + DfSendMessage(NULL, SAVE_CURSOR, 0, 0); + SwapCursorStack(); + DfSendMessage(NULL, RESTORE_CURSOR, 0, 0); +} + +/* ------- Shell out to DOS ---------- */ +static void ShellDOS(DFWINDOW wnd) +{ + oldFocus = inFocus; + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + SwitchCursor(); + printf("To return to %s, execute the DOS exit command.", + DFlatApplication); + fflush(stdout); + _spawnl(P_WAIT, getenv("COMSPEC"), " ", NULL); + SwitchCursor(); + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); + DfSendMessage(oldFocus, SETFOCUS, TRUE, 0); +} +#endif + +/* -------- Create the menu bar -------- */ +static void DfCreateMenu(DFWINDOW wnd) +{ + AddAttribute(wnd, HASMENUBAR); + if (wnd->MenuBarWnd != NULL) + DfSendMessage(wnd->MenuBarWnd, CLOSE_WINDOW, 0, 0); + wnd->MenuBarWnd = DfCreateWindow(MENUBAR, + NULL, + GetClientLeft(wnd), + GetClientTop(wnd)-1, + 1, + ClientWidth(wnd), + NULL, + wnd, + NULL, + 0); + DfSendMessage(wnd->MenuBarWnd,BUILDMENU, + (PARAM)wnd->extension,0); + AddAttribute(wnd->MenuBarWnd, VISIBLE); +} + +/* ----------- Create the status bar ------------- */ +static void CreateStatusBar(DFWINDOW wnd) +{ + if (wnd->StatusBar != NULL) { + DfSendMessage(wnd->StatusBar, CLOSE_WINDOW, 0, 0); + wnd->StatusBar = NULL; + } + if (TestAttribute(wnd, HASSTATUSBAR)) { + wnd->StatusBar = DfCreateWindow(STATUSBAR, + NULL, + GetClientLeft(wnd), + GetBottom(wnd), + 1, + ClientWidth(wnd), + NULL, + wnd, + NULL, + 0); + AddAttribute(wnd->StatusBar, VISIBLE); + } +} + +#ifdef INCLUDE_MULTI_WINDOWS +/* -------- return the name of a document window ------- */ +static char *WindowName(DFWINDOW wnd) +{ + if (GetTitle(wnd) == NULL) { + if (GetClass(wnd) == DIALOG) + return ((DBOX *)(wnd->extension))->HelpName; + else + return "Untitled"; + } + else + return GetTitle(wnd); +} + +/* ----------- Prepare the Window menu ------------ */ +void PrepWindowMenu(void *w, struct Menu *mnu) +{ + DFWINDOW wnd = w; + struct PopDown *p0 = mnu->Selections; + struct PopDown *pd = mnu->Selections + 2; + struct PopDown *ca = mnu->Selections + 13; + int MenuNo = 0; + DFWINDOW cwnd; + + mnu->Selection = 0; + oldFocus = NULL; + + if (GetClass(wnd) != APPLICATION) + { + oldFocus = wnd; + + /* point to the APPLICATION window */ + if (ApplicationWindow == NULL) + return; + + cwnd = FirstWindow(ApplicationWindow); + /* get the first 9 document windows */ + while (cwnd != NULL && MenuNo < 9) + { + if (GetClass(cwnd) != MENUBAR && + GetClass(cwnd) != STATUSBAR) + { + /* add the document window to the menu */ + strncpy (Menus[MenuNo]+4, WindowName(cwnd), 20); + pd->SelectionTitle = Menus[MenuNo]; + if (cwnd == oldFocus) + { + /* mark the current document */ + pd->Attrib |= CHECKED; + mnu->Selection = MenuNo+2; + } + else + pd->Attrib &= ~CHECKED; + pd++; + MenuNo++; + } + cwnd = NextWindow(cwnd); + } + } + + if (MenuNo) + p0->SelectionTitle = "~Close all"; + else + p0->SelectionTitle = NULL; + + if (MenuNo >= 9) + { + *pd++ = *ca; + if (mnu->Selection == 0) + mnu->Selection = 11; + } + pd->SelectionTitle = NULL; +} + +/* window processing module for the More Windows dialog box */ +static int WindowPrep(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + switch (msg) { + case INITIATE_DIALOG: { + DFWINDOW wnd1; + DFWINDOW cwnd = ControlWindow(&Windows,ID_WINDOWLIST); + int sel = 0; + if (cwnd == NULL) + return FALSE; + wnd1 = FirstWindow(ApplicationWindow); + while (wnd1 != NULL) { + if (wnd1 != wnd && GetClass(wnd1) != MENUBAR && + GetClass(wnd1) != STATUSBAR) { + if (wnd1 == oldFocus) + WindowSel = sel; + DfSendMessage(cwnd, ADDTEXT, + (PARAM) WindowName(wnd1), 0); + sel++; + } + wnd1 = NextWindow(wnd1); + } + DfSendMessage(cwnd, LB_SETSELECTION, WindowSel, 0); + AddAttribute(cwnd, VSCROLLBAR); + DfPostMessage(cwnd, SHOW_WINDOW, 0, 0); + break; + } + case DFM_COMMAND: + switch ((int) p1) { + case ID_OK: + if ((int)p2 == 0) + WindowSel = DfSendMessage( + ControlWindow(&Windows, + ID_WINDOWLIST), + LB_CURRENTSELECTION, 0, 0); + break; + case ID_WINDOWLIST: + if ((int) p2 == LB_CHOOSE) + DfSendMessage(wnd, DFM_COMMAND, ID_OK, 0); + break; + default: + break; + } + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +/* ---- the More Windows command on the Window menu ---- */ +static void MoreWindows(DFWINDOW wnd) +{ + if (DfDialogBox(wnd, &Windows, TRUE, WindowPrep)) + ChooseWindow(wnd, WindowSel); +} + +/* ----- user chose a window from the Window menu + or the More Window dialog box ----- */ +static void ChooseWindow(DFWINDOW wnd, int WindowNo) +{ + DFWINDOW cwnd = FirstWindow(wnd); + while (cwnd != NULL) { + if (GetClass(cwnd) != MENUBAR && + GetClass(cwnd) != STATUSBAR) + if (WindowNo-- == 0) + break; + cwnd = NextWindow(cwnd); + } + if (cwnd != NULL) { + DfSendMessage(cwnd, SETFOCUS, TRUE, 0); + if (cwnd->condition == ISMINIMIZED) + DfSendMessage(cwnd, RESTORE, 0, 0); + } +} + +/* ----- Close all document windows ----- */ +static void CloseAll(DFWINDOW wnd, int closing) +{ + DFWINDOW wnd1, wnd2; + + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + wnd1 = LastWindow(wnd); + while (wnd1 != NULL) + { + wnd2 = PrevWindow(wnd1); + if (GetClass(wnd1) != MENUBAR && GetClass(wnd1) != STATUSBAR) + { + ClearVisible(wnd1); + DfSendMessage(wnd1, CLOSE_WINDOW, 0, 0); + } + wnd1 = wnd2; + } + if (!closing) + DfSendMessage(wnd, PAINT, 0, 0); +} + +#endif /* #ifdef INCLUDE_MULTI_WINDOWS */ + +static void DoWindowColors(DFWINDOW wnd) +{ + DFWINDOW cwnd; + + InitWindowColors(wnd); + cwnd = FirstWindow(wnd); + while (cwnd != NULL) + { + DoWindowColors(cwnd); + if (GetClass(cwnd) == TEXT && GetText(cwnd) != NULL) + DfSendMessage(cwnd, CLEARTEXT, 0, 0); + cwnd = NextWindow(cwnd); + } +} + +/* set up colors for the application window */ +static void SelectColors(DFWINDOW wnd) +{ + memcpy(cfg.clr, color, sizeof color); + DoWindowColors(wnd); +} + + +#ifdef INCLUDE_WINDOWOPTIONS + +/* ----- select the screen texture ----- */ +static void SelectTexture(void) +{ + cfg.Texture = CheckBoxSetting(&Display, ID_TEXTURE); +} + +/* -- select whether the application screen has a border -- */ +static void SelectBorder(DFWINDOW wnd) +{ + cfg.Border = CheckBoxSetting(&Display, ID_BORDER); + if (cfg.Border) + AddAttribute(wnd, HASBORDER); + else + ClearAttribute(wnd, HASBORDER); +} + +/* select whether the application screen has a status bar */ +static void SelectStatusBar(DFWINDOW wnd) +{ + cfg.StatusBar = CheckBoxSetting(&Display, ID_STATUSBAR); + if (cfg.StatusBar) + AddAttribute(wnd, HASSTATUSBAR); + else + ClearAttribute(wnd, HASSTATUSBAR); +} + +/* select whether the application screen has a title bar */ +static void SelectTitle(DFWINDOW wnd) +{ + cfg.Title = CheckBoxSetting(&Display, ID_TITLE); + if (cfg.Title) + AddAttribute(wnd, HASTITLEBAR); + else + ClearAttribute(wnd, HASTITLEBAR); +} + +#endif + +/* EOF */ diff --git a/rosapps/dflat32/barchart.c b/rosapps/dflat32/barchart.c new file mode 100644 index 00000000000..020c1543e42 --- /dev/null +++ b/rosapps/dflat32/barchart.c @@ -0,0 +1,74 @@ +/* ------------ barchart.c ----------- */ +#include "dflat.h" + +#define BCHEIGHT 12 +#define BCWIDTH 44 +#define COLWIDTH 4 + +static DFWINDOW Bwnd; + +/* ------- project schedule array ------- */ +static struct ProjChart { + char *prj; + int start, stop; +} projs[] = { + {"Center St", 0,3}, + {"City Hall", 0,5}, + {"Rt 395 ", 1,4}, + {"Sky Condo", 2,3}, + {"Out Hs ", 0,4}, + {"Bk Palace", 1,5} +}; + +static char *Title = " PROJECT SCHEDULE"; +static char *Months = " Jan Feb Mar Apr May Jun"; + +static int BarChartProc(DFWINDOW wnd, DFMESSAGE msg, + PARAM p1, PARAM p2) +{ + switch (msg) { + case DFM_COMMAND: + if ((int)p1 == ID_HELP) { + DisplayHelp(wnd, "BarChart"); + return TRUE; + } + break; + case CLOSE_WINDOW: + Bwnd = NULL; + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +void BarChart(DFWINDOW pwnd) +{ + int pct = sizeof projs / sizeof(struct ProjChart); + int i; + + if (Bwnd == NULL) { + Bwnd = DfCreateWindow(PICTUREBOX, + "BarChart", + -1, -1, BCHEIGHT, BCWIDTH, + NULL, pwnd, BarChartProc, + SHADOW | + CONTROLBOX | + MOVEABLE | + HASBORDER + ); + DfSendMessage(Bwnd, ADDTEXT, (PARAM) Title, 0); + DfSendMessage(Bwnd, ADDTEXT, (PARAM) "", 0); + for (i = 0; i < pct; i++) { + DfSendMessage(Bwnd,ADDTEXT,(PARAM)projs[i].prj,0); + DrawBar(Bwnd, SOLIDBAR+(i%4), + 11+projs[i].start*COLWIDTH, 2+i, + (1 + projs[i].stop-projs[i].start) * COLWIDTH, + TRUE); + } + DfSendMessage(Bwnd, ADDTEXT, (PARAM) "", 0); + DfSendMessage(Bwnd, ADDTEXT, (PARAM) Months, 0); + DrawBox(Bwnd, 10, 1, pct+2, 25); + } + DfSendMessage(Bwnd, SETFOCUS, TRUE, 0); +} diff --git a/rosapps/dflat32/box.c b/rosapps/dflat32/box.c new file mode 100644 index 00000000000..f23604218a2 --- /dev/null +++ b/rosapps/dflat32/box.c @@ -0,0 +1,44 @@ +/* ----------- box.c ------------ */ + +#include "dflat.h" + +int BoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + DFWINDOW oldFocus; + CTLWINDOW *ct = GetControl(wnd); + static BOOL SettingFocus = FALSE; + if (ct != NULL) + { + switch (msg) + { + case SETFOCUS: + SettingFocus = isVisible(wnd); + rtn = BaseWndProc(BOX, wnd, msg, p1, p2); + SettingFocus = FALSE; + return rtn; + + case PAINT: + return FALSE; + case LEFT_BUTTON: + case DFM_BUTTON_RELEASED: + return DfSendMessage(GetParent(wnd), msg, p1, p2); + case BORDER: + if (SettingFocus) + return TRUE; + oldFocus = inFocus; + inFocus = NULL; + rtn = BaseWndProc(BOX, wnd, msg, p1, p2); + inFocus = oldFocus; + if (ct != NULL) + if (ct->itext != NULL) + writeline(wnd, ct->itext, 1, 0, FALSE); + return rtn; + default: + break; + } + } + return BaseWndProc(BOX, wnd, msg, p1, p2); +} + +/* EOF */ diff --git a/rosapps/dflat32/button.c b/rosapps/dflat32/button.c new file mode 100644 index 00000000000..46f0b26b4d8 --- /dev/null +++ b/rosapps/dflat32/button.c @@ -0,0 +1,92 @@ +/* -------------- button.c -------------- */ + +#include "dflat.h" + +void PaintMsg(DFWINDOW wnd, CTLWINDOW *ct, DFRECT *rc) +{ + if (isVisible(wnd)) + { + if (TestAttribute(wnd, SHADOW)) + { + /* -------- draw the button's shadow ------- */ + int x; + background = WndBackground(GetParent(wnd)); + foreground = BLACK; + for (x = 1; x <= WindowWidth(wnd); x++) + wputch(wnd, (char)223, x, 1); + wputch(wnd, (char)220, WindowWidth(wnd), 0); + } + if (ct->itext != NULL) + { + unsigned char *txt; + txt = DFcalloc(1, strlen(ct->itext)+10); + if (ct->setting == OFF) { + txt[0] = CHANGECOLOR; + txt[1] = wnd->WindowColors + [HILITE_COLOR] [FG] | 0x80; + txt[2] = wnd->WindowColors + [STD_COLOR] [BG] | 0x80; + } + CopyCommand(txt+strlen(txt),ct->itext,!ct->setting, + WndBackground(wnd)); + DfSendMessage(wnd, CLEARTEXT, 0, 0); + DfSendMessage(wnd, ADDTEXT, (PARAM) txt, 0); + free(txt); + } + /* --------- write the button's text ------- */ + WriteTextLine(wnd, rc, 0, wnd == inFocus); + } +} + +void LeftButtonMsg(DFWINDOW wnd, DFMESSAGE msg, CTLWINDOW *ct) +{ + /* --------- draw a pushed button -------- */ + int x; + background = WndBackground(GetParent(wnd)); + foreground = WndBackground(wnd); + wputch(wnd, ' ', 0, 0); + for (x = 0; x < WindowWidth(wnd); x++) + { + wputch(wnd, (char)220, x+1, 0); + wputch(wnd, (char)223, x+1, 1); + } + if (msg == LEFT_BUTTON) + DfSendMessage(NULL, WAITMOUSE, 0, 0); + else + DfSendMessage(NULL, WAITKEYBOARD, 0, 0); + DfSendMessage(wnd, PAINT, 0, 0); + if (ct->setting == ON) + DfPostMessage(GetParent(wnd), DFM_COMMAND, ct->command, 0); + else + beep(); +} + +int ButtonProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + CTLWINDOW *ct = GetControl(wnd); + if (ct != NULL) { + switch (msg) { + case SETFOCUS: + BaseWndProc(BUTTON, wnd, msg, p1, p2); + p1 = 0; + /* ------- fall through ------- */ + case PAINT: + PaintMsg(wnd, ct, (DFRECT*)p1); + return TRUE; + case KEYBOARD: + if (p1 != '\r') + break; + /* ---- fall through ---- */ + case LEFT_BUTTON: + LeftButtonMsg(wnd, msg, ct); + return TRUE; + case HORIZSCROLL: + return TRUE; + default: + break; + } + } + return BaseWndProc(BUTTON, wnd, msg, p1, p2); +} + +/* EOF */ diff --git a/rosapps/dflat32/calendar.c b/rosapps/dflat32/calendar.c new file mode 100644 index 00000000000..99a33bffbd5 --- /dev/null +++ b/rosapps/dflat32/calendar.c @@ -0,0 +1,165 @@ +/* ------------- calendar.c ------------- */ +#include "dflat.h" + +#ifndef TURBOC + +#define CALHEIGHT 17 +#define CALWIDTH 33 + +static int DyMo[] = {31,28,31,30,31,30,31,31,30,31,30,31}; +static struct tm ttm; +static int dys[42]; +static DFWINDOW Cwnd; + +static void FixDate(void) +{ + /* ---- adjust Feb for leap year ---- */ + DyMo[1] = (ttm.tm_year % 4) ? 28 : 29; + ttm.tm_mday = min(ttm.tm_mday, DyMo[ttm.tm_mon]); +} + +/* ---- build calendar dates array ---- */ +static void BuildDateArray(void) +{ + int offset, dy = 0; + memset(dys, 0, sizeof dys); + FixDate(); + /* ----- compute the weekday for the 1st ----- */ + offset = ((ttm.tm_mday-1) - ttm.tm_wday) % 7; + if (offset < 0) + offset += 7; + if (offset) + offset = (offset - 7) * -1; + /* ----- build the dates into the array ---- */ + for (dy = 1; dy <= DyMo[ttm.tm_mon]; dy++) + dys[offset++] = dy; +} + +static void CreateWindowMsg(DFWINDOW wnd) +{ + int x, y; + DrawBox(wnd, 1, 2, CALHEIGHT-4, CALWIDTH-4); + for (x = 5; x < CALWIDTH-4; x += 4) + DrawVector(wnd, x, 2, CALHEIGHT-4, FALSE); + for (y = 4; y < CALHEIGHT-3; y+=2) + DrawVector(wnd, 1, y, CALWIDTH-4, TRUE); +} + +static void DisplayDates(DFWINDOW wnd) +{ + int week, day; + char dyln[10]; + int offset; + char banner[CALWIDTH-1]; + char banner1[30]; + + SetStandardColor(wnd); + PutWindowLine(wnd, "Sun Mon Tue Wed Thu Fri Sat", 2, 1); + memset(banner, ' ', CALWIDTH-2); + strftime(banner1, 16, "%B, %Y", &ttm); + offset = (CALWIDTH-2 - strlen(banner1)) / 2; + strcpy(banner+offset, banner1); + strcat(banner, " "); + PutWindowLine(wnd, banner, 0, 0); + BuildDateArray(); + for (week = 0; week < 6; week++) { + for (day = 0; day < 7; day++) { + int dy = dys[week*7+day]; + if (dy == 0) + strcpy(dyln, " "); + else { + if (dy == ttm.tm_mday) + sprintf(dyln, "%c%c%c%2d %c", + CHANGECOLOR, + SelectForeground(wnd)+0x80, + SelectBackground(wnd)+0x80, + dy, RESETCOLOR); + else + sprintf(dyln, "%2d ", dy); + } + SetStandardColor(wnd); + PutWindowLine(wnd, dyln, 2 + day * 4, 3 + week*2); + } + } +} + +static int KeyboardMsg(DFWINDOW wnd, PARAM p1) +{ + switch ((int)p1) { + case PGUP: + if (ttm.tm_mon == 0) { + ttm.tm_mon = 12; + ttm.tm_year--; + } + ttm.tm_mon--; + FixDate(); + mktime(&ttm); + DisplayDates(wnd); + return TRUE; + case PGDN: + ttm.tm_mon++; + if (ttm.tm_mon == 12) { + ttm.tm_mon = 0; + ttm.tm_year++; + } + FixDate(); + mktime(&ttm); + DisplayDates(wnd); + return TRUE; + default: + break; + } + return FALSE; +} + +static int CalendarProc(DFWINDOW wnd,DFMESSAGE msg, + PARAM p1,PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + DefaultWndProc(wnd, msg, p1, p2); + CreateWindowMsg(wnd); + return TRUE; + case KEYBOARD: + if (KeyboardMsg(wnd, p1)) + return TRUE; + break; + case PAINT: + DefaultWndProc(wnd, msg, p1, p2); + DisplayDates(wnd); + return TRUE; + case DFM_COMMAND: + if ((int)p1 == ID_HELP) { + DisplayHelp(wnd, "Calendar"); + return TRUE; + } + break; + case CLOSE_WINDOW: + Cwnd = NULL; + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +void Calendar(DFWINDOW pwnd) +{ + if (Cwnd == NULL) { + time_t tim = time(NULL); + ttm = *localtime(&tim); + Cwnd = DfCreateWindow(PICTUREBOX, + "Calendar", + -1, -1, CALHEIGHT, CALWIDTH, + NULL, pwnd, CalendarProc, + SHADOW | + MINMAXBOX | + CONTROLBOX | + MOVEABLE | + HASBORDER + ); + } + DfSendMessage(Cwnd, SETFOCUS, TRUE, 0); +} + +#endif diff --git a/rosapps/dflat32/checkbox.c b/rosapps/dflat32/checkbox.c new file mode 100644 index 00000000000..3f41abe5c89 --- /dev/null +++ b/rosapps/dflat32/checkbox.c @@ -0,0 +1,49 @@ +/* -------------- checkbox.c ------------ */ + +#include "dflat.h" + +int CheckBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + CTLWINDOW *ct = GetControl(wnd); + if (ct != NULL) { + switch (msg) { + case SETFOCUS: + if (!(int)p1) + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + case MOVE: + rtn = BaseWndProc(CHECKBOX, wnd, msg, p1, p2); + SetFocusCursor(wnd); + return rtn; + case PAINT: { + char cb[] = "[ ]"; + if (ct->setting) + cb[1] = 'X'; + DfSendMessage(wnd, CLEARTEXT, 0, 0); + DfSendMessage(wnd, ADDTEXT, (PARAM) cb, 0); + SetFocusCursor(wnd); + break; + } + case KEYBOARD: + if ((int)p1 != ' ') + break; + case LEFT_BUTTON: + ct->setting ^= ON; + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + default: + break; + } + } + return BaseWndProc(CHECKBOX, wnd, msg, p1, p2); +} + +BOOL CheckBoxSetting(DBOX *db, enum commands cmd) +{ + CTLWINDOW *ct = FindCommand(db, cmd, CHECKBOX); + if (ct != NULL) + return (ct->isetting == ON); + return FALSE; +} + +/* EOF */ diff --git a/rosapps/dflat32/classdef.h b/rosapps/dflat32/classdef.h new file mode 100644 index 00000000000..086ee493651 --- /dev/null +++ b/rosapps/dflat32/classdef.h @@ -0,0 +1,31 @@ +/* ---------------- classdef.h --------------- */ + +#ifndef CLASSDEF_H +#define CLASSDEF_H + +typedef struct classdefs { + DFCLASS base; /* base window class */ + int (*wndproc)(struct window *,enum messages,PARAM,PARAM); + int attrib; +} CLASSDEFS; + +extern CLASSDEFS classdefs[]; + +#define SHADOW 0x0001 +#define MOVEABLE 0x0002 +#define SIZEABLE 0x0004 +#define HASMENUBAR 0x0008 +#define VSCROLLBAR 0x0010 +#define HSCROLLBAR 0x0020 +#define VISIBLE 0x0040 +#define SAVESELF 0x0080 +#define HASTITLEBAR 0x0100 +#define CONTROLBOX 0x0200 +#define MINMAXBOX 0x0400 +#define NOCLIP 0x0800 +#define READONLY 0x1000 +#define MULTILINE 0x2000 +#define HASBORDER 0x4000 +#define HASSTATUSBAR 0x8000 + +#endif diff --git a/rosapps/dflat32/classes.h b/rosapps/dflat32/classes.h new file mode 100644 index 00000000000..bfd1fdab055 --- /dev/null +++ b/rosapps/dflat32/classes.h @@ -0,0 +1,56 @@ +/* ----------- classes.h ------------ */ +/* + * Class definition source file + * Make class changes to this source file + * Other source files will adapt + * + * You must add entries to the color tables in + * CONFIG.C for new classes. + * + * Class Name Base Class Processor Attribute + * ------------ --------- --------------- ----------- + */ +ClassDef( NORMAL, -1, NormalProc, 0 ) +ClassDef( APPLICATION, NORMAL, ApplicationProc, VISIBLE | + SAVESELF | + CONTROLBOX ) +ClassDef( TEXTBOX, NORMAL, TextBoxProc, 0 ) +ClassDef( LISTBOX, TEXTBOX, ListBoxProc, 0 ) +ClassDef( EDITBOX, TEXTBOX, EditBoxProc, 0 ) +ClassDef( MENUBAR, NORMAL, MenuBarProc, NOCLIP ) +ClassDef( POPDOWNMENU, LISTBOX, PopDownProc, SAVESELF | + NOCLIP | + HASBORDER ) +#ifdef INCLUDE_PICTUREBOX +ClassDef( PICTUREBOX, TEXTBOX, PictureProc, 0 ) +#endif +ClassDef( DIALOG, NORMAL, DialogProc, SHADOW | + MOVEABLE | + CONTROLBOX| + HASBORDER | + NOCLIP ) +ClassDef( BOX, NORMAL, BoxProc, HASBORDER ) +ClassDef( BUTTON, TEXTBOX, ButtonProc, SHADOW ) +ClassDef( COMBOBOX, EDITBOX, ComboProc, 0 ) +ClassDef( TEXT, TEXTBOX, TextProc, 0 ) +ClassDef( RADIOBUTTON, TEXTBOX, RadioButtonProc, 0 ) +ClassDef( CHECKBOX, TEXTBOX, CheckBoxProc, 0 ) +ClassDef( SPINBUTTON, LISTBOX, SpinButtonProc, 0 ) +ClassDef( ERRORBOX, DIALOG, NULL, SHADOW | + HASBORDER ) +ClassDef( MESSAGEBOX, DIALOG, NULL, SHADOW | + HASBORDER ) +ClassDef( HELPBOX, DIALOG, HelpBoxProc, MOVEABLE | + SAVESELF | + HASBORDER | + NOCLIP | + CONTROLBOX ) +ClassDef( STATUSBAR, TEXTBOX, StatusBarProc, NOCLIP ) + +/* + * ========> Add new classes here <======== + */ + +/* ---------- pseudo classes to create enums, etc. ---------- */ +ClassDef( TITLEBAR, -1, NULL, 0 ) +ClassDef( DUMMY, -1, NULL, HASBORDER ) diff --git a/rosapps/dflat32/clipbord.c b/rosapps/dflat32/clipbord.c new file mode 100644 index 00000000000..bfa52f771fc --- /dev/null +++ b/rosapps/dflat32/clipbord.c @@ -0,0 +1,54 @@ +/* ----------- clipbord.c ------------ */ +#include "dflat.h" + +char *Clipboard; +unsigned ClipboardLength; + +void CopyTextToClipboard(char *text) +{ + ClipboardLength = strlen(text); + Clipboard = DFrealloc(Clipboard, ClipboardLength); + memmove(Clipboard, text, ClipboardLength); +} + +void CopyToClipboard(DFWINDOW wnd) +{ + if (TextBlockMarked(wnd)) { + char *bbl=TextLine(wnd,wnd->BlkBegLine)+wnd->BlkBegCol; + char *bel=TextLine(wnd,wnd->BlkEndLine)+wnd->BlkEndCol; + ClipboardLength = (int) (bel - bbl); + Clipboard = DFrealloc(Clipboard, ClipboardLength); + memmove(Clipboard, bbl, ClipboardLength); + } +} + +void ClearClipboard(void) +{ + if (Clipboard != NULL) { + free(Clipboard); + Clipboard = NULL; + } +} + + +BOOL PasteText(DFWINDOW wnd, char *SaveTo, unsigned len) +{ + if (SaveTo != NULL && len > 0) { + unsigned plen = strlen(wnd->text) + len; + + if (plen <= wnd->MaxTextLength) { + if (plen+1 > wnd->textlen) { + wnd->text = DFrealloc(wnd->text, plen+3); + wnd->textlen = plen+1; + } + memmove(CurrChar+len, CurrChar, strlen(CurrChar)+1); + memmove(CurrChar, SaveTo, len); + BuildTextPointers(wnd); + wnd->TextChanged = TRUE; + return TRUE; + } + } + return FALSE; +} + +/* EOF */ diff --git a/rosapps/dflat32/combobox.c b/rosapps/dflat32/combobox.c new file mode 100644 index 00000000000..5bb6da894aa --- /dev/null +++ b/rosapps/dflat32/combobox.c @@ -0,0 +1,149 @@ +/* -------------- combobox.c -------------- */ + +#include "dflat.h" + +int ListProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); + +int ComboProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + wnd->extension = DfCreateWindow( + LISTBOX, + NULL, + wnd->rc.lf,wnd->rc.tp+1, + wnd->ht-1, wnd->wd+1, + NULL, + wnd, + ListProc, + HASBORDER | NOCLIP | SAVESELF); + ((DFWINDOW)(wnd->extension))->ct->command = + wnd->ct->command; + wnd->ht = 1; + wnd->rc.bt = wnd->rc.tp; + break; + case PAINT: + foreground = WndBackground(wnd); + background = WndForeground(wnd); + wputch(wnd, DOWNSCROLLBOX, WindowWidth(wnd), 0); + break; + case KEYBOARD: + if ((int)p1 == DN) { + DfSendMessage(wnd->extension, SETFOCUS, TRUE, 0); + return TRUE; + } + break; + case LEFT_BUTTON: + if ((int)p1 == GetRight(wnd) + 1) + DfSendMessage(wnd->extension, SETFOCUS, TRUE, 0); + break; + case CLOSE_WINDOW: + DfSendMessage(wnd->extension, CLOSE_WINDOW, 0, 0); + break; + default: + break; + } + return BaseWndProc(COMBOBOX, wnd, msg, p1, p2); +} + +int ListProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + DFWINDOW pwnd = GetParent(GetParent(wnd)); + DBOX *db = pwnd->extension; + DFWINDOW cwnd; + char text[130]; + int rtn; + DFWINDOW currFocus; + + switch (msg) + { + case CREATE_WINDOW: + wnd->ct = DFmalloc(sizeof(CTLWINDOW)); + wnd->ct->setting = OFF; + wnd->WindowColors[FRAME_COLOR][FG] = + wnd->WindowColors[STD_COLOR][FG]; + wnd->WindowColors[FRAME_COLOR][BG] = + wnd->WindowColors[STD_COLOR][BG]; + rtn = DefaultWndProc(wnd, msg, p1, p2); + return rtn; + + case SETFOCUS: + if ((int)p1 == FALSE) + { + if (!wnd->isHelping) + { + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + wnd->ct->setting = OFF; + } + } + else + wnd->ct->setting = ON; + break; + + case SHOW_WINDOW: + if (wnd->ct->setting == OFF) + return TRUE; + break; + + case BORDER: + currFocus = inFocus; + inFocus = NULL; + rtn = DefaultWndProc(wnd, msg, p1, p2); + inFocus = currFocus; + return rtn; + + case LB_SELECTION: + rtn = DefaultWndProc(wnd, msg, p1, p2); + DfSendMessage(wnd, DFM_LB_GETTEXT, + (PARAM) text, wnd->selection); + PutItemText(pwnd, wnd->ct->command, text); + cwnd = ControlWindow(db, wnd->ct->command); + DfSendMessage(cwnd, PAINT, 0, 0); + cwnd->TextChanged = TRUE; + return rtn; + + case KEYBOARD: + switch ((int) p1) + { + case ESC: + case FWD: + case BS: + cwnd = ControlWindow(db, wnd->ct->command); + DfSendMessage(cwnd, SETFOCUS, TRUE, 0); + return TRUE; + + default: + break; + } + break; + + case LB_CHOOSE: + cwnd = ControlWindow(db, wnd->ct->command); + DfSendMessage(cwnd, SETFOCUS, TRUE, 0); + return TRUE; + + case CLOSE_WINDOW: + if (wnd->ct != NULL) + free(wnd->ct); + wnd->ct = NULL; + break; + + default: + break; + } + + return DefaultWndProc(wnd, msg, p1, p2); +} + +void PutComboListText(DFWINDOW wnd, enum commands cmd, char *text) +{ + CTLWINDOW *ct = FindCommand(wnd->extension, cmd, COMBOBOX); + + if (ct != NULL) + { + DFWINDOW lwnd = ((DFWINDOW)(ct->wnd))->extension; + DfSendMessage(lwnd, ADDTEXT, (PARAM) text, 0); + } +} + +/* EOF */ diff --git a/rosapps/dflat32/commands.h b/rosapps/dflat32/commands.h new file mode 100644 index 00000000000..6850ac68f29 --- /dev/null +++ b/rosapps/dflat32/commands.h @@ -0,0 +1,121 @@ +/* ---------------- commands.h ----------------- */ + +/* + * Command values sent as the first parameter + * in the COMMAND message + * + * Add application-specific commands to this enum + */ + +#ifndef COMMANDS_H +#define COMMANDS_H + +enum commands { + /* --------------- File menu ---------------- */ + ID_OPEN, + ID_NEW, + ID_SAVE, + ID_SAVEAS, + ID_DELETEFILE, + ID_PRINT, + ID_PRINTSETUP, + ID_DOS, + ID_EXIT, + /* --------------- Edit menu ---------------- */ + ID_UNDO, + ID_CUT, + ID_COPY, + ID_PASTE, + ID_PARAGRAPH, + ID_CLEAR, + ID_DELETETEXT, + /* --------------- Search Menu -------------- */ + ID_SEARCH, + ID_REPLACE, + ID_SEARCHNEXT, + /* --------------- Utilities Menu ------------- */ + ID_CALENDAR, + ID_BARCHART, + /* -------------- Options menu -------------- */ + ID_INSERT, + ID_WRAP, + ID_LOG, + ID_TABS, + ID_DISPLAY, + ID_SAVEOPTIONS, + /* --------------- Window menu -------------- */ + ID_CLOSEALL, + ID_WINDOW, + ID_MOREWINDOWS, + /* --------------- Help menu ---------------- */ + ID_HELPHELP, + ID_EXTHELP, + ID_KEYSHELP, + ID_HELPINDEX, + ID_ABOUT, + ID_LOADHELP, + /* --------------- System menu -------------- */ +#ifdef INCLUDE_RESTORE + ID_SYSRESTORE, +#endif + ID_SYSMOVE, + ID_SYSSIZE, +#ifdef INCLUDE_MINIMIZE + ID_SYSMINIMIZE, +#endif +#ifdef INCLUDE_MAXIMIZE + ID_SYSMAXIMIZE, +#endif + ID_SYSCLOSE, + /* ---- FileOpen and SaveAs dialog boxes ---- */ + ID_FILENAME, + ID_FILES, + ID_DRIVE, + ID_PATH, + /* ----- Search and Replace dialog boxes ---- */ + ID_SEARCHFOR, + ID_REPLACEWITH, + ID_MATCHCASE, + ID_REPLACEALL, + /* ----------- Windows dialog box ----------- */ + ID_WINDOWLIST, + /* --------- generic command buttons -------- */ + ID_OK, + ID_CANCEL, + ID_HELP, + /* -------------- TabStops menu ------------- */ + ID_TAB2, + ID_TAB4, + ID_TAB6, + ID_TAB8, + /* ------------ Display dialog box ---------- */ + ID_BORDER, + ID_TITLE, + ID_STATUSBAR, + ID_TEXTURE, + ID_SNOWY, + ID_COLOR, + ID_MONO, + ID_REVERSE, + ID_25LINES, + ID_43LINES, + ID_50LINES, + /* ------------- Log dialog box ------------- */ + ID_LOGLIST, + ID_LOGGING, + /* ------------ HelpBox dialog box ---------- */ + ID_HELPTEXT, + ID_BACK, + ID_PREV, + ID_NEXT, + /* ---------- Print Select dialog box --------- */ + ID_PRINTERPORT, + ID_LEFTMARGIN, + ID_RIGHTMARGIN, + ID_TOPMARGIN, + ID_BOTTOMMARGIN, + /* ----------- InputBox dialog box ------------ */ + ID_INPUTTEXT +}; + +#endif diff --git a/rosapps/dflat32/config.c b/rosapps/dflat32/config.c new file mode 100644 index 00000000000..6ac147527da --- /dev/null +++ b/rosapps/dflat32/config.c @@ -0,0 +1,514 @@ +/* ------------- config.c ------------- */ + +#include "dflat.h" + +/* ----- default colors for color video system ----- */ +unsigned char color[CLASSCOUNT] [4] [2] = { + /* ------------ NORMAL ------------ */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}},/* HILITE_COLOR */ + + /* ---------- APPLICATION --------- */ + {{LIGHTGRAY, BLUE}, /* STD_COLOR */ + {LIGHTGRAY, BLUE}, /* SELECT_COLOR */ + {LIGHTGRAY, BLUE}, /* FRAME_COLOR */ + {LIGHTGRAY, BLUE}}, /* HILITE_COLOR */ + + /* ------------ TEXTBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------ LISTBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLUE}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- EDITBOX ------------ */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLUE}, /* SELECT_COLOR */ + {LIGHTGRAY, BLUE}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- MENUBAR ------------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, CYAN}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {DARKGRAY, RED}}, /* HILITE_COLOR + Inactive, Shortcut (both FG) */ + + /* ---------- POPDOWNMENU --------- */ + {{BLACK, CYAN}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, CYAN}, /* FRAME_COLOR */ + {DARKGRAY, RED}}, /* HILITE_COLOR + Inactive ,Shortcut (both FG) */ + +#ifdef INCLUDE_PICTUREBOX + /* ------------ PICTUREBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ +#endif + + /* ------------- DIALOG ----------- */ + {{LIGHTGRAY, BLUE}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLUE}, /* FRAME_COLOR */ + {LIGHTGRAY, BLUE}}, /* HILITE_COLOR */ + + /* ------------ BOX --------------- */ + {{LIGHTGRAY, BLUE}, /* STD_COLOR */ + {LIGHTGRAY, BLUE}, /* SELECT_COLOR */ + {LIGHTGRAY, BLUE}, /* FRAME_COLOR */ + {LIGHTGRAY, BLUE}}, /* HILITE_COLOR */ + + /* ------------ BUTTON ------------ */ + {{BLACK, CYAN}, /* STD_COLOR */ + {WHITE, CYAN}, /* SELECT_COLOR */ + {BLACK, CYAN}, /* FRAME_COLOR */ + {DARKGRAY, RED}}, /* HILITE_COLOR + Inactive ,Shortcut (both FG) */ + /* ------------ COMBOBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------- TEXT ----------- */ + {{0xff, 0xff}, /* STD_COLOR */ + {0xff, 0xff}, /* SELECT_COLOR */ + {0xff, 0xff}, /* FRAME_COLOR */ + {0xff, 0xff}}, /* HILITE_COLOR */ + + /* ------------- RADIOBUTTON ----------- */ + {{LIGHTGRAY, BLUE}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLUE}, /* FRAME_COLOR */ + {LIGHTGRAY, BLUE}}, /* HILITE_COLOR */ + + /* ------------- CHECKBOX ----------- */ + {{LIGHTGRAY, BLUE}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLUE}, /* FRAME_COLOR */ + {LIGHTGRAY, BLUE}}, /* HILITE_COLOR */ + + /* ------------ SPINBUTTON ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- ERRORBOX ----------- */ + {{YELLOW, RED}, /* STD_COLOR */ + {YELLOW, RED}, /* SELECT_COLOR */ + {YELLOW, RED}, /* FRAME_COLOR */ + {YELLOW, RED}}, /* HILITE_COLOR */ + + /* ----------- MESSAGEBOX --------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- HELPBOX ------------ */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLUE}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {WHITE, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- STATUSBAR ------------- */ + {{BLACK, CYAN}, /* STD_COLOR */ + {BLACK, CYAN}, /* SELECT_COLOR */ + {BLACK, CYAN}, /* FRAME_COLOR */ + {BLACK, CYAN}}, /* HILITE_COLOR */ + + /* ---------- TITLEBAR ------------ */ + {{BLACK, CYAN}, /* STD_COLOR */ + {BLACK, CYAN}, /* SELECT_COLOR */ + {BLACK, CYAN}, /* FRAME_COLOR */ + {WHITE, CYAN}}, /* HILITE_COLOR */ + + /* ------------ DUMMY ------------- */ + {{GREEN, LIGHTGRAY}, /* STD_COLOR */ + {GREEN, LIGHTGRAY}, /* SELECT_COLOR */ + {GREEN, LIGHTGRAY}, /* FRAME_COLOR */ + {GREEN, LIGHTGRAY}} /* HILITE_COLOR */ +}; + +/* ----- default colors for mono video system ----- */ +unsigned char bw[CLASSCOUNT] [4] [2] = { + /* ------------ NORMAL ------------ */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}},/* HILITE_COLOR */ + + /* ---------- APPLICATION --------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}},/* HILITE_COLOR */ + + /* ------------ TEXTBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------ LISTBOX ----------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- EDITBOX ------------ */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- MENUBAR ------------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {DARKGRAY, WHITE}}, /* HILITE_COLOR + Inactive, Shortcut (both FG) */ + + /* ---------- POPDOWNMENU --------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {DARKGRAY, WHITE}}, /* HILITE_COLOR + Inactive ,Shortcut (both FG) */ + +#ifdef INCLUDE_PICTUREBOX + /* ------------ PICTUREBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ +#endif + + /* ------------- DIALOG ----------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}}, /* HILITE_COLOR */ + + /* ------------ BOX --------------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}}, /* HILITE_COLOR */ + + /* ------------ BUTTON ------------ */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {WHITE, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {DARKGRAY, WHITE}}, /* HILITE_COLOR + Inactive ,Shortcut (both FG) */ + /* ------------ COMBOBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------- TEXT ----------- */ + {{0xff, 0xff}, /* STD_COLOR */ + {0xff, 0xff}, /* SELECT_COLOR */ + {0xff, 0xff}, /* FRAME_COLOR */ + {0xff, 0xff}}, /* HILITE_COLOR */ + + /* ------------- RADIOBUTTON ----------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}}, /* HILITE_COLOR */ + + /* ------------- CHECKBOX ----------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}}, /* HILITE_COLOR */ + + /* ------------ SPINBUTTON ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- ERRORBOX ----------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}},/* HILITE_COLOR */ + + /* ----------- MESSAGEBOX --------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}},/* HILITE_COLOR */ + + /* ----------- HELPBOX ------------ */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {WHITE, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {WHITE, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- STATUSBAR ------------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- TITLEBAR ------------ */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------ DUMMY ------------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}} /* HILITE_COLOR */ +}; +/* ----- default colors for reverse mono video ----- */ +unsigned char reverse[CLASSCOUNT] [4] [2] = { + /* ------------ NORMAL ------------ */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- APPLICATION --------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------ TEXTBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------ LISTBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- EDITBOX ------------ */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- MENUBAR ------------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {DARKGRAY, WHITE}}, /* HILITE_COLOR + Inactive, Shortcut (both FG) */ + + /* ---------- POPDOWNMENU --------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {DARKGRAY, WHITE}}, /* HILITE_COLOR + Inactive ,Shortcut (both FG) */ + +#ifdef INCLUDE_PICTUREBOX + /* ------------ PICTUREBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ +#endif + + /* ------------- DIALOG ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}}, /* HILITE_COLOR */ + + /* ------------ BOX --------------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}}, /* HILITE_COLOR */ + + /* ------------ BUTTON ------------ */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {WHITE, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {DARKGRAY, WHITE}}, /* HILITE_COLOR + Inactive ,Shortcut (both FG) */ + /* ------------ COMBOBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ------------- TEXT ----------- */ + {{0xff, 0xff}, /* STD_COLOR */ + {0xff, 0xff}, /* SELECT_COLOR */ + {0xff, 0xff}, /* FRAME_COLOR */ + {0xff, 0xff}}, /* HILITE_COLOR */ + + /* ------------- RADIOBUTTON ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}}, /* HILITE_COLOR */ + + /* ------------- CHECKBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}}, /* HILITE_COLOR */ + + /* ------------ SPINBUTTON ----------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- ERRORBOX ----------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}}, /* HILITE_COLOR */ + + /* ----------- MESSAGEBOX --------- */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {BLACK, LIGHTGRAY}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {BLACK, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ----------- HELPBOX ------------ */ + {{BLACK, LIGHTGRAY}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {BLACK, LIGHTGRAY}, /* FRAME_COLOR */ + {WHITE, LIGHTGRAY}},/* HILITE_COLOR */ + + /* ---------- STATUSBAR ------------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}}, /* HILITE_COLOR */ + + /* ---------- TITLEBAR ------------ */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}}, /* HILITE_COLOR */ + + /* ------------ DUMMY ------------- */ + {{LIGHTGRAY, BLACK}, /* STD_COLOR */ + {LIGHTGRAY, BLACK}, /* SELECT_COLOR */ + {LIGHTGRAY, BLACK}, /* FRAME_COLOR */ + {LIGHTGRAY, BLACK}} /* HILITE_COLOR */ +}; + +/* ------ default configuration values ------- */ +CONFIG cfg = { + VERSION, + TRUE, /* Editor Insert Mode */ + 4, /* Editor tab stops */ + TRUE, /* Editor word wrap */ +#ifdef INCLUDE_WINDOWOPTIONS + TRUE, /* Application Border */ + TRUE, /* Application Title */ + TRUE, /* Status Bar */ + TRUE, /* Textured application window */ +#endif +// 25, /* Number of screen lines */ + "Lpt1", /* Printer Port */ + 66, /* Lines per printer page */ + 80, /* characters per printer line */ + 6, /* Left printer margin */ + 70, /* Right printer margin */ + 3, /* Top printer margin */ + 55 /* Bottom printer margin */ +}; + +void BuildFileName(char *path, char *ext) +{ + extern char **Argv; + char *cp; + + strcpy(path, Argv[0]); + cp = strrchr(path, '\\'); + if (cp == NULL) + cp = path; + else + cp++; + strcpy(cp, DFlatApplication); + strcat(cp, ext); +} + +FILE *OpenConfig(char *mode) +{ + char path[64]; + BuildFileName(path, ".cfg"); + return fopen(path, mode); +} + +/* ------ load a configuration file from disk ------- */ +BOOL LoadConfig(void) +{ + static BOOL ConfigLoaded = FALSE; + if (ConfigLoaded == FALSE) { + FILE *fp = OpenConfig("rb"); + if (fp != NULL) { + fread(cfg.version, sizeof cfg.version+1, 1, fp); + if (strcmp(cfg.version, VERSION) == 0) { + fseek(fp, 0L, SEEK_SET); + fread(&cfg, sizeof(CONFIG), 1, fp); + fclose(fp); + } + else { + char path[64]; + BuildFileName(path, ".cfg"); + fclose(fp); + unlink(path); + strcpy(cfg.version, VERSION); + } + ConfigLoaded = TRUE; + } + } + return ConfigLoaded; +} + +/* ------ save a configuration file to disk ------- */ +void SaveConfig(void) +{ + FILE *fp = OpenConfig("wb"); + if (fp != NULL) { + fwrite(&cfg, sizeof(CONFIG), 1, fp); + fclose(fp); + } +} + +/* --------- set window colors --------- */ +void SetStandardColor(DFWINDOW wnd) +{ + foreground = WndForeground(wnd); + background = WndBackground(wnd); +} + +void SetReverseColor(DFWINDOW wnd) +{ + foreground = SelectForeground(wnd); + background = SelectBackground(wnd); +} + +/* EOF */ \ No newline at end of file diff --git a/rosapps/dflat32/config.h b/rosapps/dflat32/config.h new file mode 100644 index 00000000000..065e197e598 --- /dev/null +++ b/rosapps/dflat32/config.h @@ -0,0 +1,48 @@ +/* ---------------- config.h -------------- */ + +#ifndef CONFIG_H +#define CONFIG_H + +enum colortypes { + STD_COLOR, + SELECT_COLOR, + FRAME_COLOR, + HILITE_COLOR +}; + +enum grounds { FG, BG }; + +/* ----------- configuration parameters ----------- */ +typedef struct config { + char version[sizeof VERSION]; + BOOL InsertMode; /* Editor insert mode */ + int Tabs; /* Editor tab stops */ + BOOL WordWrap; /* True to word wrap editor */ +#ifdef INCLUDE_WINDOWOPTIONS + BOOL Border; /* True for application window border */ + BOOL Title; /* True for application window title */ + BOOL StatusBar; /* True for appl'n window status bar */ + BOOL Texture; /* True for textured appl window */ +#endif +// int ScreenLines; /* Number of screen lines (25/43/50) */ + char PrinterPort[5]; + int LinesPage; /* Lines per printer page */ + int CharsLine; /* Characters per printer line */ + int LeftMargin; /* Printer margins */ + int RightMargin; + int TopMargin; + int BottomMargin; + unsigned char clr[CLASSCOUNT] [4] [2]; /* Colors */ +} CONFIG; + +extern CONFIG cfg; +extern unsigned char color[CLASSCOUNT] [4] [2]; +extern unsigned char bw[CLASSCOUNT] [4] [2]; +extern unsigned char reverse[CLASSCOUNT] [4] [2]; + +BOOL LoadConfig(void); +void SaveConfig(void); +FILE *OpenConfig(char *); + +#endif + diff --git a/rosapps/dflat32/console.c b/rosapps/dflat32/console.c new file mode 100644 index 00000000000..a604300fea7 --- /dev/null +++ b/rosapps/dflat32/console.c @@ -0,0 +1,198 @@ +/* ----------- console.c ---------- */ + +#define WIN32_LEAN_AND_MEAN +#include + + +#include "dflat.h" + + +/* ----- table of alt keys for finding shortcut keys ----- */ +#if 0 +static int altconvert[] = { + ALT_A,ALT_B,ALT_C,ALT_D,ALT_E,ALT_F,ALT_G,ALT_H, + ALT_I,ALT_J,ALT_K,ALT_L,ALT_M,ALT_N,ALT_O,ALT_P, + ALT_Q,ALT_R,ALT_S,ALT_T,ALT_U,ALT_V,ALT_W,ALT_X, + ALT_Y,ALT_Z,ALT_0,ALT_1,ALT_2,ALT_3,ALT_4,ALT_5, + ALT_6,ALT_7,ALT_8,ALT_9 +}; +#endif + +static int cursorpos[MAXSAVES]; +static int cursorshape[MAXSAVES]; +static int cs; + + +void SwapCursorStack(void) +{ + if (cs > 1) { + swap(cursorpos[cs-2], cursorpos[cs-1]); + swap(cursorshape[cs-2], cursorshape[cs-1]); + } +} + + +/* ---- Read a keystroke ---- */ +void GetKey (PINPUT_RECORD lpBuffer) +{ + HANDLE hInput; + DWORD dwRead; + + hInput = GetStdHandle (STD_INPUT_HANDLE); + + do + { +// WaitForSingleObject (hInput, INFINITE); + ReadConsoleInput (hInput, lpBuffer, 1, &dwRead); + if ((lpBuffer->EventType == KEY_EVENT) && + (lpBuffer->Event.KeyEvent.bKeyDown == TRUE)) + break; + } + while (TRUE); +} + + +/* ---------- read the keyboard shift status --------- */ +int getshift(void) +{ +// regs.h.ah = 2; +// int86(KEYBRD, ®s, ®s); +// return regs.h.al; +/* FIXME */ + + return 0; +} + + +/* -------- sound a buzz tone ---------- */ +void beep(void) +{ + Beep(440, 50); +// MessageBeep (-1); +} + + +/* ------ position the cursor ------ */ +void cursor(int x, int y) +{ + COORD coPos; + + coPos.X = (USHORT)x; + coPos.Y = (USHORT)y; + SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), coPos); +} + +/* ------ get cursor shape and position ------ */ +static void getcursor(void) +{ +/* + videomode(); + regs.h.ah = READCURSOR; + regs.x.bx = video_page; + int86(VIDEO, ®s, ®s); +*/ + /* FIXME */ +} + +/* ------- get the current cursor position ------- */ + +void curr_cursor(int *x, int *y) +//VOID GetCursorXY (PSHORT x, PSHORT y) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi); + + *x = (int)csbi.dwCursorPosition.X; + *y = (int)csbi.dwCursorPosition.Y; +} + + +/* ------ save the current cursor configuration ------ */ +void savecursor(void) +{ +/* + if (cs < MAXSAVES) { + getcursor(); + cursorshape[cs] = regs.x.cx; + cursorpos[cs] = regs.x.dx; + cs++; + } +*/ +} + +/* ---- restore the saved cursor configuration ---- */ +void restorecursor(void) +{ +/* + if (cs) { + --cs; + videomode(); + regs.x.dx = cursorpos[cs]; + regs.h.ah = SETCURSOR; + regs.x.bx = video_page; + int86(VIDEO, ®s, ®s); + set_cursor_type(cursorshape[cs]); + } +*/ +} + +/* ------ make a normal cursor ------ */ +void normalcursor(void) +{ +// set_cursor_type(0x0607); +} + +/* ------ hide the cursor ------ */ +void hidecursor(void) +{ +/* + getcursor(); + regs.h.ch |= HIDECURSOR; + regs.h.ah = SETCURSORTYPE; + int86(VIDEO, ®s, ®s); +*/ +} + +/* ------ unhide the cursor ------ */ +void unhidecursor(void) +{ +/* + getcursor(); + regs.h.ch &= ~HIDECURSOR; + regs.h.ah = SETCURSORTYPE; + int86(VIDEO, ®s, ®s); +*/ +} + +/* ---- use BIOS to set the cursor type ---- */ +void set_cursor_type(unsigned t) +{ +/* + videomode(); + regs.h.ah = SETCURSORTYPE; + regs.x.bx = video_page; + regs.x.cx = t; + int86(VIDEO, ®s, ®s); +*/ +} + + +/* ------ convert an Alt+ key to its letter equivalent ----- */ +int AltConvert(int c) +{ + return c; +#if 0 + int i, a = 0; + for (i = 0; i < 36; i++) + if (c == altconvert[i]) + break; + if (i < 26) + a = 'a' + i; + else if (i < 36) + a = '0' + i - 26; + return a; +#endif +} + +/* EOF */ diff --git a/rosapps/dflat32/decomp.c b/rosapps/dflat32/decomp.c new file mode 100644 index 00000000000..9660107ea63 --- /dev/null +++ b/rosapps/dflat32/decomp.c @@ -0,0 +1,134 @@ +/* ------------------- decomp.c -------------------- */ + +/* + * Decompress the application.HLP file + * or load the application.TXT file if the .HLP file + * does not exist + */ + +#include "dflat.h" +#include "htree.h" + +static int in8; +static int ct8 = 8; +static FILE *fi; +static BYTECOUNTER bytectr; +static int LoadingASCII; +struct htr *HelpTree; +static int root; + +/* ------- open the help database file -------- */ +FILE *OpenHelpFile(void) +{ + char *cp; + int treect, i; + char helpname[65]; + + /* -------- get the name of the help file ---------- */ + BuildFileName(helpname, ".hlp"); + LoadingASCII = FALSE; + if ((fi = fopen(helpname, "rb")) == NULL) { + /* ---- no .hlp file, look for .txt file ---- */ + if ((cp = strrchr(helpname, '.')) != NULL) { + strcpy(cp, ".TXT"); + fi = fopen(helpname, "rt"); + } + if (fi == NULL) + return NULL; + LoadingASCII = TRUE; + } + + if (!LoadingASCII && HelpTree == NULL) { + /* ----- read the byte count ------ */ + fread(&bytectr, sizeof bytectr, 1, fi); + /* ----- read the frequency count ------ */ + fread(&treect, sizeof treect, 1, fi); + /* ----- read the root offset ------ */ + fread(&root, sizeof root, 1, fi); + HelpTree = DFcalloc(treect-256, sizeof(struct htr)); + /* ---- read in the tree --- */ + for (i = 0; i < treect-256; i++) { + fread(&HelpTree[i].left, sizeof(int), 1, fi); + fread(&HelpTree[i].right, sizeof(int), 1, fi); + } + } + return fi; +} + +/* ----- read a line of text from the help database ----- */ +void *GetHelpLine(char *line) +{ + int h; + if (LoadingASCII) { + void *hp; + do + hp = fgets(line, 160, fi); + while (*line == ';'); + return hp; + } + *line = '\0'; + while (TRUE) { + /* ----- decompress a line from the file ------ */ + h = root; + /* ----- walk the Huffman tree ----- */ + while (h > 255) { + /* --- h is a node pointer --- */ + if (ct8 == 8) { + /* --- read 8 bits of compressed data --- */ + if ((in8 = fgetc(fi)) == EOF) { + *line = '\0'; + return NULL; + } + ct8 = 0; + } + /* -- point to left or right node based on msb -- */ + if (in8 & 0x80) + h = HelpTree[h-256].left; + else + h = HelpTree[h-256].right; + /* --- shift the next bit in --- */ + in8 <<= 1; + ct8++; + } + /* --- h < 255 = decompressed character --- */ + if (h == '\r') + continue; /* skip the '\r' character */ + /* --- put the character in the buffer --- */ + *line++ = h; + /* --- if '\n', end of line --- */ + if (h == '\n') + break; + } + *line = '\0'; /* null-terminate the line */ + return line; +} + +/* --- compute the database file byte and bit position --- */ +void HelpFilePosition(long *offset, int *bit) +{ + *offset = ftell(fi); + if (LoadingASCII) + *bit = 0; + else { + if (ct8 < 8) + --*offset; + *bit = ct8; + } +} + +/* -- position the database to the specified byte and bit -- */ +void SeekHelpLine(long offset, int bit) +{ + int i; + fseek(fi, offset, 0); + if (!LoadingASCII) { + ct8 = bit; + if (ct8 < 8) { + in8 = fgetc(fi); + for (i = 0; i < bit; i++) + in8 <<= 1; + } + } +} + + diff --git a/rosapps/dflat32/dfalloc.c b/rosapps/dflat32/dfalloc.c new file mode 100644 index 00000000000..f34b2a62982 --- /dev/null +++ b/rosapps/dflat32/dfalloc.c @@ -0,0 +1,70 @@ +/* ---------- dfalloc.c ---------- */ + +#define WIN32_LEAN_AND_MEAN +#include + +#include "dflat.h" + +static void AllocationError(void) +{ + static BOOL OnceIn = FALSE; + extern jmp_buf AllocError; + extern BOOL AllocTesting; + static char *ErrMsg[] = { + "ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿", + "³ Out of Memory! ³", + "RÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU" + }; + int x, y; + CHAR_INFO savbuf[54]; + DFRECT rc = {30,11,47,13}; + INPUT_RECORD ir; + + if (!OnceIn) + { + OnceIn = TRUE; + /* ------ close all windows ------ */ + DfSendMessage(ApplicationWindow, CLOSE_WINDOW, 0, 0); + GetVideo(rc, savbuf); + for (x = 0; x < 18; x++) + { + for (y = 0; y < 3; y++) + { + int c = (255 & (*(*(ErrMsg+y)+x))) | 0x7000; + PutVideoChar(x+rc.lf, y+rc.tp, c); + } + } + GetKey(&ir); + StoreVideo(rc, savbuf); + if (AllocTesting) + longjmp(AllocError, 1); + } +} + +void *DFcalloc(size_t nitems, size_t size) +{ + void *rtn = calloc(nitems, size); + if (size && rtn == NULL) + AllocationError(); + return rtn; +} + +void *DFmalloc(size_t size) +{ + void *rtn = malloc(size); + if (size && rtn == NULL) + AllocationError(); + return rtn; +} + +void *DFrealloc(void *block, size_t size) +{ + void *rtn; + + rtn = realloc(block, size); + if (size && rtn == NULL) + AllocationError(); + return rtn; +} + +/* EOF */ diff --git a/rosapps/dflat32/dflat.doc b/rosapps/dflat32/dflat.doc new file mode 100644 index 00000000000..9a965300325 --- /dev/null +++ b/rosapps/dflat32/dflat.doc @@ -0,0 +1,1350 @@ +Window Classes: + +Window classes define the behavior of windows. Each class has its own +unique reaction to messages. Classes derive from other classes. + + NORMAL base window for all window classes + APPLICATION application window. has the menu + (derived from NORMAL) + TEXTBOX textbox. base window for listbox, editbox, etc. + (derived from NORMAL) + LISTBOX listbox. base window for menubar + (derived from TEXTBOX) + PICTUREBOX picturebox. a text box onto which you can draw lines + (derived from TEXTBOX) + EDITBOX editbox + (derived from TEXTBOX) + MENUBAR the application's menu bar + (derived from NORMAL) + POPDOWNMENU popdown menu + (derived from LISTBOX) + BUTTON command button in a dialog box + (derived from TEXTBOX) + SPINBUTTON spin button in a dialog box + (derived from LISTBOX) + COMBOBOX combination editbox/listbox + (derived from EDITBOX) + DIALOG dialog box. parent to editbox, button, listbox, etc. + (derived from NORMAL) + ERRORBOX for displaying an error message + (derived from DIALOG) + MESSAGEBOX for displaying a message + (derived from DIALOG) + HELPBOX help window + (derived from DIALOG) + TEXT static text on a dialog box + (derived from TEXTBOX) + RADIOBUTTON radio button on a dialog box + (derived from TEXTBOX) + CHECKBOX check box on a dialog box + (derived from TEXTBOX) + STATUSBAR status bar at the bottom of application window + (derived from TEXTBOX) + + D-Flat Window Class Tree + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ ³ + ³ NORMAL ³ + ³ ³ ³ + ³ ÃÄÄ APPLICATION ³ + ³ ³ ³ + ³ ÃÄÄ MENUBAR ³ + ³ ³ ³ + ³ ÃÄÄ TEXTBOX ³ + ³ ³ ³ ³ + ³ ³ ÃÄÄ LISTBOX ³ + ³ ³ ³ ³ ³ + ³ ³ ³ ÃÄÄÄÄ POPDOWNMENU ³ + ³ ³ ³ ³ ³ + ³ ³ ³ ÀÄÄÄÄ SPINBUTTON ³ + ³ ³ ³ ³ + ³ ³ ÃÄÄ EDITBOX ³ + ³ ³ ³ ³ ³ + ³ ³ ³ ÀÄÄÄÄ COMBOBOX ³ + ³ ³ ³ ³ + ³ ³ ÃÄÄ PICTUREBOX ³ + ³ ³ ³ ³ + ³ ³ ÃÄÄ STATUSBAR ³ + ³ ³ ³ ³ + ³ ³ ÃÄÄ TEXT ³ + ³ ³ ³ ³ + ³ ³ ÃÄÄ BUTTON ³ + ³ ³ ³ ³ + ³ ³ ÃÄÄ RADIOBUTTON ³ + ³ ³ ³ ³ + ³ ³ ÀÄÄ CHECKBOX ³ + ³ ³ ³ + ³ ÀÄÄ DIALOG ³ + ³ ³ ³ + ³ ÃÄÄ ERRORBOX ³ + ³ ³ ³ + ³ ÃÄÄ MESSAGEBOX ³ + ³ ³ ³ + ³ ÀÄÄ HELPBOX ³ + ³ ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + +Window Attributes: + +Every window has an attribute word that defines some of its +appearance and behavior. The following values are bitwise flags that +OR together to make a window's attributes. + +You can establish default attributes for a window's class, add +additional attributes when you create the window, and use the +AddAttribute, ClearAttribute, and TestAttribute macros to change and +test a window's attributes. + + SHADOW has a shadow + MOVEABLE can move the window with mouse or cursor + SIZEABLE can resize the window with mouse or cursor + HASMENUBAR has a menubar (an application window) + VSCROLLBAR has a vertical scroll bar + HSCROLLBAR has a horizontal scroll bar + VISIBLE is visible + SAVESELF saves its own video memory + TITLEBAR has a title bar + CONTROLBOX has a control box and control menu + MINMAXBOX has a min/max box + NOCLIP is not clipped to its parent's borders + READONLY is a readonly textbox + MULTILINE is a multiline editbox or listbox + HASBORDER has a border + HASSTATUSBAR has a statusbar (application window only) + +Messages: + +A D-Flat program is message-driven. You initiate message processing +with the init_messages function, create a window with the +CreateWindow function, and go into the message dispatching loop with +the dispatch_message function. + +A window can have a window-processing function. When the user causes +events to occur by pressing keys and using the mouse, D-Flat sends +messages to the window's function. That function can send messages to +itself and other windows with the SendMessage and PostMessage +functions. + +Windows are declared as members of a class. Every class has a default +window-processing function. If you do not provide one for an instance +of a window class, the default one receives messages for the window. +Your custom window-processing function--if one exists--should chain to +the default window-processing function for the blass by calling the +DefaultWndProc function. + +There are five things a window-processing function can do with a +message: + - ignore it and let the D-Flat default processing occur. + - suppress it by returning without chaining to the default + window-processing function for the window class. + - chain to the default window-processing function and then do some + additional processing. + - do some preliminary processing and then chain to the default + window-processing function. + - do all the processing of the message and then return without + chaining to the default window-processing function for the + window class. + +Following are the messages that an application program would use. +There are other messages, but they are used by D-Flat only. + +Process Communication Messages + +START start message processing (not used now) + Sent: + P1: + P2: + Returns: + +STOP stop message processing + Sent: by application window to NULL to stop message + dispatch loop + P1: + P2: + Returns: + +COMMAND send a command to a window + Sent: to send command + P1: command code (commands.h) + P2: additional data (command-dependent) + If the command code is a menu selection, P2 is the + position of the selection on the menu (1,2,...) + If the command code is a dialog box control, P2 is + ENTERFOCUS when the command gets the focus, LEAVEFOCUS + when the command loses the focus, and 0 when the user + executes the control's command, e.g. presses a button. + Returns: Nothing if sent by PostCommand + Command-dependent value if sent by SendCommand + + +Window Management Messages + +CREATE_WINDOW create a window + Sent: by DFLAT to new window after window is created + P1: + P2: + Returns: + +OPEN_WINDOW open a window + Sent: (posted) by DFLAT to new window after window is created + P1: + P2: + Returns: + +SHOW_WINDOW show a window + Sent: by the app to the window to display the window + P1: + P2: + Returns: + +HIDE_WINDOW hide a window + Sent: by the app to the window to hide the window + P1: + P2: + Returns: + +CLOSE_WINDOW delete a window + Sent: by the app to destroy a window + P1: + P2: + Returns: + +SETFOCUS set and clear the focus + Sent: by D-Flat or the app to set or release the focus + P1: true = set, false = release + P2: + Returns: + +PAINT paint the window's data space + Sent: to paint the client area of a window + P1: address of RECT relative to window (0/0 = upper left) + to paint or 0 to paint entire client area + P2: True to make non-focus window paint without clipping + Returns: + +BORDER paint the window's border + Sent: to paint a window's border + P1: address of RECT relative to window (0/0 = upper left) + to paint or 0 to paint entire border + P2: + Returns: FALSE to suppress D-Flat title display + (e.g. the window displays its own border) + +TITLE display the window's title + Sent: by D-Flat when it is about to display a window's title + P1: address of RECT relative to window (0/0 = upper left) + to paint or 0 to paint entire title + P2: + Returns: FALSE to suppress D-Flat title display + (e.g. the window displays its own title) + +MOVE move the window + Sent: to move a window + P1: new left coordinate + P2: new upper coordinate + Returns: + +SIZE change the window's size + Sent: to resize a window + P1: new right coordinate + P2: new lower coordinate + Returns: + +MAXIMIZE maximize the window + Sent: to maximize a window within its parent's client area + P1: + P2: + Returns: + +MINIMIZE minimize the window + Sent: to minimize a window to an icon + P1: + P2: + Returns: + +RESTORE restore the window + Sent: to restore a window to its position and size prior to the + maximize or minimize operation + P1: + P2: + Returns: + +INSIDE_WINDOW test x/y inside a window + Sent: to test to see if coordinates are inside a window + P1: x + P2: y + Returns: true or false + + +Clock Messages + +CLOCKTICK the clock ticked + Sent: every second to a window that has captured the clock + P1: segment of time display string + P2: offset of time display string + Returns: + +CAPTURE_CLOCK capture clock into a window + Sent: to capture the clock. To chain clock ticks, send this + message to wnd->PrevClock when you receive the message. + P1: + P2: + Returns: + +RELEASE_CLOCK release clock to the system + Sent: to release the captured clock + P1: + P2: + Returns: + + +Keyboard and Screen Messages + +KEYBOARD key was pressed + Sent: when key is pressed. sent to the window that has the focus + P1: keystroke + P2: shift key mask + Returns: + +CAPTURE_KEYBOARD capture keyboard into a window + Sent: by window to itself to capture the keyboard + regardless of focus + P1: + P2: + Returns: + +RELEASE_KEYBOARD release keyboard to system + Sent: by window to itelf to release the captured keyboard + P1: + P2: + Returns: + +KEYBOARD_CURSOR position the keyboard cursor + Sent: to position the keyboard cursor + P1: x (if sent by window, 0 = left client area) + P2: y (if sent by window, 0 = top client area) + if sent with NULL, x/y are relative to the screen + Returns: + +CURRENT_KEYBOARD_CURSOR read the cursor position + Sent: to retrieve the cursor position + P1: x (relative to the screen) + P2: y (relative to the screen) + Returns: + +HIDE_CURSOR hide the keyboard cursor + Sent: to hide the keyboard cursor + P1: + P2: + Returns: + +SHOW_CURSOR display the keyboard cursor + Sent: to display the keyboard cursor + P1: + P2: + Returns: + +SAVE_CURSOR save the cursor's configuration + Sent: to save the keyboard cursor's current configuration + P1: + P2: + Returns: + +RESTORE_CURSOR restore the saved cursor + Sent: to restore a keyboard cursor's saved configuration + P1: + P2: + Returns: + +SHIFT_CHANGED the shift status changed + Sent: to in-focus window when the user presses or + releases shift, alt, or ctrl key + P1: BIOS shift key mask + P2: + Returns: + +WAITKEYBOARD wait for key release + Sent: to wait for a keypress release + P1: + P2: + Returns: + + +Mouse Messages + +RESET_MOUSE reset the mouse + Sent: to reset the mouse to the current screen configuration + P1: + P2: + Returns: + +MOUSE_TRAVEL set the mouse's travel + Sent: to limit the mouse travel to a screen rectangle + P1: address of a RECT + P2: + Returns: + +MOUSE_INSTALLED test for mouse installed + Sent: to see if the mouse is installed + P1: + P2: + Returns: true or false + +RIGHT_BUTTON right button pressed + Sent: to window when the user presses the right button + (sent only when mouse cursor is within the window + or the window has captured the mouse) + P1: x + P2: y + Returns: + +LEFT_BUTTON left button pressed + Sent: to window when the user presses the left button + (sent only when mouse cursor is within the window + or the window has captured the mouse) + P1: x + P2: y + Returns: + +DOUBLE_CLICK left button doubleclicked + Sent: to window when the user double-clicks the left button + (sent only when mouse cursor is within the window + or the window has captured the mouse) + (a LEFT_BUTTON message will have preceded this one) + P1: x + P2: y + Returns: + +MOUSE_MOVED mouse changed position + Sent: to window when the mouse has moved + (sent only when mouse cursor is within the window + or the window has captured the mouse) + P1: x + P2: y + Returns: + +BUTTON_RELEASED mouse button released + Sent: to window when user releases mouse button + (sent only when mouse cursor is within the window + or the window has captured the mouse) + P1: x + P2: y + Returns: + +CURRENT_MOUSE_CURSOR get mouse position + Sent: to determine the current mouse position + P1: address of x + P2: address of y + Returns: mouse coordinates in x and y. If no mouse is installed, + returns -1 in x and y. + +MOUSE_CURSOR set mouse position + Sent: to set the current mouse position + P1: x + P2: y + Returns: + +SHOW_MOUSE make mouse cursor visible + Sent: to display the mouse cursor + P1: + P2: + Returns: + +HIDE_MOUSE hide mouse cursor + Sent: to hide the mouse cursor + P1: + P2: + Returns: + +WAITMOUSE wait until button released + Sent: to wait until the user releases the mouse button + P1: + P2: + Returns: + +TESTMOUSE test any mouse button pressed + Sent: to see if either mouse button is pressed + P1: + P2: + Returns: true or false + +CAPTURE_MOUSE capture mouse into a window + Sent: by/to a window to capture all mouse activity + regardless of whether it occurs inside this window + P1: + P2: + Returns: + +RELEASE_MOUSE release the mouse to system + Sent: release a captured mouse + P1: + P2: + Returns: + + +Text Box Messages + +ADDTEXT add text to the text box + Sent: to append a line of text to the text box + P1: address of null-terminated string without \n + (textbox makes its own copy. string can go out of scope.) + P2: + Returns: + +DELETETEXT delete line of text from the text box + Sent: to delete a line of text from the text box + P1: line number relative to zero + P2: + Returns: + +INSERTTEXT insert line of text into the text box + Sent: to insert a line of text into the text box + P1: address of null-terminated string without \n + P2: line number relative to zero that will follow new line. + Returns: + +CLEARTEXT clear the text box + Sent: clear all text from the text box + P1: + P2: + Returns: + +SETTEXT set text buffer contents + Sent: To set text buffer to caller's text. + P1: address of text buffer + (lines are terminated by \n without \0) + (textbox makes its own copy. string can go out of scope.) + P2: length of text buffer + Returns: + +SCROLL vertical scroll of text box + Sent: to scroll a text window vertically one line + P1: true = scroll up, false = scroll down + P2: + Returns: + +HORIZSCROLL horizontal scroll of text box + Sent: to scroll a text window horizontally one column + P1: true = scroll left, false = scroll right + P2: + Returns: + +SCROLLPAGE vertical scroll of text box 1 page + Sent: to scroll a text window vertically one page + P1: true = scroll up, false = scroll down + P2: + Returns: + +HORIZSCROLLPAGE horizontal scroll of text box 1 page + Sent: to scroll a text window horizontally one page + P1: true = scroll left, false = scroll right + P2: + Returns: + +SCROLLDOC document scroll of text box + Sent: to scroll a text window to beginning/end of document + P1: true = scroll to beginning, false = scroll to end + P2: + Returns: + +Edit Box Messages + +GETTEXT get text from an edit box + Sent: Get the line of text from a single-line editbox + P1: address of receiving buffer + P2: max length to copy + Returns: + +SETTEXTLENGTH set maximum text length in an edit box + Sent: to set the maximum number of characters that an editbox + may hold in its buffer. + P1: maximum character count + P2: + Returns: + + +Application Window Messages + +ADDSTATUS write text to the status bar + Sent: to write to or clear status bar text area + P1: address of text (null-terminated string) or NULL to clear + P2: + Returns: + +List Box Messages + +LB_SELECTION list box selection + Sent: sent by list box to self and to parent (if parent is not + a simple LISTBOX window) when user moves to an entry on + the list box. + P1: selection number: 0, 1, ... + P2: if multi-line selection listbox, shift status mask + if not, true = selection was same as choice (e.g. mouse) + Returns: + +LB_CHOOSE list box choice + Sent: sent to parent of list box when user chooses an item + from the list box + P1: selection number: 0, 1, ... + P2: + Returns: + +LB_CURRENTSELECTION return the current selection + Sent: To get the current selection number (where the listbox + cursor is positioned) + P1: + P2: + Returns: selection number: 0, 1, ..., or -1 if listbox is empty or + no line is selected. + +LB_GETTEXT return the text of selection + Sent: To get a copy of the text at a specified line + P1: Address of string to receive copy of text + P2: Line number: 0, 1, ... + Returns: + +LB_SETSELECTION sets the listbox selection + Sent: To change where the listbox cursor points + P1: Line number: 0, 1, ... + P2: + Returns: + +Picture Box Messages + +DRAWVECTOR Draws a vector + Sent: To draw a vector in the window's client area + P1: address of RECT that describes the vector relative to the + window's client area + (either lf = rt [vertical vector] or tp = bt [horizontal + vector]) + P2: + Returns: + +DRAWBOX Draws a box + Sent: To draw a box in the window's client area + P1: address of RECT that describes the box relative to the + window's client area + P2: + Returns: + +DRAWBAR Draws a barchart bar + Sent: To draw a bar in the window's client area + P1: address of RECT that describes the bar relative to the + window's client area + (either lf = rt [vertical vector] or tp = bt [horizontal + vector]) + P2: one of these: SOLIDBAR, HEAVYBAR, CROSSBAR, LIGHTBAR + (4 different bar textures) + Returns: + +===================================================== + +API Functions & Macros: + +These are functions and macros defined for use by applications +programs. There are many others defined in the header files. These +others are for D-Flat to use, and programmers need not be concerned +about them except as an expression of their curiosity about how +D-Flat works. + + +(Note: These specifications are not in any orderly sequence yet.) + + +------------------------------------------------------------------- +void init_messages(void) + +Call this function first to initialize message processing. Continue +only if the function returns a true value. Otherwise, terminate the +processing of your program. A false return occurs from a longjmp that +is executed when D-Flat attempts to allocate memory that is not +available. + +------------------------------------------------------------------- +WINDOW CreateWindow( + CLASS Class, /* class of this window */ + char *ttl, /* title or NULL */ + int left, int top, /* upper left coordinates */ + int height, int width, /* dimensions */ + void *extension, /* pointer to additional data */ + WINDOW parent, /* parent of this window */ + int (*wndproc)(struct window *,MESSAGE,PARAM,PARAM), + int attrib) /* window attribute */ + +This function creates a window. It returns the WINDOW handle that +messages and functions use to identify the window. If you specify +NULL for the parent, the APPLICATION window becomes the parent. + +------------------------------------------------------------------- +void PostMessage(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) + +Post a message to a window. The window will receive the message in +turn during the message-dispatching loop. + +------------------------------------------------------------------- +int SendMessage(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) + +Send a message to a window. The window will receive the message +immediately. Control returns to the sender after the window has +processed the message. The window can return an integer value. + +This function can send system messages to NULL. System messages +are ones that D-Flat processes without regard to a particular window. +------------------------------------------------------------------- +int dispatch_message(void) + +The message dispatching loop. After opening the first window (usually +the applications window), continue to call this function until it +returns a FALSE value. +------------------------------------------------------------------- +void handshake(void) + +This function dispatches messages without allowing any keyboard or +click events to pass through. You use it to allow the clock to run or +the watch icon to move during a lengthy process without allowing +anything to execute a command that might interfere with what your +program is doing. + +------------------------------------------------------------------- +int TestCriticalError(void) + +------------------------------------------------------------------- +int DefaultWndProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) + +Call this from a window-processing function to chain to the default +window-processing function for the window's class. + +------------------------------------------------------------------- +int BaseWndProc(CLASS Class, WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) + +Call this from the window-processing function of a derived window +class to chain to the window-processing function of the base window's +class. + +------------------------------------------------------------------- +int WindowHeight(WINDOW wnd) +int WindowWidth(WINDOW wnd) + +These functions return the window's height and width. +------------------------------------------------------------------- +int ClientWidth(WINDOW wnd) +int ClientHeight(WINDOW wnd) + +These functions return the height and width of the window's client +area. + +------------------------------------------------------------------- +int GetTop(WINDOW wnd) +int GetBottom(WINDOW wnd) +int GetLeft(WINDOW wnd) +int GetRight(WINDOW wnd) + +These functions return the screen coordinates of the four corners of +the window. + +------------------------------------------------------------------- +int GetClientTop(WINDOW wnd) +int GetClientBottom(WINDOW wnd) +int GetClientLeft(WINDOW wnd) +int GetClientRight(WINDOW wnd) + +These functions return the screen coordinates of the four corners of +the window's client area. + +------------------------------------------------------------------- +WINDOW GetParent(WINDOW wnd) + +Returns the parent of the window or NULL if the window has no +parent. + +------------------------------------------------------------------- +WINDOW FirstWindow(wnd) + +Returns the first child window that wnd is a parent of or NULL if +wnd has no children. + +------------------------------------------------------------------- +WINDOW LastWindow(wnd) + +Returns the last child window that wnd is a parent of or NULL if +wnd has no children. + +------------------------------------------------------------------- +WINDOW NextWindow(wnd) + +Returns the next adjacent sibling window of wnd or NULL if wnd has no +siblings. + +------------------------------------------------------------------- +WINDOW PrevWindow(wnd) + +Returns the previous adjacent sibling window of wnd or NULL if wnd +has no siblings. + +------------------------------------------------------------------- +int CharInView(WINDOW wnd, int x, int y) + +Returns true if the x/y character position, relative to the window, +is in view (not clipped at the border of a parent window or the +screen. + +------------------------------------------------------------------- +int TopBorderAdj(WINDOW wnd) + +Returns the value to add to a y coordinate of the window's client +area to make it relative to the window top. + +------------------------------------------------------------------- +int BorderAdj(WINDOW wnd) + +Returns the value to add to an x coordinate relative to the window's +client area to make it relative to the window's left edge. + +------------------------------------------------------------------- +char *GetTitle(WINDOW wnd) + +Returns the address of a window's title, or NULL if the window has no +title. + +------------------------------------------------------------------- +void AddTitle(WINDOW wnd, char *title) + +Adds or changes the title to an existing window. + +------------------------------------------------------------------- +CLASS GetClass(WINDOW wnd) + +Returns the class of the window. + +------------------------------------------------------------------- +int GetAttribute(WINDOW wnd) + +Returns the attribute word of a window. + +------------------------------------------------------------------- +void AddAttribute(WINDOW wnd, int attrib) + +Adds one or more attributes to a window. OR the attribute values +together. + +------------------------------------------------------------------- +void ClearAttribute(WINDOW wnd, int attrib) + +Clears one or more attributes from a window. OR the attribute values +together. + +------------------------------------------------------------------- +int TestAttribute(WINDOW wnd, int attrib) + +Tests one or more attributes in a window. Returns true if any of them +are set. OR the attribute values together. + +------------------------------------------------------------------- +int isVisible(WINDOW wnd) + +Returns true if the window is visible. + +------------------------------------------------------------------- +char *GetText(WINDOW wnd) + +Returns the address of the text buffer for a TEXTBOX or derived +window class. + +------------------------------------------------------------------- +int GetTextLines(WINDOW wnd) + +Returns the number of text lines in a TEXTBOX or derived +window class. + +------------------------------------------------------------------- +char *TextLine(WINDOW wnd, int line) + +Returns the address of a specified line of text (0, 1, ...) in a +TEXTBOX or derived class. + +------------------------------------------------------------------- +void SetProtected(WINDOW wnd) + +Protects a TEXTBOX or control derived from a TEXT from having its +data displayed. Displays * for each displayable character. Typically +used for EDITBOX controls used for password input. + +------------------------------------------------------------------- +int isActive(MENU *mnu, int command) + +Returns true if the command (commands.h) on the menu is active +(enabled). + +------------------------------------------------------------------- +char *GetCommandText(MBAR *mn, int cmd) + +Returns the address of a menu command's title text. + +------------------------------------------------------------------- +void ActivateCommand(MENU *mnu, int command) +void DeactivateCommand(MENU *mnu, int command) + +Activate (enable) or deactivate (disable) a command (commands.h) on a +menu. + +------------------------------------------------------------------- +int GetCommandToggle(MENU *mnu, int command) +void SetCommandToggle(MENU *mnu, int command) +void ClearCommandToggle(MENU *mnu, int command) +void InvertCommandToggle(MENU *mnu, int command) + +Some menu commands are toggles rather than executors of processes. +Examples are the Insert and Word wrap commands on the Options menu. +These functions get, set, clear, and invert the toggle setting for a +specified command on a specified menu. + +------------------------------------------------------------------- +int ItemSelected(WINDOW wnd, int line) + +This function returns true if the specified item (0, 1, ...) on a +multiple-line selection listbox is selected. + +------------------------------------------------------------------- +int DialogBox( + WINDOW wnd, /* parent window of the dialog box */ + DBOX *db, /* address of dialog box definition array */ + int Modal, /* true if it is a modal dialog box */ + int (*wndproc)(struct window *, MESSAGE, PARAM, PARAM) + /* the window processing function or NULL */ +) + +This function executes a dialog box. If it is a modal dialog box, the +function does not return until the user completes the dialog box. The +return value will be true if the user has selected OK and false if +the user has selected Cancel on the dialog box. If the dialog box is +modeless, the function returns immediately, and the user can select +other things from the screen while the dialog box is still active. + +------------------------------------------------------------------- +WINDOW ControlWindow(DBOX *db, enum commands cmd) + +This function returns the WINDOW handle of the control specified by +the cmd parameter. +------------------------------------------------------------------- +void MessageBox(char *title, char *message) +void CancelBox(wnd, char *message) +void ErrorMessage(char *message) +int TestErrorMessage(char *message) +int YesNoBox(char *question) +WINDOW MomentaryMessage(char *message) + +These functions display generic message boxes. The message text is +one null-terminated string with newlines (\n) to indicate where lines +are to be broken. The size of the boxes adjusts to the width of the +longest line and the number of lines of text. A message may have no +more lines of text than will fit into the largest window that the +screen can display. You must account for the window's border's and +the presence at the bottom of one or more command buttons. + +The MessageBox function displays a message in a window with a title +provided by the caller. The window contains the message and an OK +command button. + +The CancelBox function displays a message in a window with a +"Wait..." title. The window contains the message and a Cancel command +button. If the user presses the Cancel button before the program +closes the window, the COMMAND, ID_CANCEL message is sent to the +parent window. + +The ErrorMessage function displays the message in an error box window +with an OK command button. + +The TestErrorMessage function is an error message with OK and Cancel +command buttons. The function returns true if the user selects OK or +presses Enter and false if the user selects Cancel or presses Esc. + +The YesNoBox function displays the message with Yes and No command +buttons. The function returns true if the user selects Yes or +presses Enter and false if the user selects No or presses Esc. + +The MomentaryMessage function displays a message box and returns its +WINDOW handle. The caller must close the window. The purpose of this +function is to allow you to display a message while some time +consuming process is underway and then erase the message after the +process is done but without any action required from the user. + +------------------------------------------------------------------- +int InputBox(WINDOW wnd, char *ttl, char *msg, char *text, int len, int wd) + +This function executes a generic one-line user input dialog box. The +wnd parameter is the parent window of the dialog box. The ttl +parameter points to a title string for the dialog box. The msg +parameter points to a prompting text message. The text parameter +points to the string that will receive the user's input. The len +parameter is the length of the input string not including the null +terminator. The wd parameter is the width of the string display. If +the wd parameter is 0, the function computes a width based on the len +parameter. + +The function returns a true value if the user chooses the OK command +button and false if the user selects Cancel. + +------------------------------------------------------------------- +WINDOW SliderBox(int len, char *ttl, char *msg) + +This function displays a dialog box with the specified title and +message, a slider bar of the specified length, and a Cancel button. +The slider bar displays a percent value. + +You use the slider box to display feedback to the user when the +program is doing a time-consuming task, such as printing a file. +Periodically, through your process, you send a PAINT message to the +window handle that the SliderBox function returns. The second +parameter is the new percent value. When you have sent 100, the +slider dialog box closes itself. If the user chooses the Cancel +command on the dialog box, your next PAINT message returns FALSE. +Otherwise it returns TRUE. + +------------------------------------------------------------------- +int RadioButtonSetting(DBOX *db, enum commands cmd) + +This function returns true if the specified command on the specified +dialog box is a pressed radio button. + +------------------------------------------------------------------- +void EnableButton(DBOX *db, enum commands cmd) + +This function enables a command button on a dialog box. command +buttons are initially enabled when the dialog box is first opened. + +------------------------------------------------------------------- +void DisableButton(DBOX *db, enum commands cmd) + +This function disables a command button on a dialog box. command +buttons are initially enabled when the dialog box is first opened. + +------------------------------------------------------------------- +int ButtonEnabled(DBOX *db, enum commands cmd) + +Returns true if the button is enabled. +------------------------------------------------------------------- +void PushRadioButton(DBOX *db, enum commands cmd) + +This function presses the specified radio button command on the +specified dialog box. + +------------------------------------------------------------------- +void PutItemText(WINDOW wnd, enum commands cmd, char *text) + +This function appends a line of text to a TEXT, TEXTBOX, EDITBOX, +LISTBOX, SPINBUTTON, or COMBOBOX control window in a dialog box. The +wnd parameter is the WINDOW handle of the dialog box. The cmd +parameter specifies the command associated with the control item. The +text parameter points to the text to be added. The control window +makes its own copy of the text, so the caller's copy can go out of +scope. If the control window is a COMBOBOX, TEXTBOX, or EDITBOX +window, you must send a PAINT message to the control window so that +the new text will display. + +You must call this function while the dialog box is active. That +means that if the dialog box is modal, you must call this function +from within a custom window processing function that you supply when +you call DialogBox. + +------------------------------------------------------------------- +void PutComboListText(WINDOW wnd, enum commands cmd, char *text) + +This function appends a line of text to the LISTBOX of a COMBOBOX +control window in a dialog box. The wnd parameter is the WINDOW +handle of the dialog box. The cmd parameter specifies the command +associated with the combo box. The text parameter points to the +text to be added. The control window makes its own copy of the text, +so the caller's copy can go out of scope. + +You must call this function while the dialog box is active. That +means that if the dialog box is modal, you must call this function +from within a custom window processing function that you supply when +you call DialogBox. + +------------------------------------------------------------------- +void GetItemText(WINDOW wnd, enum commands cmd, char *text, int length) + +This function copies the text from a TEXT, TEXTBOX, COMBOBOX, or +EDITBOX control window in a dialog box. The wnd parameter is the +WINDOW handle of the dialog box. The cmd parameter specifies the +command associated with the control item. The text parameter points +to the caller's buffer where the text will be copied. The length +parameter specifies the maximum number of characters to copy. + +You must call this function while the dialog box is active. That +means that if the dialog box is modal, you must call this function +from within a custom window processing function that you supply when +you call DialogBox. + +------------------------------------------------------------------- +char *GetEditBoxText(DBOX *db, enum commands cmd) + +This function returns a pointer to the text associated with an +editbox control in a dialog box. You can call it after the dialog box +has completed processing. The buffer is on the heap. Do not free it. +Instead, call SetEditBoxText with a NULL pointer. + +------------------------------------------------------------------- +char *GetComboBoxText(DBOX *db, enum commands cmd) + +This function returns a pointer to the text associated with an +combo box control in a dialog box. You can call it after the dialog box +has completed processing. The buffer is on the heap. Do not free it. +Instead, call SetEditBoxText with a NULL pointer. + +------------------------------------------------------------------- +void SetEditBoxText(DBOX *db, enum commands cmd, char *text) + +This function sets the text of a dialog box editbox. You can call +this function before or while the dialog box is open. The dialog box +makes its own copy on the heap, so your text can go out of scope. + +------------------------------------------------------------------- +void SetComboBoxText(DBOX *db, enum commands cmd, char *text) + +This function sets the text of a dialog box combo box. You can call +this function before or while the dialog box is open. The dialog box +makes its own copy on the heap, so your text can go out of scope. + +------------------------------------------------------------------- +char *GetDlgText(DBOX *db, enum commands cmd, char *text) + +Similar to GetEditBoxText except that it works with text controls. + +------------------------------------------------------------------- +char *SetDlgText(DBOX *db, enum commands cmd, char *text) + +Similar to SetEditBoxText except that it works with text controls. + +------------------------------------------------------------------- +char *GetDlgTextBox(DBOX *db, enum commands cmd, char *text) + +Similar to GetEditBoxText except that it works with textbox controls. + +------------------------------------------------------------------- +char *SetDlgTextBox(DBOX *db, enum commands cmd, char *text) + +Similar to SetEditBoxText except that it works with textbox controls. + +------------------------------------------------------------------- +void SetCheckBox(DBOX *db, enum commands cmd) +void ClearCheckBox(DBOX *db, enum commands cmd) +int CheckBoxSetting(DBOX *db, enum commands cmd) + +These functions set, clear, and test the setting of a specified check +box control item on a dialog box. + +------------------------------------------------------------------- +void SetDlgTitle(DBOX *db, char *ttl) + +This function changes the specified dialog box's title. +------------------------------------------------------------------- +void LoadHelpFile(char *apname); + +This function loads the help file. The apname parameter points to +the helpfile name without the .hlp extension. + +Call this function at the beginning of an application program or to +change the help file midstream. + +------------------------------------------------------------------- +void DisplayHelp(WINDOW wnd, char *Help) + +Display the help window identified by the Help parameter. See the +comments in memopad.txt for the format of a help database. You can +get the same effect by sending the DISPLAY_HELP message with a +pointer to the Help string as the first parameter after the message +id. + +------------------------------------------------------------------- +char *HelpComment(char *Help) + +Retrieve a pointer to the comment text associated with the specified +Help parameter. + +------------------------------------------------------------------- +void UnLoadHelpFile(void); + +Call this function at the end of a D-Flat application to free the +memory used by a help file. + +------------------------------------------------------------------- +void SearchText(WINDOW wnd) + +Opens a dialog box for the user to enter a search string. Searches +the wnd TEXTBOX for a match on the string. + +------------------------------------------------------------------- +void ReplaceText(WINDOW wnd) + +Opens a dialog box for the user to enter search and replacement +strings. Searches the wnd TEXTBOX for a match on the string and +replaces it if found. The dialog box includes an option to replace +all matches. + +------------------------------------------------------------------- +void SearchNext(WINDOW wnd) + +Assumes that a previous SearchText call has found a match. Searches +for the next match of the same string in the specified EDITBOX +window. + +------------------------------------------------------------------- +void WriteTextLine(WINDOW wnd, RECT *rcc, int y, int reverse) + +This function displays a text line from a TEXTBOX or derived window +class. The text has already been added to the window with ADDTEXT, +etc. The y parameter specifies which line (0, 1, ...) relative to the +window's text buffer to display. If the specified line is not in +view, the function does nothing. If the reverse parameter is true, +the line displays in the reverse-video colors of the window. The rcc +RECT pointer is usually NULL for applications calls. It points to a +rectangle relative to the window outside of which displays will not +occur. + +------------------------------------------------------------------- +void PutWindowLine(WINDOW wnd, void *s, int x, int y) + +This function writes a line of text to a window. The x and y +coordinates point to the first character in the window's client area +where the line is to be written. The text must be null-terminated. +This function clips the line if it goes beyond the window or the +screen. The function clips the line if it goes outside the borders of +the window's parent. If other windows overlap the target window, the +text is clipped. Do not use negative values in x or y. + +You can assign color values to the global variables foreground and +background to affect the color of the line's display. + +------------------------------------------------------------------- +void PutWindowChar(WINDOW wnd, int c, int x, int y) + +This function writes the character c to a window. The x and y +coordinates are relative to the window's client area. + +The function performs clipping. If the character is beyond the +window's or the screen's borders it is not written. If the window +does not have the NOCLIP attribute, the character is not written if +its coordinates are beyond the margins of its parent window (if the +window has a parent). If other windows overlap the target window, the +text is clipped. Do not use negative values in x or y. + +You can assign color values to the global variables foreground and +background to affect the color of the character's display. + +------------------------------------------------------------------- +void DrawVector(WINDOW wnd, int x, int y, int len, int hv) + +Draw a horizontal vector in a picture box. x and y are character +coordinates relative to the starting position of the vector. len is +the length. hv is TRUE for a horizontal vector and FALSE for a +vertical vector. Sends a DRAWVECTOR message to the window. + +Send a PAINT message to the window to display the vectors. + +------------------------------------------------------------------- +void DrawBox(WINDOW wnd, int x, int y, int ht, int wd) + +Draw a box in a picture box. x and y are character coordinates +relative to the upper left corner of the box. ht and wd are the +height and width of the box. Sends a DRAWBOX message to the window. + +Send a PAINT message to the window to display the box. + +------------------------------------------------------------------- +void DrawBar(WINDOW wnd, enum VectTypes vt, int x, int y, int len, int hv) + +Draw a graph bar in a picture box. vt is one of the following values +to specify the character box used to display the bar: SOLIDBAR, +HEAVYBAR, CROSSBAR, LIGHTBAR. x and y are character coordinates +relative to the starting position of the bar. len is the length. hv +is TRUE for a horizontal bar and FALSE for a vertical bar. Sends a +DRAWBAR message to the window. + +Send a PAINT message to the window to display the bars. + +------------------------------------------------------------------- +void WindowClientColor(WINDOW wnd, int fg, int bg) + +Changes the window client space's foreground and background colors. +------------------------------------------------------------------- +void WindowReverseColor(WINDOW wnd, int fg, int bg) + +Changes the window's foreground and background reverse colors, which +are used to display such things as selected text blocks. +------------------------------------------------------------------- +void WindowFrameColor(WINDOW wnd, int fg, int bg) + +Changes the window's foreground and background frame colors. +------------------------------------------------------------------- +void WindowHighlightColor(WINDOW wnd, int fg, int bg) + +Changes the window's foreground and background highlight colors, +which are used to display highlighted items such as menu selector +bars. +------------------------------------------------------------------- +void MarkTextBlock(WINDOW wnd, int BegLine, int BegCol, + int EndLine, int EndCol) + +Marks a block in the specified TEXTBOX window. + +------------------------------------------------------------------- +void ClearTextBlock(WINDOW wnd) + +Unmarks a marked block in the specified TEXTBOX window. + +------------------------------------------------------------------- +void CopyToClipboard(WINDOW wnd) + +Copies the marked block from the WINDOW into the Clipboard. + +------------------------------------------------------------------- +void CopyTextToClipboard(char *string) + +Copies a null-terminated string into the Clipboard. + +------------------------------------------------------------------- +void PasteFromClipboard(WINDOW wnd) + +Pastes the Clipboard's contents into the specified EDITBOX window at +the current cursor location. + +------------------------------------------------------------------- +void ClearClipboard(void) + +Clears the clipboard and frees the memory allocated for it. Called by +D-Flat when message processing terminates. + +------------------------------------------------------------------- +WINDOW WatchIcon(void) + +Displays a wristwatch icon on the screen. The icon has control of the +keyboard and mouse. You must send the CLOSE_WINDOW message to the +WINDOW handle that WatchIcon returns to get rid of the icon. + +Use this icon to tell the user to please stand by during long +processes. Call handshake frequently during these processes to +update the date display in the status bar and to allow the watch icon +to move when the user moves the mouse. + +------------------------------------------------------------------- +Configurable Items + +Global Symbol File Value Description +------------- --------- ----- --------------------------------------- +MAXMESSAGES DFLAT.H 50 Maximum D-Flat messages queued +MAXCONTROLS DIALBOX.H 26 Maximum Controls on a dialog box +MAXRADIOS DIALBOX.H 20 Maximum radio buttons in a group +MAXSAVES SYSTEM.H 50 Maximum cursor saves +MAXPULLDOWNS MENU.H 15 Maximum number of pull-down menus on + a menu bar (including cascading menus) +MAXSELECTIONS MENU.H 15 Maximum number of selections on + a pull-down menu (includes separators) +MAXCASCADES MENU.H 3 Maximum nesting level of cascaded menus +MAXTEXTLEN DFLAT.H 65000 Maximum text buffer +EDITLEN DFLAT.H 1024 Starting length for multiline EDITBOX +ENTRYLEN DFLAT.H 256 Starting length for single-line EDITBOX +GROWLENGTH DFLAT.H 64 EDITBOX buffers grow by this much + + diff --git a/rosapps/dflat32/dflat.h b/rosapps/dflat32/dflat.h new file mode 100644 index 00000000000..fd391a19094 --- /dev/null +++ b/rosapps/dflat32/dflat.h @@ -0,0 +1,482 @@ +/* ------------- dflat.h ----------- */ +#ifndef DFLAT_H +#define DFLAT_H + +//#ifdef BUILD_FULL_DFLAT +#define INCLUDE_MULTI_WINDOWS +#define INCLUDE_LOGGING +#define INCLUDE_SHELLDOS +#define INCLUDE_WINDOWOPTIONS +#define INCLUDE_PICTUREBOX +#define INCLUDE_MINIMIZE +#define INCLUDE_MAXIMIZE +#define INCLUDE_RESTORE +#define INCLUDE_EXTENDEDSELECTIONS +//#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef VERSION +#define VERSION "Beta Version 0.3" +#endif + +void *DFcalloc(size_t, size_t); +void *DFmalloc(size_t); +void *DFrealloc(void *, size_t); + + +#define MAXMESSAGES 50 +#define DELAYTICKS 1 +#define FIRSTDELAY 7 +#define DOUBLETICKS 5 + +#define MAXTEXTLEN 65000U /* maximum text buffer */ +#define EDITLEN 1024 /* starting length for multiliner */ +#define ENTRYLEN 256 /* starting length for one-liner */ +#define GROWLENGTH 64 /* buffers grow by this much */ + +#include "system.h" +#include "config.h" +#include "rect.h" +#include "menu.h" +#include "keys.h" +#include "commands.h" +#include "dialbox.h" + +/* ------ integer type for message parameters ----- */ +typedef long PARAM; + +enum Condition +{ + ISRESTORED, ISMINIMIZED, ISMAXIMIZED, ISCLOSING +}; + +typedef struct window +{ + DFCLASS class; /* window class */ + char *title; /* window title */ + int (*wndproc)(struct window *, enum messages, PARAM, PARAM); + + /* ----------------- window colors -------------------- */ + char WindowColors[4][2]; + + /* ---------------- window dimensions ----------------- */ + DFRECT rc; /* window coordinates (0/0 to 79/24) */ + int ht, wd; /* window height and width */ + DFRECT RestoredRC; /* restored condition rect */ + + /* -------------- linked list pointers ---------------- */ + struct window *parent; /* parent window */ + struct window *firstchild; /* first child this parent */ + struct window *lastchild; /* last child this parent */ + struct window *nextsibling; /* next sibling */ + struct window *prevsibling; /* previous sibling */ + struct window *childfocus; /* child that ha(s/d) focus */ + + int attrib; /* Window attributes */ + PCHAR_INFO videosave; /* video save buffer */ + enum Condition condition; /* Restored, Maximized, + Minimized, Closing */ + enum Condition oldcondition;/* previous condition */ + int restored_attrib; /* attributes when restored */ + void *extension; /* menus, dialogs, documents, etc */ + struct window *PrevMouse; + struct window *PrevKeyboard; + struct window *MenuBarWnd;/* menu bar */ + struct window *StatusBar; /* status bar */ + int isHelping; /* > 0 when help is being displayed */ + + /* ----------------- text box fields ------------------ */ + int wlines; /* number of lines of text */ + int wtop; /* text line that is on the top display */ + unsigned char *text; /* window text */ + unsigned int textlen; /* text length */ + int wleft; /* left position in window viewport */ + int textwidth; /* width of longest line in textbox */ + int BlkBegLine; /* beginning line of marked block */ + int BlkBegCol; /* beginning column of marked block */ + int BlkEndLine; /* ending line of marked block */ + int BlkEndCol; /* ending column of marked block */ + int HScrollBox; /* position of horizontal scroll box */ + int VScrollBox; /* position of vertical scroll box */ + unsigned int *TextPointers; /* -> list of line offsets */ + + /* ----------------- list box fields ------------------ */ + int selection; /* current selection */ + BOOL AddMode; /* adding extended selections mode */ + int AnchorPoint;/* anchor point for extended selections */ + int SelectCount;/* count of selected items */ + + /* ----------------- edit box fields ------------------ */ + int CurrCol; /* Current column */ + int CurrLine; /* Current line */ + int WndRow; /* Current window row */ + BOOL TextChanged; /* TRUE if text has changed */ + unsigned char *DeletedText; /* for undo */ + unsigned DeletedLength; /* Length of deleted field */ + BOOL InsertMode; /* TRUE or FALSE for text insert */ + BOOL WordWrapMode; /* TRUE or FALSE for word wrap */ + unsigned int MaxTextLength; /* maximum text length */ + + /* ---------------- dialog box fields ----------------- */ + int ReturnCode; /* return code from a dialog box */ + BOOL Modal; /* True if a modeless dialog box */ + CTLWINDOW *ct; /* control structure */ + struct window *dfocus; /* control window that has focus */ + /* -------------- popdownmenu fields ------------------ */ + MENU *mnu; /* points to menu structure */ + MBAR *holdmenu; /* previous active menu */ + struct window *oldFocus; + + /* --------------- help box fields -------------------- */ + void *firstword; /* -> first in list of key words */ + void *lastword; /* -> last in list of key words */ + void *thisword; /* -> current in list of key words */ + /* -------------- status bar fields ------------------- */ + BOOL TimePosted; /* True if time has been posted */ +#ifdef INCLUDE_PICTUREBOX + /* ------------- picture box fields ------------------- */ + int VectorCount; /* number of vectors in vector list */ + void *VectorList; /* list of picture box vectors */ +#endif +} * DFWINDOW; + +#include "classdef.h" +#include "video.h" + +void LogMessages (DFWINDOW, DFMESSAGE, PARAM, PARAM); +void MessageLog(DFWINDOW); +/* ------- window methods ----------- */ +#define ICONHEIGHT 3 +#define ICONWIDTH 10 +#define WindowHeight(w) ((w)->ht) +#define WindowWidth(w) ((w)->wd) +#define BorderAdj(w) (TestAttribute(w,HASBORDER)?1:0) +#define BottomBorderAdj(w) (TestAttribute(w,HASSTATUSBAR)?1:BorderAdj(w)) +#define TopBorderAdj(w) ((TestAttribute(w,HASTITLEBAR) && \ + TestAttribute(w,HASMENUBAR)) ? \ + 2 : (TestAttribute(w,HASTITLEBAR | \ + HASMENUBAR | HASBORDER) ? 1 : 0)) +#define ClientWidth(w) (WindowWidth(w)-BorderAdj(w)*2) +#define ClientHeight(w) (WindowHeight(w)-TopBorderAdj(w)-\ + BottomBorderAdj(w)) +#define WindowRect(w) ((w)->rc) +#define GetTop(w) (RectTop(WindowRect(w))) +#define GetBottom(w) (RectBottom(WindowRect(w))) +#define GetLeft(w) (RectLeft(WindowRect(w))) +#define GetRight(w) (RectRight(WindowRect(w))) +#define GetClientTop(w) (GetTop(w)+TopBorderAdj(w)) +#define GetClientBottom(w) (GetBottom(w)-BottomBorderAdj(w)) +#define GetClientLeft(w) (GetLeft(w)+BorderAdj(w)) +#define GetClientRight(w) (GetRight(w)-BorderAdj(w)) +#define GetTitle(w) ((w)->title) +#define GetParent(w) ((w)->parent) +#define FirstWindow(w) ((w)->firstchild) +#define LastWindow(w) ((w)->lastchild) +#define NextWindow(w) ((w)->nextsibling) +#define PrevWindow(w) ((w)->prevsibling) +#define GetClass(w) ((w)->class) +#define GetAttribute(w) ((w)->attrib) +#define AddAttribute(w,a) (GetAttribute(w) |= a) +#define ClearAttribute(w,a) (GetAttribute(w) &= ~(a)) +#define TestAttribute(w,a) (GetAttribute(w) & (a)) +#define isHidden(w) (!(GetAttribute(w) & VISIBLE)) +#define SetVisible(w) (GetAttribute(w) |= VISIBLE) +#define ClearVisible(w) (GetAttribute(w) &= ~VISIBLE) +#define gotoxy(w,x,y) cursor(w->rc.lf+(x)+1,w->rc.tp+(y)+1) +BOOL isVisible(DFWINDOW); +DFWINDOW DfCreateWindow(DFCLASS,char *,int,int,int,int,void*,DFWINDOW, + int (*)(struct window *,enum messages,PARAM,PARAM),int); +void AddTitle(DFWINDOW, char *); +void InsertTitle(DFWINDOW, char *); +void DisplayTitle(DFWINDOW, DFRECT *); +void RepaintBorder(DFWINDOW, DFRECT *); +void PaintShadow(DFWINDOW); +void ClearWindow(DFWINDOW, DFRECT *, int); +void writeline(DFWINDOW, char *, int, int, BOOL); +void InitWindowColors(DFWINDOW); + +void SetNextFocus(void); +void SetPrevFocus(void); +void RemoveWindow(DFWINDOW); +void AppendWindow(DFWINDOW); +void ReFocus(DFWINDOW); +void SkipApplicationControls(void); + +BOOL CharInView(DFWINDOW, int, int); +void CreatePath(char *, char *, int, int); +#define SwapVideoBuffer(wnd, ish, fh) swapvideo(wnd, wnd->videosave, ish, fh) +int LineLength(char *); +DFRECT AdjustRectangle(DFWINDOW, DFRECT); +BOOL isDerivedFrom(DFWINDOW, DFCLASS); +DFWINDOW GetAncestor(DFWINDOW); +void PutWindowChar(DFWINDOW,char,int,int); +void PutWindowLine(DFWINDOW, void *,int,int); +#define BaseWndProc(class,wnd,msg,p1,p2) \ + (*classdefs[(classdefs[class].base)].wndproc)(wnd,msg,p1,p2) +#define DefaultWndProc(wnd,msg,p1,p2) \ + (classdefs[wnd->class].wndproc == NULL) ? \ + BaseWndProc(wnd->class,wnd,msg,p1,p2) : \ + (*classdefs[wnd->class].wndproc)(wnd,msg,p1,p2) +struct LinkedList { + DFWINDOW FirstWindow; + DFWINDOW LastWindow; +}; +extern DFWINDOW ApplicationWindow; +extern DFWINDOW inFocus; +extern DFWINDOW CaptureMouse; +extern DFWINDOW CaptureKeyboard; +extern int foreground, background; +extern BOOL WindowMoving; +extern BOOL WindowSizing; +extern BOOL VSliding; +extern BOOL HSliding; +extern char DFlatApplication[]; +extern char *Clipboard; +extern unsigned ClipboardLength; +extern BOOL ClipString; +/* --------- space between menubar labels --------- */ +#define MSPACE 2 +/* --------------- border characters ------------- */ +#define FOCUS_NW (unsigned char) '\xc9' +#define FOCUS_NE (unsigned char) '\xbb' +#define FOCUS_SE (unsigned char) '\xbc' +#define FOCUS_SW (unsigned char) '\xc8' +#define FOCUS_SIDE (unsigned char) '\xba' +#define FOCUS_LINE (unsigned char) '\xcd' +#define NW (unsigned char) '\xda' +#define NE (unsigned char) '\xbf' +#define SE (unsigned char) '\xd9' +#define SW (unsigned char) '\xc0' +#define SIDE (unsigned char) '\xb3' +#define LINE (unsigned char) '\xc4' +#define LEDGE (unsigned char) '\xc3' +#define REDGE (unsigned char) '\xb4' +/* ------------- scroll bar characters ------------ */ +#define UPSCROLLBOX (unsigned char) '\x1e' +#define DOWNSCROLLBOX (unsigned char) '\x1f' +#define LEFTSCROLLBOX (unsigned char) '\x11' +#define RIGHTSCROLLBOX (unsigned char) '\x10' +#define SCROLLBARCHAR (unsigned char) 176 +#define SCROLLBOXCHAR (unsigned char) 178 +/* ------------------ menu characters --------------------- */ +#define CHECKMARK (unsigned char) (SCREENHEIGHT==25?251:4) +#define CASCADEPOINTER (unsigned char) '\x10' +/* ----------------- title bar characters ----------------- */ +#define CONTROLBOXCHAR (unsigned char) '\xf0' +#define MAXPOINTER 24 /* maximize token */ +#define MINPOINTER 25 /* minimize token */ +#define RESTOREPOINTER 18 /* restore token */ +/* --------------- text control characters ---------------- */ +#define APPLCHAR (unsigned char) 176 /* fills application window */ +#define SHORTCUTCHAR '~' /* prefix: shortcut key display */ +#define CHANGECOLOR (unsigned char) 174 /* prefix to change colors */ +#define RESETCOLOR (unsigned char) 175 /* reset colors to default */ +#define LISTSELECTOR 4 /* selected list box entry */ +/* --------- message prototypes ----------- */ +BOOL init_messages(void); +void DfPostMessage (DFWINDOW, DFMESSAGE, PARAM, PARAM); +int DfSendMessage (DFWINDOW, DFMESSAGE, PARAM, PARAM); +BOOL DfDispatchMessage (void); +void handshake(void); + +/* ---- standard window message processing prototypes ----- */ +int ApplicationProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int NormalProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int TextBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int ListBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int EditBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int PictureProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int MenuBarProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int PopDownProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int ButtonProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int ComboProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int TextProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int RadioButtonProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int CheckBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int SpinButtonProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int BoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int DialogProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int SystemMenuProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int HelpBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int MessageBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int CancelBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int ErrorBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int YesNoBoxProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int StatusBarProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +int WatchIconProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +/* ------------- normal box prototypes ------------- */ +void SetStandardColor(DFWINDOW); +void SetReverseColor(DFWINDOW); +BOOL isAncestor(DFWINDOW, DFWINDOW); +#define HitControlBox(wnd, p1, p2) \ + (TestAttribute(wnd, CONTROLBOX) && \ + p1 == 2 && p2 == 0) +#define WndForeground(wnd) \ + (wnd->WindowColors [STD_COLOR] [FG]) +#define WndBackground(wnd) \ + (wnd->WindowColors [STD_COLOR] [BG]) +#define FrameForeground(wnd) \ + (wnd->WindowColors [FRAME_COLOR] [FG]) +#define FrameBackground(wnd) \ + (wnd->WindowColors [FRAME_COLOR] [BG]) +#define SelectForeground(wnd) \ + (wnd->WindowColors [SELECT_COLOR] [FG]) +#define SelectBackground(wnd) \ + (wnd->WindowColors [SELECT_COLOR] [BG]) +#define HighlightForeground(wnd) \ + (wnd->WindowColors [HILITE_COLOR] [FG]) +#define HighlightBackground(wnd) \ + (wnd->WindowColors [HILITE_COLOR] [BG]) +#define WindowClientColor(wnd, fg, bg) \ + WndForeground(wnd) = fg, WndBackground(wnd) = bg +#define WindowReverseColor(wnd, fg, bg) \ + SelectForeground(wnd) = fg, SelectBackground(wnd) = bg +#define WindowFrameColor(wnd, fg, bg) \ + FrameForeground(wnd) = fg, FrameBackground(wnd) = bg +#define WindowHighlightColor(wnd, fg, bg) \ + HighlightForeground(wnd) = fg, HighlightBackground(wnd) = bg +/* -------- text box prototypes ---------- */ +#define TextLine(wnd, sel) \ + (wnd->text + *((wnd->TextPointers) + sel)) +void WriteTextLine(DFWINDOW, DFRECT *, int, BOOL); +#define TextBlockMarked(wnd) ( wnd->BlkBegLine || \ + wnd->BlkEndLine || \ + wnd->BlkBegCol || \ + wnd->BlkEndCol) +void MarkTextBlock(DFWINDOW, int, int, int, int); +#define ClearTextBlock(wnd) wnd->BlkBegLine = wnd->BlkEndLine = \ + wnd->BlkBegCol = wnd->BlkEndCol = 0; +#define GetText(w) ((w)->text) +#define GetTextLines(w) ((w)->wlines) +void ClearTextPointers(DFWINDOW); +void BuildTextPointers(DFWINDOW); +int TextLineNumber(DFWINDOW, char *); +/* ------------ Clipboard prototypes ------------- */ +void CopyTextToClipboard(char *); +void CopyToClipboard(DFWINDOW); +#define PasteFromClipboard(wnd) PasteText(wnd,Clipboard,ClipboardLength) +BOOL PasteText(DFWINDOW, char *, unsigned); +void ClearClipboard(void); +/* --------- menu prototypes ---------- */ +int CopyCommand(unsigned char *, unsigned char *, int, int); +void PrepFileMenu(void *, struct Menu *); +void PrepEditMenu(void *, struct Menu *); +void PrepSearchMenu(void *, struct Menu *); +void PrepWindowMenu(void *, struct Menu *); +void BuildSystemMenu(DFWINDOW); +BOOL isActive(MBAR *, int); +char *GetCommandText(MBAR *, int); +BOOL isCascadedCommand(MBAR *,int); +void ActivateCommand(MBAR *,int); +void DeactivateCommand(MBAR *,int); +BOOL GetCommandToggle(MBAR *,int); +void SetCommandToggle(MBAR *,int); +void ClearCommandToggle(MBAR *,int); +void InvertCommandToggle(MBAR *,int); +int BarSelection(int); +/* ------------- list box prototypes -------------- */ +BOOL ItemSelected(DFWINDOW, int); +/* ------------- edit box prototypes ----------- */ +#define CurrChar (TextLine(wnd, wnd->CurrLine)+wnd->CurrCol) +#define WndCol (wnd->CurrCol-wnd->wleft) +#define isMultiLine(wnd) TestAttribute(wnd, MULTILINE) +void DfSearchText(DFWINDOW); +void DfReplaceText(DFWINDOW); +void DfSearchNext(DFWINDOW); +/* --------- message box prototypes -------- */ +DFWINDOW SliderBox(int, char *, char *); +BOOL InputBox(DFWINDOW, char *, char *, char *, int); +BOOL GenericMessage(DFWINDOW, char *, char *, int, + int (*)(struct window *, enum messages, PARAM, PARAM), + char *, char *, int, int, int); +#define DfTestErrorMessage(msg) \ + GenericMessage(NULL, "Error", msg, 2, ErrorBoxProc, \ + Ok, Cancel, ID_OK, ID_CANCEL, TRUE) +#define DfErrorMessage(msg) \ + GenericMessage(NULL, "Error", msg, 1, ErrorBoxProc, \ + Ok, NULL, ID_OK, 0, TRUE) +#define DfMessageBox(ttl, msg) \ + GenericMessage(NULL, ttl, msg, 1, MessageBoxProc, \ + Ok, NULL, ID_OK, 0, TRUE) +#define DfYesNoBox(msg) \ + GenericMessage(NULL, NULL, msg, 2, YesNoBoxProc, \ + Yes, No, ID_OK, ID_CANCEL, TRUE) +#define DfCancelBox(wnd, msg) \ + GenericMessage(wnd, "Wait...", msg, 1, CancelBoxProc, \ + Cancel, NULL, ID_CANCEL, 0, FALSE) +void CloseCancelBox(void); +DFWINDOW MomentaryMessage(char *); +int MsgHeight(char *); +int MsgWidth(char *); + +/* ------------- dialog box prototypes -------------- */ +BOOL DfDialogBox(DFWINDOW, DBOX *, BOOL, + int (*)(struct window *, enum messages, PARAM, PARAM)); +void ClearDialogBoxes(void); +BOOL OpenFileDialogBox(char *, char *); +BOOL SaveAsDialogBox(char *); +void GetDlgListText(DFWINDOW, char *, enum commands); +BOOL DfDlgDirList(DFWINDOW, char *, enum commands, + enum commands, unsigned); +BOOL RadioButtonSetting(DBOX *, enum commands); +void PushRadioButton(DBOX *, enum commands); +void PutItemText(DFWINDOW, enum commands, char *); +void PutComboListText(DFWINDOW, enum commands, char *); +void GetItemText(DFWINDOW, enum commands, char *, int); +char *GetDlgTextString(DBOX *, enum commands, DFCLASS); +void SetDlgTextString(DBOX *, enum commands, char *, DFCLASS); +BOOL CheckBoxSetting(DBOX *, enum commands); +CTLWINDOW *FindCommand(DBOX *, enum commands, int); +DFWINDOW ControlWindow(DBOX *, enum commands); +void SetScrollBars(DFWINDOW); +void SetRadioButton(DBOX *, CTLWINDOW *); +void ControlSetting(DBOX *, enum commands, int, int); +void SetFocusCursor(DFWINDOW); + +#define GetControl(wnd) (wnd->ct) +#define GetDlgText(db, cmd) GetDlgTextString(db, cmd, TEXT) +#define GetDlgTextBox(db, cmd) GetDlgTextString(db, cmd, TEXTBOX) +#define GetEditBoxText(db, cmd) GetDlgTextString(db, cmd, EDITBOX) +#define GetComboBoxText(db, cmd) GetDlgTextString(db, cmd, COMBOBOX) +#define SetDlgText(db, cmd, s) SetDlgTextString(db, cmd, s, TEXT) +#define SetDlgTextBox(db, cmd, s) SetDlgTextString(db, cmd, s, TEXTBOX) +#define SetEditBoxText(db, cmd, s) SetDlgTextString(db, cmd, s, EDITBOX) +#define SetComboBoxText(db, cmd, s) SetDlgTextString(db, cmd, s, COMBOBOX) +#define SetDlgTitle(db, ttl) ((db)->dwnd.title = ttl) +#define SetCheckBox(db, cmd) ControlSetting(db, cmd, CHECKBOX, ON) +#define ClearCheckBox(db, cmd) ControlSetting(db, cmd, CHECKBOX, OFF) +#define EnableButton(db, cmd) ControlSetting(db, cmd, BUTTON, ON) +#define DisableButton(db, cmd) ControlSetting(db, cmd, BUTTON, OFF) + +/* ---- types of vectors that can be in a picture box ------- */ +enum VectTypes {VECTOR, SOLIDBAR, HEAVYBAR, CROSSBAR, LIGHTBAR}; + +/* ------------- picture box prototypes ------------- */ +void DrawVector(DFWINDOW, int, int, int, int); +void DrawBox(DFWINDOW, int, int, int, int); +void DrawBar(DFWINDOW, enum VectTypes, int, int, int, int); +DFWINDOW WatchIcon(void); + +/* ------------- help box prototypes ------------- */ +void LoadHelpFile(void); +void UnLoadHelpFile(void); +BOOL DisplayHelp(DFWINDOW, char *); + +extern char *ClassNames[]; + +void BuildFileName(char *, char *); + +#endif diff --git a/rosapps/dflat32/dflatmsg.h b/rosapps/dflat32/dflatmsg.h new file mode 100644 index 00000000000..cfca23e4b1c --- /dev/null +++ b/rosapps/dflat32/dflatmsg.h @@ -0,0 +1,100 @@ +/* ----------- dflatmsg.h ------------ */ + +/* + * message foundation file + * make message changes here + * other source files will adapt + */ + +/* -------------- process communication messages ----------- */ +DFlatMsg(DFM_START) /* start message processing */ +DFlatMsg(DFM_STOP) /* stop message processing */ +DFlatMsg(DFM_COMMAND) /* send a command to a window */ +/* -------------- window management messages --------------- */ +DFlatMsg(CREATE_WINDOW) /* create a window */ +DFlatMsg(SHOW_WINDOW) /* show a window */ +DFlatMsg(DFM_HIDE_WINDOW) /* hide a window */ +DFlatMsg(CLOSE_WINDOW) /* delete a window */ +DFlatMsg(SETFOCUS) /* set and clear the focus */ +DFlatMsg(PAINT) /* paint the window's data space*/ +DFlatMsg(BORDER) /* paint the window's border */ +DFlatMsg(TITLE) /* display the window's title */ +DFlatMsg(MOVE) /* move the window */ +DFlatMsg(DFM_SIZE) /* change the window's size */ +#ifdef INCLUDE_MAXIMIZE +DFlatMsg(MAXIMIZE) /* maximize the window */ +#endif +#ifdef INCLUDE_MINIMIZE +DFlatMsg(MINIMIZE) /* minimize the window */ +#endif +DFlatMsg(RESTORE) /* restore the window */ +DFlatMsg(INSIDE_WINDOW) /* test x/y inside a window */ +/* ---------------- clock messages ------------------------- */ +DFlatMsg(CLOCKTICK) /* the clock ticked */ +DFlatMsg(CAPTURE_CLOCK) /* capture clock into a window */ +DFlatMsg(RELEASE_CLOCK) /* release clock to the system */ +/* -------------- keyboard and screen messages ------------- */ +DFlatMsg(KEYBOARD) /* key was pressed */ +DFlatMsg(CAPTURE_KEYBOARD) /* capture keyboard into a window */ +DFlatMsg(RELEASE_KEYBOARD) /* release keyboard to system */ +DFlatMsg(KEYBOARD_CURSOR) /* position the keyboard cursor */ +DFlatMsg(CURRENT_KEYBOARD_CURSOR) /*read the cursor position */ +DFlatMsg(HIDE_CURSOR) /* hide the keyboard cursor */ +DFlatMsg(SHOW_CURSOR) /* display the keyboard cursor */ +DFlatMsg(SAVE_CURSOR) /* save the cursor's configuration*/ +DFlatMsg(RESTORE_CURSOR) /* restore the saved cursor */ +DFlatMsg(SHIFT_CHANGED) /* the shift status changed */ +DFlatMsg(WAITKEYBOARD) /* waits for a key to be released */ + +/* ---------------- mouse messages ------------------------- */ +DFlatMsg(MOUSE_TRAVEL) /* set the mouse travel */ +DFlatMsg(RIGHT_BUTTON) /* right button pressed */ +DFlatMsg(LEFT_BUTTON) /* left button pressed */ +DFlatMsg(DFM_DOUBLE_CLICK) /* left button double-clicked */ +DFlatMsg(DFM_MOUSE_MOVED) /* mouse changed position */ +DFlatMsg(DFM_BUTTON_RELEASED) /* mouse button released */ +DFlatMsg(WAITMOUSE) /* wait until button released */ +DFlatMsg(TESTMOUSE) /* test any mouse button pressed*/ +DFlatMsg(CAPTURE_MOUSE) /* capture mouse into a window */ +DFlatMsg(RELEASE_MOUSE) /* release the mouse to system */ + +/* ---------------- text box messages ---------------------- */ +DFlatMsg(ADDTEXT) /* append text to the text box */ +DFlatMsg(INSERTTEXT) /* insert line of text */ +DFlatMsg(DELETETEXT) /* delete line of text */ +DFlatMsg(CLEARTEXT) /* clear the edit box */ +DFlatMsg(SETTEXT) /* copy text to text buffer */ +DFlatMsg(SCROLL) /* vertical line scroll */ +DFlatMsg(HORIZSCROLL) /* horizontal column scroll */ +DFlatMsg(SCROLLPAGE) /* vertical page scroll */ +DFlatMsg(HORIZPAGE) /* horizontal page scroll */ +DFlatMsg(SCROLLDOC) /* scroll to beginning/end */ +/* ---------------- edit box messages ---------------------- */ +DFlatMsg(GETTEXT) /* get text from an edit box */ +DFlatMsg(SETTEXTLENGTH) /* set maximum text length */ +/* ---------------- menubar messages ----------------------- */ +DFlatMsg(BUILDMENU) /* build the menu display */ +DFlatMsg(MB_SELECTION) /* menubar selection */ +/* ---------------- popdown messages ----------------------- */ +DFlatMsg(BUILD_SELECTIONS) /* build the menu display */ +DFlatMsg(CLOSE_POPDOWN) /* tell parent popdown is closing */ +/* ---------------- list box messages ---------------------- */ +DFlatMsg(LB_SELECTION) /* sent to parent on selection */ +DFlatMsg(LB_CHOOSE) /* sent when user chooses */ +DFlatMsg(LB_CURRENTSELECTION)/* return the current selection */ +DFlatMsg(DFM_LB_GETTEXT) /* return the text of selection */ +DFlatMsg(LB_SETSELECTION) /* sets the listbox selection */ +/* ---------------- dialog box messages -------------------- */ +DFlatMsg(INITIATE_DIALOG) /* begin a dialog */ +DFlatMsg(ENTERFOCUS) /* tell DB control got focus */ +DFlatMsg(LEAVEFOCUS) /* tell DB control lost focus */ +DFlatMsg(ENDDIALOG) /* end a dialog */ +/* ---------------- help box messages ---------------------- */ +DFlatMsg(DISPLAY_HELP) +/* --------------- application window messages ------------- */ +DFlatMsg(ADDSTATUS) +/* --------------- picture box messages -------------------- */ +DFlatMsg(DRAWVECTOR) +DFlatMsg(DRAWBOX) +DFlatMsg(DRAWBAR) + diff --git a/rosapps/dflat32/dialbox.c b/rosapps/dflat32/dialbox.c new file mode 100644 index 00000000000..9e7fd3e652f --- /dev/null +++ b/rosapps/dflat32/dialbox.c @@ -0,0 +1,792 @@ +/* ----------------- dialbox.c -------------- */ + +#include "dflat.h" + +static int inFocusCommand(DBOX *); +static void dbShortcutKeys(DBOX *, int); +static int ControlProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static void FirstFocus(DBOX *db); +static void NextFocus(DBOX *db); +static void PrevFocus(DBOX *db); +static CTLWINDOW *AssociatedControl(DBOX *, enum commands); + +static BOOL SysMenuOpen; + +static DBOX **dbs = NULL; +static int dbct = 0; + +/* --- clear all heap allocations to control text fields --- */ +void ClearDialogBoxes(void) +{ + int i; + + for (i = 0; i < dbct; i++) + { + CTLWINDOW *ct = (*(dbs+i))->ctl; + + while (ct->class) + { + if ((ct->class == EDITBOX || + ct->class == COMBOBOX) && + ct->itext != NULL) + { + free(ct->itext); + } + ct++; + } + } + + if (dbs != NULL) + { + free(dbs); + dbs = NULL; + } + dbct = 0; +} + + +/* -------- CREATE_WINDOW Message --------- */ +static int CreateWindowMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + DBOX *db = wnd->extension; + CTLWINDOW *ct = db->ctl; + DFWINDOW cwnd; + int rtn, i; + /* ---- build a table of processed dialog boxes ---- */ + for (i = 0; i < dbct; i++) + if (db == dbs[i]) + break; + if (i == dbct) { + dbs = DFrealloc(dbs, sizeof(DBOX *) * (dbct+1)); + *(dbs + dbct++) = db; + } + rtn = BaseWndProc(DIALOG, wnd, CREATE_WINDOW, p1, p2); + ct = db->ctl; + while (ct->class) { + int attrib = 0; + if (TestAttribute(wnd, NOCLIP)) + attrib |= NOCLIP; + if (wnd->Modal) + attrib |= SAVESELF; + ct->setting = ct->isetting; + if (ct->class == EDITBOX && ct->dwnd.h > 1) + attrib |= (MULTILINE | HASBORDER); + else if ((ct->class == LISTBOX || ct->class == TEXTBOX) && + ct->dwnd.h > 2) + attrib |= HASBORDER; + cwnd = DfCreateWindow(ct->class, + ct->dwnd.title, + ct->dwnd.x+GetClientLeft(wnd), + ct->dwnd.y+GetClientTop(wnd), + ct->dwnd.h, + ct->dwnd.w, + ct, + wnd, + ControlProc, + attrib); + if ((ct->class == EDITBOX || + ct->class == COMBOBOX) && + ct->itext != NULL) + DfSendMessage(cwnd, SETTEXT, (PARAM) ct->itext, 0); + ct++; + } + return rtn; +} + +/* -------- LEFT_BUTTON Message --------- */ +static BOOL LeftButtonMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + DBOX *db = wnd->extension; + CTLWINDOW *ct = db->ctl; + if (WindowSizing || WindowMoving) + return TRUE; + if (HitControlBox(wnd, p1-GetLeft(wnd), p2-GetTop(wnd))) { + DfPostMessage(wnd, KEYBOARD, ' ', ALTKEY); + return TRUE; + } + while (ct->class) { + DFWINDOW cwnd = ct->wnd; + if (ct->class == COMBOBOX) { + if (p2 == GetTop(cwnd)) { + if (p1 == GetRight(cwnd)+1) { + DfSendMessage(cwnd, LEFT_BUTTON, p1, p2); + return TRUE; + } + } + if (GetClass(inFocus) == LISTBOX) + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + } + else if (ct->class == SPINBUTTON) { + if (p2 == GetTop(cwnd)) { + if (p1 == GetRight(cwnd)+1 || + p1 == GetRight(cwnd)+2) { + DfSendMessage(cwnd, LEFT_BUTTON, p1, p2); + return TRUE; + } + } + } + ct++; + } + return FALSE; +} + +/* -------- KEYBOARD Message --------- */ +static BOOL KeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + DBOX *db = wnd->extension; + CTLWINDOW *ct; + + if (WindowMoving || WindowSizing) + return FALSE; + switch ((int)p1) { + case F1: + ct = GetControl(inFocus); + if (ct != NULL) + if (DisplayHelp(wnd, ct->help)) + return TRUE; + break; + case SHIFT_HT: + case BS: + case UP: + PrevFocus(db); + break; + case ALT_F6: + case '\t': + case FWD: + case DN: + NextFocus(db); + break; + case ' ': + if (((int)p2 & ALTKEY) && + TestAttribute(wnd, CONTROLBOX)) { + SysMenuOpen = TRUE; + BuildSystemMenu(wnd); + } + break; + case CTRL_F4: + case ESC: + DfSendMessage(wnd, DFM_COMMAND, ID_CANCEL, 0); + break; + default: + /* ------ search all the shortcut keys ----- */ + dbShortcutKeys(db, (int) p1); + break; + } + return wnd->Modal; +} + +/* -------- COMMAND Message --------- */ +static BOOL CommandMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + DBOX *db = wnd->extension; + switch ((int) p1) { + case ID_OK: + case ID_CANCEL: + if ((int)p2 != 0) + return TRUE; + wnd->ReturnCode = (int) p1; + if (wnd->Modal) + DfPostMessage(wnd, ENDDIALOG, 0, 0); + else + DfSendMessage(wnd, CLOSE_WINDOW, TRUE, 0); + return TRUE; + case ID_HELP: + if ((int)p2 != 0) + return TRUE; + return DisplayHelp(wnd, db->HelpName); + default: + break; + } + return FALSE; +} + +/* ----- window-processing module, DIALOG window class ----- */ +int DialogProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + DBOX *db = wnd->extension; + + switch (msg) { + case CREATE_WINDOW: + return CreateWindowMsg(wnd, p1, p2); + case SHIFT_CHANGED: + if (wnd->Modal) + return TRUE; + break; + case LEFT_BUTTON: + if (LeftButtonMsg(wnd, p1, p2)) + return TRUE; + break; + case KEYBOARD: + if (KeyboardMsg(wnd, p1, p2)) + return TRUE; + break; + case CLOSE_POPDOWN: + SysMenuOpen = FALSE; + break; + case LB_SELECTION: + case LB_CHOOSE: + if (SysMenuOpen) + return TRUE; + DfSendMessage(wnd, DFM_COMMAND, inFocusCommand(db), msg); + break; + case DFM_COMMAND: + if (CommandMsg(wnd, p1, p2)) + return TRUE; + break; + case PAINT: + p2 = TRUE; + break; + case MOVE: + case DFM_SIZE: + rtn = BaseWndProc(DIALOG, wnd, msg, p1, p2); + if (wnd->dfocus != NULL) + DfSendMessage(wnd->dfocus, SETFOCUS, TRUE, 0); + return rtn; + + case CLOSE_WINDOW: + if (!p1) + { + DfSendMessage(wnd, DFM_COMMAND, ID_CANCEL, 0); + return TRUE; + } + break; + + default: + break; + } + return BaseWndProc(DIALOG, wnd, msg, p1, p2); +} + +/* ------- create and execute a dialog box ---------- */ +BOOL DfDialogBox(DFWINDOW wnd, DBOX *db, BOOL Modal, + int (*wndproc)(struct window *, enum messages, PARAM, PARAM)) +{ + BOOL rtn; + int x = db->dwnd.x, y = db->dwnd.y; + DFWINDOW DialogWnd; + + if (!Modal && wnd != NULL) + { + x += GetLeft(wnd); + y += GetTop(wnd); + } + DialogWnd = DfCreateWindow(DIALOG, + db->dwnd.title, + x, y, + db->dwnd.h, + db->dwnd.w, + db, + wnd, + wndproc, + Modal ? SAVESELF : 0); + DialogWnd->Modal = Modal; + FirstFocus(db); + DfPostMessage(DialogWnd, INITIATE_DIALOG, 0, 0); + if (Modal) + { + DfSendMessage(DialogWnd, CAPTURE_MOUSE, 0, 0); + DfSendMessage(DialogWnd, CAPTURE_KEYBOARD, 0, 0); + while (DfDispatchMessage ()) + ; + rtn = DialogWnd->ReturnCode == ID_OK; + DfSendMessage(DialogWnd, RELEASE_MOUSE, 0, 0); + DfSendMessage(DialogWnd, RELEASE_KEYBOARD, 0, 0); + DfSendMessage(DialogWnd, CLOSE_WINDOW, TRUE, 0); + return rtn; + } + return FALSE; +} + +/* ----- return command code of in-focus control window ---- */ +static int inFocusCommand(DBOX *db) +{ + CTLWINDOW *ct = db->ctl; + while (ct->class) { + if (ct->wnd == inFocus) + return ct->command; + ct++; + } + return -1; +} + +/* -------- find a specified control structure ------- */ +CTLWINDOW *FindCommand(DBOX *db, enum commands cmd, int class) +{ + CTLWINDOW *ct = db->ctl; + while (ct->class) + { + if (ct->class == class) + if (cmd == ct->command) + return ct; + ct++; + } + return NULL; +} + +/* ---- return the window handle of a specified command ---- */ +DFWINDOW ControlWindow(DBOX *db, enum commands cmd) +{ + CTLWINDOW *ct = db->ctl; + while (ct->class) + { + if (ct->class != TEXT && cmd == ct->command) + return ct->wnd; + ct++; + } + return NULL; +} + +/* --- return a pointer to the control structure that matches a window --- */ +CTLWINDOW *WindowControl(DBOX *db, DFWINDOW wnd) +{ + CTLWINDOW *ct = db->ctl; + while (ct->class) + { + if (ct->wnd == wnd) + return ct; + ct++; + } + return NULL; +} + +/* ---- set a control ON or OFF ----- */ +void ControlSetting(DBOX *db, enum commands cmd, + int class, int setting) +{ + CTLWINDOW *ct = FindCommand(db, cmd, class); + if (ct != NULL) { + ct->isetting = setting; + if (ct->wnd != NULL) + ct->setting = setting; + } +} + +/* ---- return pointer to the text of a control window ---- */ +char *GetDlgTextString(DBOX *db,enum commands cmd,DFCLASS class) +{ + CTLWINDOW *ct = FindCommand(db, cmd, class); + if (ct != NULL) + return ct->itext; + else + return NULL; +} + +/* ------- set the text of a control specification ------ */ +void SetDlgTextString(DBOX *db, enum commands cmd, + char *text, DFCLASS class) +{ + CTLWINDOW *ct = FindCommand(db, cmd, class); + if (ct != NULL) { + ct->itext = DFrealloc(ct->itext, strlen(text)+1); + strcpy(ct->itext, text); + } +} + +/* ------- set the text of a control window ------ */ +void PutItemText(DFWINDOW wnd, enum commands cmd, char *text) +{ + CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX); + + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, TEXTBOX); + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, COMBOBOX); + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, LISTBOX); + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, SPINBUTTON); + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, TEXT); + if (ct != NULL) { + DFWINDOW cwnd = (DFWINDOW) (ct->wnd); + switch (ct->class) { + case COMBOBOX: + case EDITBOX: + DfSendMessage(cwnd, CLEARTEXT, 0, 0); + DfSendMessage(cwnd, ADDTEXT, (PARAM) text, 0); + if (!isMultiLine(cwnd)) + DfSendMessage(cwnd, PAINT, 0, 0); + break; + case LISTBOX: + case TEXTBOX: + case SPINBUTTON: + DfSendMessage(cwnd, ADDTEXT, (PARAM) text, 0); + break; + case TEXT: { + DfSendMessage(cwnd, CLEARTEXT, 0, 0); + DfSendMessage(cwnd, ADDTEXT, (PARAM) text, 0); + DfSendMessage(cwnd, PAINT, 0, 0); + break; + } + default: + break; + } + } +} + +/* ------- get the text of a control window ------ */ +void GetItemText(DFWINDOW wnd, enum commands cmd, + char *text, int len) +{ + CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX); + unsigned char *cp; + + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, COMBOBOX); + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, TEXTBOX); + if (ct == NULL) + ct = FindCommand(wnd->extension, cmd, TEXT); + if (ct != NULL) { + DFWINDOW cwnd = (DFWINDOW) (ct->wnd); + if (cwnd != NULL) { + switch (ct->class) { + case TEXT: + if (GetText(cwnd) != NULL) { + cp = strchr(GetText(cwnd), '\n'); + if (cp != NULL) + len = (int) (cp - GetText(cwnd)); + strncpy(text, GetText(cwnd), len); + *(text+len) = '\0'; + } + break; + case TEXTBOX: + if (GetText(cwnd) != NULL) + strncpy(text, GetText(cwnd), len); + break; + case COMBOBOX: + case EDITBOX: + DfSendMessage(cwnd,GETTEXT,(PARAM)text,len); + break; + default: + break; + } + } + } +} + +/* ------- set the text of a listbox control window ------ */ +void GetDlgListText(DFWINDOW wnd, char *text, enum commands cmd) +{ + CTLWINDOW *ct = FindCommand(wnd->extension, cmd, LISTBOX); + int sel = DfSendMessage(ct->wnd, LB_CURRENTSELECTION, 0, 0); + DfSendMessage(ct->wnd, DFM_LB_GETTEXT, (PARAM) text, sel); +} + +/* -- find control structure associated with text control -- */ +static CTLWINDOW *AssociatedControl(DBOX *db,enum commands Tcmd) +{ + CTLWINDOW *ct = db->ctl; + while (ct->class) { + if (ct->class != TEXT) + if (ct->command == Tcmd) + break; + ct++; + } + return ct; +} + +/* --- process dialog box shortcut keys --- */ +static void dbShortcutKeys(DBOX *db, int ky) +{ + CTLWINDOW *ct; + int ch = AltConvert(ky); + + if (ch != 0) { + ct = db->ctl; + while (ct->class) { + char *cp = ct->itext; + while (cp && *cp) { + if (*cp == SHORTCUTCHAR && + tolower(*(cp+1)) == ch) { + if (ct->class == TEXT) + ct = AssociatedControl(db, ct->command); + if (ct->class == RADIOBUTTON) + SetRadioButton(db, ct); + else if (ct->class == CHECKBOX) { + ct->setting ^= ON; + DfSendMessage(ct->wnd, PAINT, 0, 0); + } + else if (ct->class) { + DfSendMessage(ct->wnd, SETFOCUS, TRUE, 0); + if (ct->class == BUTTON) + DfSendMessage(ct->wnd,KEYBOARD,'\r',0); + } + return; + } + cp++; + } + ct++; + } + } +} + +/* --- dynamically add or remove scroll bars + from a control window ---- */ +void SetScrollBars(DFWINDOW wnd) +{ + int oldattr = GetAttribute(wnd); + if (wnd->wlines > ClientHeight(wnd)) + AddAttribute(wnd, VSCROLLBAR); + else + ClearAttribute(wnd, VSCROLLBAR); + if (wnd->textwidth > ClientWidth(wnd)) + AddAttribute(wnd, HSCROLLBAR); + else + ClearAttribute(wnd, HSCROLLBAR); + if (GetAttribute(wnd) != oldattr) + DfSendMessage(wnd, BORDER, 0, 0); +} + +/* ------- CREATE_WINDOW Message (Control) ----- */ +static void CtlCreateWindowMsg(DFWINDOW wnd) +{ + CTLWINDOW *ct; + ct = wnd->ct = wnd->extension; + wnd->extension = NULL; + if (ct != NULL) + ct->wnd = wnd; +} + +/* ------- KEYBOARD Message (Control) ----- */ +static BOOL CtlKeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + CTLWINDOW *ct = GetControl(wnd); + switch ((int) p1) { + case F1: + if (WindowMoving || WindowSizing) + break; + if (!DisplayHelp(wnd, ct->help)) + DfSendMessage(GetParent(wnd),DFM_COMMAND,ID_HELP,0); + return TRUE; + case ' ': + if (!((int)p2 & ALTKEY)) + break; + case ALT_F6: + case CTRL_F4: + case ALT_F4: + DfPostMessage(GetParent(wnd), KEYBOARD, p1, p2); + return TRUE; + default: + break; + } + if (GetClass(wnd) == EDITBOX) + if (isMultiLine(wnd)) + return FALSE; + switch ((int) p1) { + case UP: + if (!isDerivedFrom(wnd, LISTBOX)) { + p1 = CTRL_FIVE; + p2 = LEFTSHIFT; + } + break; + case BS: + if (!isDerivedFrom(wnd, EDITBOX)) { + p1 = CTRL_FIVE; + p2 = LEFTSHIFT; + } + break; + case DN: + if (!isDerivedFrom(wnd, LISTBOX) && + !isDerivedFrom(wnd, COMBOBOX)) + p1 = '\t'; + break; + case FWD: + if (!isDerivedFrom(wnd, EDITBOX)) + p1 = '\t'; + break; + case '\r': + if (isDerivedFrom(wnd, EDITBOX)) + if (isMultiLine(wnd)) + break; + if (isDerivedFrom(wnd, BUTTON)) + break; + DfSendMessage(GetParent(wnd), DFM_COMMAND, ID_OK, 0); + return TRUE; + default: + break; + } + return FALSE; +} + +/* ------- CLOSE_WINDOW Message (Control) ----- */ +static void CtlCloseWindowMsg(DFWINDOW wnd) +{ + CTLWINDOW *ct = GetControl(wnd); + if (ct != NULL) { + ct->wnd = NULL; + if (GetParent(wnd)->ReturnCode == ID_OK) { + if (ct->class == EDITBOX || ct->class == COMBOBOX) { + if (wnd->TextChanged) { + ct->itext=DFrealloc(ct->itext,strlen(wnd->text)+1); + strcpy(ct->itext, wnd->text); + if (!isMultiLine(wnd)) { + char *cp = ct->itext+strlen(ct->itext)-1; + if (*cp == '\n') + *cp = '\0'; + } + } + } + else if (ct->class == RADIOBUTTON || ct->class == CHECKBOX) + ct->isetting = ct->setting; + } + } +} + + +static void FixColors(DFWINDOW wnd) +{ + CTLWINDOW *ct = wnd->ct; + + if (ct->class != BUTTON) + { + if (ct->class != SPINBUTTON && ct->class != COMBOBOX) + { + wnd->WindowColors[FRAME_COLOR][FG] = + GetParent(wnd)->WindowColors[FRAME_COLOR][FG]; + wnd->WindowColors[FRAME_COLOR][BG] = + GetParent(wnd)->WindowColors[FRAME_COLOR][BG]; + if (ct->class != EDITBOX && ct->class != LISTBOX) + { + wnd->WindowColors[STD_COLOR][FG] = + GetParent(wnd)->WindowColors[STD_COLOR][FG]; + wnd->WindowColors[STD_COLOR][BG] = + GetParent(wnd)->WindowColors[STD_COLOR][BG]; + } + } + } +} + + +/* -- generic window processor used by dialog box controls -- */ +static int ControlProc(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + DBOX *db; + + if (wnd == NULL) + return FALSE; + db = GetParent(wnd) ? GetParent(wnd)->extension : NULL; + + switch (msg) { + case CREATE_WINDOW: + CtlCreateWindowMsg(wnd); + break; + case KEYBOARD: + if (CtlKeyboardMsg(wnd, p1, p2)) + return TRUE; + break; + case PAINT: + FixColors(wnd); + if (GetClass(wnd) == EDITBOX || + GetClass(wnd) == LISTBOX || + GetClass(wnd) == TEXTBOX) + SetScrollBars(wnd); + break; + case BORDER: + FixColors(wnd); + if (GetClass(wnd) == EDITBOX) { + DFWINDOW oldFocus = inFocus; + inFocus = NULL; + DefaultWndProc(wnd, msg, p1, p2); + inFocus = oldFocus; + return TRUE; + } + break; + case SETFOCUS: { + DFWINDOW pwnd = GetParent(wnd); + if (p1) + { + DefaultWndProc(wnd, msg, p1, p2); + if (pwnd != NULL) + { + pwnd->dfocus = wnd; + DfSendMessage(pwnd, DFM_COMMAND, + inFocusCommand(db), ENTERFOCUS); + } + return TRUE; + } + else + DfSendMessage(pwnd, DFM_COMMAND, + inFocusCommand(db), LEAVEFOCUS); + break; + } + case CLOSE_WINDOW: + CtlCloseWindowMsg(wnd); + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +/* ---- change the focus to the first control --- */ +static void FirstFocus(DBOX *db) +{ + CTLWINDOW *ct = db->ctl; + if (ct != NULL) + { + while (ct->class == TEXT || ct->class == BOX) { + ct++; + if (ct->class == 0) + return; + } + DfSendMessage(ct->wnd, SETFOCUS, TRUE, 0); + } +} + +/* ---- change the focus to the next control --- */ +static void NextFocus(DBOX *db) +{ + CTLWINDOW *ct = WindowControl(db, inFocus); + int looped = 0; + if (ct != NULL) + { + do + { + ct++; + if (ct->class == 0) + { + if (looped) + return; + looped++; + ct = db->ctl; + } + } while (ct->class == TEXT || ct->class == BOX); + DfSendMessage(ct->wnd, SETFOCUS, TRUE, 0); + } +} + +/* ---- change the focus to the previous control --- */ +static void PrevFocus(DBOX *db) +{ + CTLWINDOW *ct = WindowControl(db, inFocus); + int looped = 0; + if (ct != NULL) + { + do + { + if (ct == db->ctl) + { + if (looped) + return; + looped++; + while (ct->class) + ct++; + } + --ct; + } while (ct->class == TEXT || ct->class == BOX); + DfSendMessage(ct->wnd, SETFOCUS, TRUE, 0); + } +} + +void SetFocusCursor(DFWINDOW wnd) +{ + if (wnd == inFocus) + { + DfSendMessage(NULL, SHOW_CURSOR, 0, 0); + DfSendMessage(wnd, KEYBOARD_CURSOR, 1, 0); + } +} + +/* EOF */ diff --git a/rosapps/dflat32/dialbox.h b/rosapps/dflat32/dialbox.h new file mode 100644 index 00000000000..a32119d1d2a --- /dev/null +++ b/rosapps/dflat32/dialbox.h @@ -0,0 +1,55 @@ +/* ----------------- dialbox.h ---------------- */ + +#ifndef DIALOG_H +#define DIALOG_H + +#include + +#define MAXCONTROLS 30 +#define MAXRADIOS 20 + +#define OFF FALSE +#define ON TRUE + +/* -------- dialog box and control window structure ------- */ +typedef struct { + char *title; /* window title */ + int x, y; /* relative coordinates */ + int h, w; /* size */ +} DIALOGWINDOW; + +/* ------ one of these for each control window ------- */ +typedef struct { + DIALOGWINDOW dwnd; + DFCLASS class; /* LISTBOX, BUTTON, etc */ + char *itext; /* initialized text */ + int command; /* command code */ + char *help; /* help mnemonic */ + BOOL isetting; /* initially ON or OFF */ + BOOL setting; /* ON or OFF */ + void *wnd; /* window handle */ +} CTLWINDOW; + +/* --------- one of these for each dialog box ------- */ +typedef struct { + char *HelpName; + DIALOGWINDOW dwnd; + CTLWINDOW ctl[MAXCONTROLS+1]; +} DBOX; + +/* -------- macros for dialog box resource compile -------- */ +#define DIALOGBOX(db) DBOX db={ #db, +#define DB_TITLE(ttl,x,y,h,w) {ttl,x,y,h,w},{ +#define CONTROL(ty,tx,x,y,h,w,c) \ + {{NULL,x,y,h,w},ty, \ + (ty==EDITBOX||ty==COMBOBOX?NULL:tx), \ + c,#c,(ty==BUTTON?ON:OFF),OFF,NULL}, + +#define ENDDB {{NULL}} }}; + +#define Cancel " Cancel " +#define Ok " OK " +#define Yes " Yes " +#define No " No " + +#endif diff --git a/rosapps/dflat32/dialogs.c b/rosapps/dflat32/dialogs.c new file mode 100644 index 00000000000..489b8a73489 --- /dev/null +++ b/rosapps/dflat32/dialogs.c @@ -0,0 +1,160 @@ +/* ----------- dialogs.c --------------- */ + +#include "dflat.h" + +/* -------------- the File Open dialog box --------------- */ +DIALOGBOX( FileOpen ) + DB_TITLE( "Open File", -1,-1,19,48) + CONTROL(TEXT, "~Filename", 2, 1, 1, 8, ID_FILENAME) + CONTROL(EDITBOX, NULL, 13, 1, 1,29, ID_FILENAME) + CONTROL(TEXT, "Directory:", 2, 3, 1,10, 0) + CONTROL(TEXT, NULL, 13, 3, 1,28, ID_PATH) + CONTROL(TEXT, "F~iles", 2, 5, 1, 5, ID_FILES) + CONTROL(LISTBOX, NULL, 2, 6,11,16, ID_FILES) + CONTROL(TEXT, "~Directories", 19, 5, 1,11, ID_DRIVE) + CONTROL(LISTBOX, NULL, 19, 6,11,16, ID_DRIVE) + CONTROL(BUTTON, " ~OK ", 36, 7, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 36,10, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 36,13, 1, 8, ID_HELP) +ENDDB + +/* -------------- the Save As dialog box --------------- */ +DIALOGBOX( SaveAs ) + DB_TITLE( "Save As", -1,-1,19,48) + CONTROL(TEXT, "~Filename", 2, 1, 1, 8, ID_FILENAME) + CONTROL(EDITBOX, NULL, 13, 1, 1,29, ID_FILENAME) + CONTROL(TEXT, "Directory:", 2, 3, 1,10, 0) + CONTROL(TEXT, NULL, 13, 3, 1,28, ID_PATH) + CONTROL(TEXT, "~Directories",2, 5, 1,11, ID_DRIVE) + CONTROL(LISTBOX, NULL, 2, 6,11,16, ID_DRIVE) + CONTROL(BUTTON, " ~OK ", 36, 7, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 36,10, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 36,13, 1, 8, ID_HELP) +ENDDB + +/* -------------- The Printer Setup dialog box ------------------ */ +DIALOGBOX( PrintSetup ) + DB_TITLE( "Printer Setup", -1, -1, 17, 32) + CONTROL(BOX, "Margins", 2, 3, 9, 26, 0 ) + CONTROL(TEXT, "~Port:", 4, 1, 1, 5, ID_PRINTERPORT) + CONTROL(COMBOBOX, NULL, 12, 1, 8, 9, ID_PRINTERPORT) + CONTROL(TEXT, "~Left:", 6, 4, 1, 5, ID_LEFTMARGIN) + CONTROL(SPINBUTTON, NULL, 17, 4, 1, 6, ID_LEFTMARGIN) + CONTROL(TEXT, "~Right:", 6, 6, 1, 6, ID_RIGHTMARGIN) + CONTROL(SPINBUTTON, NULL, 17, 6, 1, 6, ID_RIGHTMARGIN) + CONTROL(TEXT, "~Top:", 6, 8, 1, 4, ID_TOPMARGIN) + CONTROL(SPINBUTTON, NULL, 17, 8, 1, 6, ID_TOPMARGIN) + CONTROL(TEXT, "~Bottom:", 6, 10, 1, 7, ID_BOTTOMMARGIN) + CONTROL(SPINBUTTON, NULL, 17, 10, 1, 6, ID_BOTTOMMARGIN) + CONTROL(BUTTON, " ~OK ", 1, 13, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 11, 13, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 21, 13, 1, 8, ID_HELP) +ENDDB + +/* -------------- the Search Text dialog box --------------- */ +DIALOGBOX( SearchTextDB ) + DB_TITLE( "Search Text", -1,-1,9,48) + CONTROL(TEXT, "~Search for:", 2, 1, 1, 11, ID_SEARCHFOR) + CONTROL(EDITBOX, NULL, 14, 1, 1, 29, ID_SEARCHFOR) + CONTROL(TEXT, "~Match upper/lower case:", 2, 3, 1, 23, ID_MATCHCASE) + CONTROL(CHECKBOX, NULL, 26, 3, 1, 3, ID_MATCHCASE) + CONTROL(BUTTON, " ~OK ", 7, 5, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 19, 5, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 31, 5, 1, 8, ID_HELP) +ENDDB + +/* -------------- the Replace Text dialog box --------------- */ +DIALOGBOX( ReplaceTextDB ) + DB_TITLE( "Replace Text", -1,-1,12,50) + CONTROL(TEXT, "~Search for:", 2, 1, 1, 11, ID_SEARCHFOR) + CONTROL(EDITBOX, NULL, 16, 1, 1, 29, ID_SEARCHFOR) + CONTROL(TEXT, "~Replace with:", 2, 3, 1, 13, ID_REPLACEWITH) + CONTROL(EDITBOX, NULL, 16, 3, 1, 29, ID_REPLACEWITH) + CONTROL(TEXT, "~Match upper/lower case:", 2, 5, 1, 23, ID_MATCHCASE) + CONTROL(CHECKBOX, NULL, 26, 5, 1, 3, ID_MATCHCASE) + CONTROL(TEXT, "Replace ~Every Match:", 2, 6, 1, 23, ID_REPLACEALL) + CONTROL(CHECKBOX, NULL, 26, 6, 1, 3, ID_REPLACEALL) + CONTROL(BUTTON, " ~OK ", 7, 8, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 20, 8, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 33, 8, 1, 8, ID_HELP) +ENDDB + +/* -------------- generic message dialog box --------------- */ +DIALOGBOX( MsgBox ) + DB_TITLE( NULL, -1,-1, 0, 0) + CONTROL(TEXT, NULL, 1, 1, 0, 0, 0) + CONTROL(BUTTON, NULL, 0, 0, 1, 8, ID_OK) + CONTROL(0, NULL, 0, 0, 1, 8, ID_CANCEL) +ENDDB + +/* ----------- InputBox Dialog Box ------------ */ +DIALOGBOX( InputBoxDB ) + DB_TITLE( NULL, -1,-1, 9, 0) + CONTROL(TEXT, NULL, 1, 1, 1, 0, 0) + CONTROL(EDITBOX, NULL, 1, 3, 1, 0, ID_INPUTTEXT) + CONTROL(BUTTON, " ~OK ", 0, 5, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 0, 5, 1, 8, ID_CANCEL) +ENDDB + +/* ----------- SliderBox Dialog Box ------------- */ +DIALOGBOX( SliderBoxDB ) + DB_TITLE( NULL, -1,-1, 9, 0) + CONTROL(TEXT, NULL, 0, 1, 1, 0, 0) + CONTROL(TEXT, NULL, 0, 3, 1, 0, 0) + CONTROL(BUTTON, " Cancel ", 0, 5, 1, 8, ID_CANCEL) +ENDDB + + +/* ------------ Display dialog box -------------- */ +DIALOGBOX( Display ) + DB_TITLE( "Display", -1, -1, 12, 35) + + CONTROL(BOX, "Window", 7, 1, 6,20, 0) + CONTROL(CHECKBOX, NULL, 9, 2, 1, 3, ID_TITLE) + CONTROL(TEXT, "~Title", 15, 2, 1, 5, ID_TITLE) + CONTROL(CHECKBOX, NULL, 9, 3, 1, 3, ID_BORDER) + CONTROL(TEXT, "~Border", 15, 3, 1, 6, ID_BORDER) + CONTROL(CHECKBOX, NULL, 9, 4, 1, 3, ID_STATUSBAR) + CONTROL(TEXT, "~Status bar",15, 4, 1,10, ID_STATUSBAR) + CONTROL(CHECKBOX, NULL, 9, 5, 1, 3, ID_TEXTURE) + CONTROL(TEXT, "Te~xture", 15, 5, 1, 7, ID_TEXTURE) + + CONTROL(BUTTON, " ~OK ", 2, 8,1,8,ID_OK) + CONTROL(BUTTON, " ~Cancel ", 12, 8,1,8,ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 22, 8,1,8,ID_HELP) +ENDDB + +/* ------------ Windows dialog box -------------- */ +DIALOGBOX( Windows ) + DB_TITLE( "Windows", -1, -1, 19, 24) + CONTROL(LISTBOX, NULL, 1, 1,11,20, ID_WINDOWLIST) + CONTROL(BUTTON, " ~OK ", 2, 13, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 12, 13, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 7, 15, 1, 8, ID_HELP) +ENDDB + +#ifdef INCLUDE_LOGGING +/* ------------ Message Log dialog box -------------- */ +DIALOGBOX( Log ) + DB_TITLE( "D-Flat Message Log", -1, -1, 18, 41) + CONTROL(TEXT, "~Messages", 10, 1, 1, 8, ID_LOGLIST) + CONTROL(LISTBOX, NULL, 1, 2, 14, 26, ID_LOGLIST) + CONTROL(TEXT, "~Logging:", 29, 4, 1, 10, ID_LOGGING) + CONTROL(CHECKBOX, NULL, 31, 5, 1, 3, ID_LOGGING) + CONTROL(BUTTON, " ~OK ", 29, 7, 1, 8, ID_OK) + CONTROL(BUTTON, " ~Cancel ", 29, 10, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Help ", 29, 13, 1, 8, ID_HELP) +ENDDB +#endif + +/* ------------ the Help window dialog box -------------- */ +DIALOGBOX( HelpBox ) + DB_TITLE( NULL, -1, -1, 0, 45) + CONTROL(TEXTBOX, NULL, 1, 1, 0, 40, ID_HELPTEXT) + CONTROL(BUTTON, " ~Close ", 0, 0, 1, 8, ID_CANCEL) + CONTROL(BUTTON, " ~Back ", 10, 0, 1, 8, ID_BACK) + CONTROL(BUTTON, "<< ~Prev ", 20, 0, 1, 8, ID_PREV) + CONTROL(BUTTON, " ~Next >>", 30, 0, 1, 8, ID_NEXT) +ENDDB + +/* EOF */ \ No newline at end of file diff --git a/rosapps/dflat32/direct.c b/rosapps/dflat32/direct.c new file mode 100644 index 00000000000..4635d44ef54 --- /dev/null +++ b/rosapps/dflat32/direct.c @@ -0,0 +1,175 @@ +/* ---------- direct.c --------- */ + +#include +#include + +#include "dflat.h" + +#define DRIVE 1 +#define DIRECTORY 2 +#define FILENAME 4 +#define EXTENSION 8 + +static char path[MAX_PATH]; +static char drive[_MAX_DRIVE] = " :"; +static char dir[_MAX_DIR]; +static char name[_MAX_FNAME]; +static char ext[_MAX_EXT]; + +/* ----- Create unambiguous path from file spec, filling in the + drive and directory if incomplete. Optionally change to + the new drive and subdirectory ------ */ +void CreatePath(char *path,char *fspec,int InclName,int Change) +{ + int cm = 0; + char currdir[MAX_PATH]; + char *cp; + + /* save the current directory */ + if (!Change) + GetCurrentDirectory (MAX_PATH, currdir); + + *drive = *dir = *name = *ext = '\0'; + _splitpath(fspec, drive, dir, name, ext); + if (!InclName) + *name = *ext = '\0'; + *drive = toupper(*drive); + if (*ext) + cm |= EXTENSION; + if (InclName && *name) + cm |= FILENAME; + if (*dir) + cm |= DIRECTORY; + if (*drive) + cm |= DRIVE; + if (cm & DRIVE) + _chdrive(*drive - '@'); + else + { + *drive = _getdrive(); + *drive += '@'; + } + if (cm & DIRECTORY) + { + cp = dir+strlen(dir)-1; + if (*cp == '\\') + *cp = '\0'; + chdir(dir); + } + getcwd(dir, sizeof dir); + memmove(dir, dir+2, strlen(dir+1)); + if (InclName) { + if (!(cm & FILENAME)) + strcpy(name, "*"); + if (!(cm & EXTENSION) && strchr(fspec, '.') != NULL) + strcpy(ext, ".*"); + } + else + *name = *ext = '\0'; + if (dir[strlen(dir)-1] != '\\') + strcat(dir, "\\"); + memset(path, 0, sizeof path); + _makepath(path, drive, dir, name, ext); + + if (!Change) + SetCurrentDirectory (currdir); +} + + +static int dircmp(const void *c1, const void *c2) +{ + return stricmp(*(char **)c1, *(char **)c2); +} + + +BOOL DfDlgDirList(DFWINDOW wnd, char *fspec, + enum commands nameid, enum commands pathid, + unsigned attrib) +{ + int ax, i = 0; + struct _finddata_t ff; + CTLWINDOW *ct = FindCommand(wnd->extension,nameid,LISTBOX); + DFWINDOW lwnd; + char **dirlist = NULL; + + CreatePath(path, fspec, TRUE, TRUE); + if (ct != NULL) + { + lwnd = ct->wnd; + DfSendMessage(ct->wnd, CLEARTEXT, 0, 0); + + if (attrib & 0x8000) + { + DWORD cd, dr; + + cd = GetLogicalDrives (); + for (dr = 0; dr < 26; dr++) + { + if (cd & (1 << dr)) + { + char drname[15]; + + sprintf(drname, "[%c:\\]", (char)(dr+'A')); +#if 0 + /* ---- test for network or RAM disk ---- */ + regs.x.ax = 0x4409; /* IOCTL func 9 */ + regs.h.bl = dr+1; + int86(DOS, ®s, ®s); + if (!regs.x.cflag) { + if (regs.x.dx & 0x1000) + strcat(drname, " (Network)"); + else if (regs.x.dx == 0x0800) + strcat(drname, " (RAMdisk)"); + } +#endif + DfSendMessage(lwnd,ADDTEXT,(PARAM)drname,0); + } + } + DfSendMessage(lwnd, PAINT, 0, 0); + } + ax = _findfirst(path, &ff); + if (ax == -1) + return FALSE; + do + { + if (!((attrib & 0x4000) && + (ff.attrib & (attrib & 0x3f)) == 0) && + strcmp(ff.name, ".")) + { + char fname[MAX_PATH+2]; + sprintf(fname, (ff.attrib & FILE_ATTRIBUTE_DIRECTORY) ? + "[%s]" : "%s" , ff.name); + dirlist = DFrealloc(dirlist, + sizeof(char *)*(i+1)); + dirlist[i] = DFmalloc(strlen(fname)+1); + if (dirlist[i] != NULL) + strcpy(dirlist[i], fname); + i++; + } + } + while (_findnext(ax, &ff) == 0); + _findclose(ax); + if (dirlist != NULL) + { + int j; + /* -- sort file/drive/directory list box data -- */ + qsort(dirlist, i, sizeof(void *), dircmp); + + /* ---- send sorted list to list box ---- */ + for (j = 0; j < i; j++) { + DfSendMessage(lwnd,ADDTEXT,(PARAM)dirlist[j],0); + free(dirlist[j]); + } + free(dirlist); + } + DfSendMessage(lwnd, SHOW_WINDOW, 0, 0); + } + if (pathid) + { + _makepath(path, drive, dir, NULL, NULL); + PutItemText(wnd, pathid, path); + } + return TRUE; +} + +/* EOF */ diff --git a/rosapps/dflat32/edit.c b/rosapps/dflat32/edit.c new file mode 100644 index 00000000000..4ae2d5de475 --- /dev/null +++ b/rosapps/dflat32/edit.c @@ -0,0 +1,738 @@ +/* --------------- edit.c ----------- */ + +#include "dflat.h" + +extern DBOX PrintSetup; + +char DFlatApplication[] = "Edit"; + +static char Untitled[] = "Untitled"; + +static int wndpos; + +static int MemoPadProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static void NewFile(DFWINDOW,char *); +static void SelectFile(DFWINDOW); +static void PadWindow(DFWINDOW, char *); +static void OpenPadWindow(DFWINDOW, char *,char *); +static void LoadFile(DFWINDOW); +static void PrintPad(DFWINDOW); +static void SaveFile(DFWINDOW, int); +static void EditDeleteFile(DFWINDOW); +static int EditorProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static char *NameComponent(char *); +static int PrintSetupProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static void FixTabMenu(void); +#ifndef TURBOC +void Calendar(DFWINDOW); +#endif +//void BarChart(DFWINDOW); +char **Argv; + +#define CHARSLINE 80 +#define LINESPAGE 66 + +int main (int argc, char *argv[]) +{ + DFWINDOW wnd; + FILE *fp; + if (!init_messages()) + return 1; + Argv = argv; + LoadConfig (); +// if (!LoadConfig()) +// cfg.ScreenLines = SCREENHEIGHT; + wnd = DfCreateWindow (APPLICATION, + "FreeDos Edit " VERSION, + 0, 0, -1, -1, + &MainMenu, + NULL, + MemoPadProc, +// MOVEABLE | +// SIZEABLE | +// HASBORDER | +// MINMAXBOX | + HASSTATUSBAR); + + LoadHelpFile (); + DfSendMessage (wnd, SETFOCUS, TRUE, 0); + + // Load the files from args - if the file does not exist, open a new window.... + while (argc > 1) + { + // check if the file exists.... + if (( fp = fopen(argv[1],"r")) == NULL ) + { + // file does not exist - create new window + NewFile(wnd,argv[1]); + } + else + PadWindow(wnd, argv[1]); + --argc; + argv++; + } + + while (DfDispatchMessage ()) + ; + + return 0; +} + +/* ------ open text files and put them into editboxes ----- */ +static void PadWindow(DFWINDOW wnd, char *FileName) +{ + int ax; + struct _finddata_t ff; + char path[MAX_PATH]; + char *cp; + + CreatePath(path, FileName, FALSE, FALSE); + cp = path+strlen(path); + CreatePath(path, FileName, TRUE, FALSE); + ax = _findfirst(path, &ff); + if (ax == -1) + return; + do + { + strcpy(cp, ff.name); + OpenPadWindow(wnd, path,NULL); + } + while (_findnext(ax, &ff) == 0); + _findclose (ax); +} + +/* ------- window processing module for the + Edit application window ----- */ +static int MemoPadProc(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + int rtn; + switch (msg) + { + case CREATE_WINDOW: + rtn = DefaultWndProc(wnd, msg, p1, p2); + if (cfg.InsertMode) + SetCommandToggle(&MainMenu, ID_INSERT); + if (cfg.WordWrap) + SetCommandToggle(&MainMenu, ID_WRAP); + FixTabMenu(); + return rtn; + case DFM_COMMAND: + switch ((int)p1) + { + case ID_NEW: + NewFile(wnd,NULL); + return TRUE; + + case ID_OPEN: + SelectFile(wnd); + return TRUE; + + case ID_SAVE: + SaveFile(inFocus, FALSE); + return TRUE; + + case ID_SAVEAS: + SaveFile(inFocus, TRUE); + return TRUE; + + case ID_DELETEFILE: + EditDeleteFile(inFocus); + return TRUE; + + case ID_PRINTSETUP: + DfDialogBox(wnd, &PrintSetup, TRUE, PrintSetupProc); + return TRUE; + + case ID_PRINT: + PrintPad(inFocus); + return TRUE; + + case ID_EXIT: + if (!DfYesNoBox("Exit FreeDos Edit?")) + return FALSE; + break; + + case ID_WRAP: + cfg.WordWrap = GetCommandToggle(&MainMenu, ID_WRAP); + return TRUE; + + case ID_INSERT: + cfg.InsertMode = GetCommandToggle(&MainMenu, ID_INSERT); + return TRUE; + + case ID_TAB2: + cfg.Tabs = 2; + FixTabMenu(); + return TRUE; + + case ID_TAB4: + cfg.Tabs = 4; + FixTabMenu(); + return TRUE; + + case ID_TAB6: + cfg.Tabs = 6; + FixTabMenu(); + return TRUE; + + case ID_TAB8: + cfg.Tabs = 8; + FixTabMenu(); + return TRUE; + + case ID_CALENDAR: + Calendar(wnd); + return TRUE; + +// case ID_BARCHART: +// BarChart(wnd); +// return TRUE; + + case ID_ABOUT: + DfMessageBox( + "About D-Flat and FreeDos Edit", + " ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n" + " ³ ÜÜÜ ÜÜÜ Ü ³\n" + " ³ Û Û Û Û Û ³\n" + " ³ Û Û Û Û Û ³\n" + " ³ Û Û Û Û Û Û ³\n" + " ³ ßßß ßßß ßß ³\n" + " RÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU\n" + "D-Flat implements the SAA/CUA\n" + "interface in a public domain\n" + "C language library originally\n" + "published in Dr. Dobb's Journal\n" + " ------------------------ \n" + "FreeDos Edit is a clone of MSDOS\n" + "editor for the FREEDOS Project"); + return TRUE; + + default: + break; + } + break; + + default: + break; + } + + return DefaultWndProc(wnd, msg, p1, p2); +} + +/* --- The New command. Open an empty editor window --- */ +static void NewFile(DFWINDOW wnd, char *FileName) +{ + OpenPadWindow(wnd, Untitled,FileName); +} + +/* --- The Open... command. Select a file --- */ +static void SelectFile(DFWINDOW wnd) +{ + char FileName[MAX_PATH]; + + if (OpenFileDialogBox("*.*", FileName)) + { + /* see if the document is already in a window */ + DFWINDOW wnd1 = FirstWindow(wnd); + while (wnd1 != NULL) + { + if (wnd1->extension && + stricmp(FileName, wnd1->extension) == 0) + { + DfSendMessage(wnd1, SETFOCUS, TRUE, 0); + DfSendMessage(wnd1, RESTORE, 0, 0); + return; + } + wnd1 = NextWindow(wnd1); + } + OpenPadWindow(wnd, FileName, NULL); + } +} + +/* --- open a document window and load a file --- */ +static void OpenPadWindow(DFWINDOW wnd, char *FileName,char *NewFileName) +{ + static DFWINDOW wnd1 = NULL; + DFWINDOW wwnd; + struct stat sb; + char *Fname = FileName; + char *Fnewname = NewFileName; + char *ermsg; + + if (strcmp(FileName, Untitled)) + { + if (stat(FileName, &sb)) + { + ermsg = DFmalloc(strlen(FileName)+20); + strcpy(ermsg, "No such file as\n"); + strcat(ermsg, FileName); + DfErrorMessage(ermsg); + free(ermsg); + return; + } + + Fname = NameComponent(FileName); + + // check file size + if (sb.st_size > 64000) + { + ermsg = DFmalloc(strlen(FileName)+20); + strcpy(ermsg, "File too large for this version of Edit\n"); + DfErrorMessage(ermsg); + free(ermsg); + return; + } + } + + wwnd = WatchIcon(); + wndpos += 2; + + if (NewFileName != NULL) + Fname = NameComponent(NewFileName); + + if (wndpos == 20) + wndpos = 2; + + wnd1 = DfCreateWindow(EDITBOX, + Fname, + (wndpos-1)*2, wndpos, 10, 40, + NULL, wnd, EditorProc, + SHADOW | + MINMAXBOX | + CONTROLBOX | + VSCROLLBAR | + HSCROLLBAR | + MOVEABLE | + HASBORDER | + SIZEABLE | + MULTILINE); + + if (strcmp(FileName, Untitled)) + { + wnd1->extension = DFmalloc(strlen(FileName)+1); + strcpy(wnd1->extension, FileName); + LoadFile(wnd1); + } + DfSendMessage(wwnd, CLOSE_WINDOW, 0, 0); + DfSendMessage(wnd1, SETFOCUS, TRUE, 0); + DfSendMessage(wnd1, MAXIMIZE, 0, 0); +} + +/* --- Load the notepad file into the editor text buffer --- */ +static void LoadFile(DFWINDOW wnd) +{ + char *Buf = NULL; + int recptr = 0; + FILE *fp; + + if ((fp = fopen(wnd->extension, "rt")) != NULL) + { + while (!feof(fp)) + { + handshake(); + Buf = DFrealloc(Buf, recptr+150); + memset(Buf+recptr, 0, 150); + fgets(Buf+recptr, 150, fp); + recptr += strlen(Buf+recptr); + } + fclose(fp); + if (Buf != NULL) + { + DfSendMessage(wnd, SETTEXT, (PARAM) Buf, 0); + free(Buf); + } + } +} + +static int LineCtr; +static int CharCtr; + +/* ------- print a character -------- */ +static void PrintChar(FILE *prn, int c) +{ + int i; + + if (c == '\n' || CharCtr == cfg.RightMargin) + { + fputs("\r\n", prn); + LineCtr++; + if (LineCtr == cfg.BottomMargin) + { + fputc('\f', prn); + for (i = 0; i < cfg.TopMargin; i++) + fputc('\n', prn); + LineCtr = cfg.TopMargin; + } + CharCtr = 0; + if (c == '\n') + return; + } + if (CharCtr == 0) + { + for (i = 0; i < cfg.LeftMargin; i++) + { + fputc(' ', prn); + CharCtr++; + } + } + CharCtr++; + fputc(c, prn); +} + +/* --- print the current notepad --- */ +static void PrintPad(DFWINDOW wnd) +{ + if (*cfg.PrinterPort) + { + FILE *prn; + if ((prn = fopen(cfg.PrinterPort, "wt")) != NULL) + { + long percent; + BOOL KeepPrinting = TRUE; + unsigned char *text = GetText(wnd); + unsigned oldpct = 100, cct = 0, len = strlen(text); + DFWINDOW swnd = SliderBox(20, GetTitle(wnd), "Printing"); + /* ------- print the notepad text --------- */ + LineCtr = CharCtr = 0; + while (KeepPrinting && *text) + { + PrintChar(prn, *text++); + percent = ((long) ++cct * 100) / len; + if ((int)percent != (int)oldpct) + { + oldpct = (int) percent; + KeepPrinting = DfSendMessage(swnd, PAINT, 0, oldpct); + } + } + if (KeepPrinting) + /* ---- user did not cancel ---- */ + if (oldpct < 100) + DfSendMessage(swnd, PAINT, 0, 100); + /* ------- follow with a form feed? --------- */ + if (DfYesNoBox("Form Feed?")) + fputc('\f', prn); + fclose(prn); + } + else + DfErrorMessage("Cannot open printer file"); + } + else + DfErrorMessage("No printer selected"); +} + +/* ---------- save a file to disk ------------ */ +static void SaveFile(DFWINDOW wnd, int Saveas) +{ + FILE *fp; + if (wnd->extension == NULL || Saveas) { + char FileName[MAX_PATH]; + if (SaveAsDialogBox(FileName)) { + if (wnd->extension != NULL) + free(wnd->extension); + wnd->extension = DFmalloc(strlen(FileName)+1); + strcpy(wnd->extension, FileName); + AddTitle(wnd, NameComponent(FileName)); + DfSendMessage(wnd, BORDER, 0, 0); + } + else + return; + } + if (wnd->extension != NULL) + { + DFWINDOW mwnd = MomentaryMessage("Saving the file"); + if ((fp = fopen(wnd->extension, "wt")) != NULL) + { + fwrite(GetText(wnd), strlen(GetText(wnd)), 1, fp); + fclose(fp); + wnd->TextChanged = FALSE; + } + DfSendMessage(mwnd, CLOSE_WINDOW, 0, 0); + } +} +/* -------- delete a file ------------ */ +static void EditDeleteFile(DFWINDOW wnd) +{ + if (wnd->extension != NULL) { + if (strcmp(wnd->extension, Untitled)) { + char *fn = NameComponent(wnd->extension); + if (fn != NULL) { + char msg[30]; + sprintf(msg, "Delete %s?", fn); + if (DfYesNoBox(msg)) { + unlink(wnd->extension); + DfSendMessage(wnd, CLOSE_WINDOW, 0, 0); + } + } + } + } +} +/* ------ display the row and column in the statusbar ------ */ +static void ShowPosition(DFWINDOW wnd) +{ + char status[30]; + sprintf(status, "Line:%4d Column: %2d", + wnd->CurrLine, wnd->CurrCol); + DfSendMessage(GetParent(wnd), ADDSTATUS, (PARAM) status, 0); +} + +/* window processing module for the editboxes */ +static int EditorProc(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + int rtn; + + switch (msg) + { + case SETFOCUS: + if ((int)p1) + { + wnd->InsertMode = GetCommandToggle(&MainMenu, ID_INSERT); + wnd->WordWrapMode = GetCommandToggle(&MainMenu, ID_WRAP); + } + rtn = DefaultWndProc(wnd, msg, p1, p2); + if ((int)p1 == FALSE) + DfSendMessage(GetParent(wnd), ADDSTATUS, 0, 0); + else + ShowPosition(wnd); + return rtn; + + case KEYBOARD_CURSOR: + rtn = DefaultWndProc(wnd, msg, p1, p2); + ShowPosition(wnd); + return rtn; + + case DFM_COMMAND: + switch ((int) p1) + { + case ID_SEARCH: + DfSearchText(wnd); + return TRUE; + case ID_REPLACE: + DfReplaceText(wnd); + return TRUE; + case ID_SEARCHNEXT: + DfSearchNext(wnd); + return TRUE; + case ID_CUT: + CopyToClipboard(wnd); + DfSendMessage(wnd, DFM_COMMAND, ID_DELETETEXT, 0); + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + case ID_COPY: + CopyToClipboard(wnd); + ClearTextBlock(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + case ID_PASTE: + PasteFromClipboard(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + case ID_DELETETEXT: + case ID_CLEAR: + rtn = DefaultWndProc(wnd, msg, p1, p2); + DfSendMessage(wnd, PAINT, 0, 0); + return rtn; + case ID_HELP: + DisplayHelp(wnd, "MEMOPADDOC"); + return TRUE; + case ID_WRAP: + DfSendMessage(GetParent(wnd), DFM_COMMAND, ID_WRAP, 0); + wnd->WordWrapMode = cfg.WordWrap; + return TRUE; + case ID_INSERT: + DfSendMessage(GetParent(wnd), DFM_COMMAND, ID_INSERT, 0); + wnd->InsertMode = cfg.InsertMode; + DfSendMessage(NULL, SHOW_CURSOR, wnd->InsertMode, 0); + return TRUE; + default: + break; + } + break; + + case CLOSE_WINDOW: + if (wnd->TextChanged) + { + char *cp = DFmalloc(25+strlen(GetTitle(wnd))); + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + strcpy(cp, GetTitle(wnd)); + strcat(cp, "\nText changed. Save it?"); + if (DfYesNoBox(cp)) + DfSendMessage(GetParent(wnd), DFM_COMMAND, ID_SAVE, 0); + free(cp); + } + wndpos = 0; + if (wnd->extension != NULL) + { + free(wnd->extension); + wnd->extension = NULL; + } + break; + + default: + break; + } + + return DefaultWndProc(wnd, msg, p1, p2); +} + +/* -- point to the name component of a file specification -- */ +static char *NameComponent(char *FileName) +{ + char *Fname; + if ((Fname = strrchr(FileName, '\\')) == NULL) + if ((Fname = strrchr(FileName, ':')) == NULL) + Fname = FileName-1; + return Fname + 1; +} + +static char *ports[] = { + "Lpt1", "Lpt2", "Lpt3", + "Com1", "Com2", "Com3", "Com4", + NULL +}; + +static int PrintSetupProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn, i = 0, mar; + char marg[10]; + DFWINDOW cwnd; + + switch (msg) + { + case CREATE_WINDOW: + rtn = DefaultWndProc(wnd, msg, p1, p2); + PutItemText(wnd, ID_PRINTERPORT, cfg.PrinterPort); + while (ports[i] != NULL) + PutComboListText(wnd, ID_PRINTERPORT, ports[i++]); + for (mar = CHARSLINE; mar >= 0; --mar) + { + sprintf(marg, "%3d", mar); + PutItemText(wnd, ID_LEFTMARGIN, marg); + PutItemText(wnd, ID_RIGHTMARGIN, marg); + } + for (mar = LINESPAGE; mar >= 0; --mar) + { + sprintf(marg, "%3d", mar); + PutItemText(wnd, ID_TOPMARGIN, marg); + PutItemText(wnd, ID_BOTTOMMARGIN, marg); + } + cwnd = ControlWindow(&PrintSetup, ID_LEFTMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + CHARSLINE-cfg.LeftMargin, 0); + cwnd = ControlWindow(&PrintSetup, ID_RIGHTMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + CHARSLINE-cfg.RightMargin, 0); + cwnd = ControlWindow(&PrintSetup, ID_TOPMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + LINESPAGE-cfg.TopMargin, 0); + cwnd = ControlWindow(&PrintSetup, ID_BOTTOMMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + LINESPAGE-cfg.BottomMargin, 0); + return rtn; + case DFM_COMMAND: + if ((int) p1 == ID_OK && (int) p2 == 0) + { + GetItemText(wnd, ID_PRINTERPORT, cfg.PrinterPort, 4); + cwnd = ControlWindow(&PrintSetup, ID_LEFTMARGIN); + cfg.LeftMargin = CHARSLINE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + cwnd = ControlWindow(&PrintSetup, ID_RIGHTMARGIN); + cfg.RightMargin = CHARSLINE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + cwnd = ControlWindow(&PrintSetup, ID_TOPMARGIN); + cfg.TopMargin = LINESPAGE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + cwnd = ControlWindow(&PrintSetup, ID_BOTTOMMARGIN); + cfg.BottomMargin = LINESPAGE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + } + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +static void FixTabMenu(void) +{ + char *cp = GetCommandText(&MainMenu, ID_TABS); + char *p; + + if (cp != NULL) + { + p = strchr(cp, '('); + if (p != NULL) + { +// *(p+1) = (char)(cfg.Tabs + '0'); +// if (GetClass(inFocus) == POPDOWNMENU) +// DfSendMessage(inFocus, PAINT, 0, 0); + } + } +} + +void PrepFileMenu(void *w, struct Menu *mnu) +{ + DFWINDOW wnd = w; + DeactivateCommand(&MainMenu, ID_SAVE); + DeactivateCommand(&MainMenu, ID_SAVEAS); + DeactivateCommand(&MainMenu, ID_DELETEFILE); + DeactivateCommand(&MainMenu, ID_PRINT); + if (wnd != NULL && GetClass(wnd) == EDITBOX) + { + if (isMultiLine(wnd)) + { + ActivateCommand(&MainMenu, ID_SAVE); + ActivateCommand(&MainMenu, ID_SAVEAS); + ActivateCommand(&MainMenu, ID_DELETEFILE); + ActivateCommand(&MainMenu, ID_PRINT); + } + } +} + +void PrepSearchMenu(void *w, struct Menu *mnu) +{ + DFWINDOW wnd = w; + DeactivateCommand(&MainMenu, ID_SEARCH); + DeactivateCommand(&MainMenu, ID_REPLACE); + DeactivateCommand(&MainMenu, ID_SEARCHNEXT); + if (wnd != NULL && GetClass(wnd) == EDITBOX) + { + if (isMultiLine(wnd)) + { + ActivateCommand(&MainMenu, ID_SEARCH); + ActivateCommand(&MainMenu, ID_REPLACE); + ActivateCommand(&MainMenu, ID_SEARCHNEXT); + } + } +} + +void PrepEditMenu(void *w, struct Menu *mnu) +{ + DFWINDOW wnd = w; + DeactivateCommand(&MainMenu, ID_CUT); + DeactivateCommand(&MainMenu, ID_COPY); + DeactivateCommand(&MainMenu, ID_CLEAR); + DeactivateCommand(&MainMenu, ID_DELETETEXT); + DeactivateCommand(&MainMenu, ID_PARAGRAPH); + DeactivateCommand(&MainMenu, ID_PASTE); + DeactivateCommand(&MainMenu, ID_UNDO); + if (wnd != NULL && GetClass(wnd) == EDITBOX) + { + if (isMultiLine(wnd)) + { + if (TextBlockMarked(wnd)) + { + ActivateCommand(&MainMenu, ID_CUT); + ActivateCommand(&MainMenu, ID_COPY); + ActivateCommand(&MainMenu, ID_CLEAR); + ActivateCommand(&MainMenu, ID_DELETETEXT); + } + ActivateCommand(&MainMenu, ID_PARAGRAPH); + if (!TestAttribute(wnd, READONLY) && Clipboard != NULL) + ActivateCommand(&MainMenu, ID_PASTE); + if (wnd->DeletedText != NULL) + ActivateCommand(&MainMenu, ID_UNDO); + } + } +} + +/* EOF */ diff --git a/rosapps/dflat32/edit.txt b/rosapps/dflat32/edit.txt new file mode 100644 index 00000000000..bbe007ea727 --- /dev/null +++ b/rosapps/dflat32/edit.txt @@ -0,0 +1,1455 @@ +; ------------------------ MEMOPAD.TXT --------------------- +; +; This is the help text file for the MEMOPAD application. It +; includes the help text that a D-Flat application would use +; for the user interface. +; +; There can be a help window with a helptag name for each +; command in commands.h, each menu label on the menu bar +; as defined in menus.c, and each dialog box name in dialogs.c +; +; There can be other help windows as well. Some of them will +; be displayed as the result of hypertext and definition key +; words embedded in the help text of other help windows. Others +; can be implemented from within an application software system. +; +; Following is the format for a help window: +; +; ÚÄÄ (1st column of each line) +;  +; ; anything with a semicolon in the 1st column is a comment +; (names the help window) +; [<<] (names the previous window in chain) +; [>>] (names the next window in chain) +; Help Window Title (displays in window's title bar) +; Help text follows until next helptag occurs +; Hypertext reference [..keyword] embedded in text +; Definition reference [**keyword] embedded in text +; (names another window) +; +; Notes: +; 1. A hypertext reference, when selected, causes the +; associated help window named by the to +; become the active help window. +; 2. A definition reference, when selected, displays +; a momentary window with the text of the associated +; help window named by the . The window +; closes when the user releases the Enter key or +; mouse button. +; 3. A definition window has no title. +; 4. The last window is followed by the helptag. +; 5. The window's height and width adjust to the text. +; 6. The [..], [**], and do not display and +; do not figure in the width of the line in which +; they occur. +; +; ----------------------------------------- + +[<<] +[>>] +Application Window +The Application Window is the desktop for the +application. + +The Application window contains the application's +[..Document Windows]. Before you open any documents, +the Application window is empty. + +The application window has an [..Action Bar] just below +its [..Title Bar] and a [..Status Bar] at the bottom. + +Note that there might not be a title or status bar +depending on the [..Display] option on the [..Options] +menu. +; ----------------------------------------- + +[>>] +The MEMOPAD Application +MEMOPAD is a multi-window notepad program that +demonstrates the programmer's [**API] to the D-Flat +Common User Access interface library. +; ----------------------------------------- + +[<<] +The MEMOPAD Document Window +This [..Document Window] is a basic notepad text editor. You can +have many of these windows open at one time. +; ----------------------------------------- + +Document Window +A Document Window contains the data that you work +on. It displays within the [..Application Window] and +consists of these parts: + + [..Client Area] + [..Border] + [..Title Bar] + [..Status Bar] + [..Scroll Bars] + [..Control Box] + [..Minimize Box] + [..Maximize Box] + [..Restore Box] + [..Resize Box] + +; ----------------------------------------- + +[<<] +[>>] +Client Area +The Client Area is the space inside the window's +borders where the application's data values are +displayed and manipulated. +; ----------------------------------------- + +[<<] +[>>] +Border +The Border is the frame around a window. When the +window has the focus, the border is a double line. +When a different window has the focus, the border +is a single line. + +The window's [..Scroll Bars], if any, are positioned +in the right and bottom parts of the border. +; ----------------------------------------- + +[<<] +[>>] +Title Bar +The Title Bar is at the top of the window and +contains the window's title. When the window +has the focus, the title is highlighted. The +Title Bar includes these items as well: + + [..Control Box] + [..Minimize Box] + [..Maximize Box] + [..Restore Box] + +You can move the window with the mouse by clicking +the title bar and dragging the window to its new +location. +; ----------------------------------------- + +[<<] +[>>] +Status Bar +The Status Bar is at the bottom of the application window. +It displays the time and brief contextual messages about +the menus and other application-dependent features. +; ----------------------------------------- + +[<<] +[>>] +Scroll Bars +You use Scroll Bars to scroll a window's data with the +mouse. A window can have one or two Scroll Bars - one +at the right and one at the bottom parts of the +window's Border. The Scroll Bar at the right scrolls +the document's data up and down. The Scroll Bar on +the bottom scrolls the window's data right and left. + +To scroll a window a line at a time, click the arrow +tokens at either end of the Scroll Bar. The Scroll Bar +includes a slider box that indicates the relative +position of the window's display with respect to the +total document. You can page to an approximate position +within the document by clicking inside the Scroll Bar. +You can drag the slider box in either direction to +scroll the document. +; ----------------------------------------- + +[<<] +[>>] +Control Box +The Control Box is indicated by the character (ð) at +the left end of the window's [..Title Bar]. You can +click it to select the System Menu or double click +it to close the window. +; ----------------------------------------- + +[<<] +[>>] +Minimize Box +The Minimize Box is the  token at the right +end of the window's [..Title Bar]. + +When you click on the Minimize Box, the window +is reduced to an icon at the bottom of the +[..Application Window] +; ----------------------------------------- + +[<<] +[>>] +Maximize Box +The Maximize Box is the  token at the right +end of the window's [..Title Bar]. + +When you click on the Maximize Box, the window +grows to occupy the entire [..Client Area] of the +[..Application Window] +; ----------------------------------------- + +[<<] +[>>] +Restore Box +The Restore Box is the  token character at the right +end of a minimized window's [..Title Bar] and the  token +character at the right end of a maximized window's +Title Bar. You click the Restore Box to restore the +window to the position and size it had before it was +minimized or maximized. +; ----------------------------------------- + +[<<] +Resize Box +The Resize Box is the lower right corner of the +window's border. To change the window's size, +drag the Resize Box. The window's upper left +coordinates remain the same, and the lower right +coordinates change as you drag the mouse around. +; ----------------------------------------- + +[<<] +[>>] +The Action Bar +To select the action bar, do one of these: + 1. Press F10 + 2. Press and release the Alt key + 3. Press Alt+the letter that is highlighted + in a menu's title on the action bar. The + selected menu will pull down. + 4. Click the action bar. If you click a + pull-down menu selection's title, that + menu will pull down. + +To exit from the action bar and return to the +document or application window, do one of these: + 1. Press Esc + 2. Press and release the Alt key +; ----------------------------------------- +; +; Following are the Help system windows +; +; ----------------------------------------- + +[<<] +[>>] +Help for Help +Getting Into the Help System +---------------------------- +There are three ways to get into the Help system: + + 1. Execute commands on the [..Help] menu + 2. Press F1 + 3. Press the Help command button on a dialog box. + +Contextual Help (F1) +-------------------- +The F1 key provides contextual help--help for the +part of the application that currently has the +focus. You can press F1 with the action bar selected, +a pull-down menu displayed, a field on a dialog box +selected, or a document window in focus. + +The Help Command Button +----------------------- +The Help command button on a dialog box displays +information about the dialog box and its purpose. +The help window that displays when you press F1 with +a dialog box field selected relates to the field +itself. + +References to Other Help Windows +-------------------------------- +A Help window can include a reference to another +help window. That reference is highlighted like +this: + + [..Help] + +You can Tab to the highlighted reference and press +the Enter key to select the referenced help window. +You can select it with the mouse by double-clicking +on it. + +Definitions +----------- +Some references, such as [**function key], are +definitions of terms. These definitions are +highlighted the same as references. When you select +the definition, a window displays in the upper left +corner of the desktop. The window contains the +definition of the selected term and stays in view +until you release the Enter key or the mouse +button. + +Command Buttons on the Help Windows +----------------------------------- +Each help window contains these [..command buttons]: + + Close This button closes the help window and + exits from the help system. + Back This button changes to the help window + that you viewed before the current one. + Prev This button changes to the help window + that logically preceeds the current one. + Next This button changes to the help window + that logically follows the current one. + +Exiting from the Help System +---------------------------- +You exit from the Help system by closing the current +help window in one of these three ways: + + 1. Press the Esc key + 2. Use the Close command button on the Help + window. + 5. Double click the window's [..Control Box]. + 4. Close the help window from its [..System Menu]. + +; ----------------------------------------- + +[<<] +[>>] +Extended Help +The MEMOPAD program has few features and procedures +that are not taken directly from the SAA/CUA +interface that D-Flat implements. The [..Log Messages] +and [..Display] selections on the [..Options] menu are +unique to MEMOPAD and would not necessarily be in +an application. Some of the Display features would +be useful to a user who is not developing D-Flat +programs. Others, such as the [..Title], [..Border], +[..Status Bar], and [..Texture] check boxes on the [..Display] +dialog box, are to allow a programmer to see how +the screen looks with these features enabled and +disabled. +; ----------------------------------------- + +[<<] +[>>] +Keys Help +From the Desktop +---------------- + Alt+Hyphen Open the desktop's [..SystemMenu]. + F10 or Alt Activate the [..ActionBar]. + Esc Deactivate the Action Bar. + Alt+letter Open the associated [..Pull-down menu]. + Alt+F6 Change focus to another document. + Alt+X Exit the application. + +From a [..Document Window] +---------------------- + Alt+Spacebar Open the window's [..System Menu] + Alt+S Save the document to a disk file. + +[..Edit Box] Keys +----------- + Arrow keys Move the cursor one character. + Ctrl+arrow Move the cursor one word. + Del Delete character to the right of + the cursor. If a [..block] is marked, + delete the block. + Backspace Delete character to the left of + the cursor. If a block is marked, + delete the block. + Alt+BackSpace Undo the last block deletion. + PgUp/PgDn Scroll forward and back one page. + Ctrl+PgUp/PgDn Scroll horizontally one page. + Home/End Move the cursor to the beginning + and end of the line. + Ctrl+Home/End Move the cursor to the beginning + and end of the document. + Alt+P Form a paragraph from the cursor + position to the next blank line. + Ins Toggle Insert/Overstrike mode. + Tab Tab to the next Tab Stop position. + +[..Clipboard] Keys +-------------- + Shift+Del [..Cut] the marked text to the + Clipboard + Ctrl+Ins [..Copy] the marked text to the + Clipboard. + Shift+Ins [..Paste] the contents of the + Clipboard into the document. + +[..Dialog Box] Keys +--------------- + Tab Move to the next control. + Shift+Tab Move to the previous control. + Enter Execute the control. + Esc Close the Dialog Box with no + action. + +[..Listbox] Keys +------------ + Up/down arrows Move the selection cursor + Ctrl+arrows Select a group of entries. + Enter Choose the selected entry + or entries. + Shift+F8 Toggle Add mode. + Spacebar In Add mode, select/deselect an + entry. +; ----------------------------------------- + +[<<] +Index of Help Titles +Select (Tab then Enter or double-click) from these +titles to view the help screens related to each one. + + [..Application Window] + [..Action Bar] + [..Pull-down Menus] + [..The File Menu] + [..The Edit Menu] + [..The Search Menu] + [..The Utilities Menu] + [..The Options Menu] + [..The Window Menu] + [..The Help Menu] + [..Dialog Boxes] + [..The File Open Dialog Box] + [..The Save As Dialog Box] + [..The MsgBox Dialog Box] + [..The Display Dialog Box] + [..The Windows Dialog Box] + [..The Log Dialog Box] + [..The Help System] + [..Help for help...] + [..Extended help...] + [..Keys help...] + [..Help index...] + [..Reload Help Database] + +; ----------------------------------------- +; +; Following are menu command help windows +; +; ----------------------------------------- + +[<<] +[>>] +The New Command +This command opens a new, untitled document +window. An untitled document is one that has +not been given a file name. When you use the +[..Save] or [..Save as] command on the File menu the +document gets a file name. +; ----------------------------------------- + +[<<] +[>>] +The Open Command +This command opens an existing document and loads +it into a window. You select the document by filling +in the [..File Open] dialog box. +; ----------------------------------------- + +[<<] +[>>] +The Save Command +This command saves the document in the currently +active document window into a disk file. The file +name is the same as when the file was loaded. If +the window contains an untitled document, this +command works just like the [..Save as] command. +; ----------------------------------------- + +[<<] +[>>] +The Save As Command +This command allows you to save the document in the +currently active document window under a new file +name. You specify the file's name by filling in the +fields on the [..Save as] dialog box. + +The new file name becomes the title of the +currently active document window where the file is +displayed. +; ----------------------------------------- + +[<<] +[>>] +The Delete Command +Use this command to delete the text file displayed +in the active editbox window. +; ----------------------------------------- + +[<<] +[>>] +The Print Command +This command prints the document in the +currently-selected document window. +; ----------------------------------------- + +[<<] +[>>] +The Print Setup Command +This command displays the [..Print Setup] dialog +box to allow you to change the printer port +and margins for the printout. +; ----------------------------------------- + +[<<] +[>>] +The DOS Command +This command "shells" out to DOS. You return to the +application from DOS by executing the DOS exit +command at the DOS command line. +; ----------------------------------------- + +[<<] +The Exit Command +This command exits to DOS from the application. If +there are any changed documents that you have not +saved, the program will ask if you want to save +them and allow you to do so, one at a time. +; ----------------------------------------- + +[<<] +[>>] +The Undo Command +This command "undoes" the most recent [..Delete] or +[..Clear] command. The text that was deleted by one of +these commands is written into the document at the +current cursor location. +; ----------------------------------------- + +[<<] +[>>] +The Cut Command +This command is active only when the current +document window has a [..marked block]. The command +deletes the text in the marked block, copies it to +the [..Clipboard], and closes up the space in the +document that the text previously occupied. +; ----------------------------------------- + +[<<] +[>>] +The Copy Command +This command is active only when the current +document window has a [..marked block]. The command +copies the text in the marked block to the +[..Clipboard], and closes up the space in the document +that the text previously occupied. +; ----------------------------------------- + +[<<] +[>>] +The Paste Command +This command is active only when the [..Clipboard] +contains text. The command inserts the text from the +Clipboard into the currently active document window +at the current cursor location. +; ----------------------------------------- + +[<<] +[>>] +The Clear Command +This command is active only when the current +document window has a [..marked block]. The command +deletes the block of text, leaving empty space in +the document where the text had been. + +You can undo the text deletion with the +[..Undo] command. +; ----------------------------------------- + +[<<] +[>>] +The Delete Command +This command is active only when the current +document window has a [..marked block]. The command +deletes the block of text, closing the space in the +document where the text had been. + +You can undo the text deletion with the +[..Undo] command. +; ----------------------------------------- + +[<<] +The Paragraph Command +This command reforms a paragraph beginning at the +current keyboard cursor position. The end of the +paragraph is the last line preceding the next blank +line. +; ----------------------------------------- + +[<<] +[>>] +The Search Command +This command opens the [..Search Text] Dialog Box to +allow you to search the text for a +matching string. +; ----------------------------------------- + +[<<] +[>>] +The Replace Command +This command opens the [..Replace Text] Dialog Box to +allow you to search the text for a +matching string and replace it with a +different text string. +; ----------------------------------------- + +[<<] +The Next Command +This command continues the most recent [..Search] +command beginning at the current cursor position. +; ----------------------------------------- + +[<<] +[>>] +The Insert Toggle +This [**toggle] command turns the editor's insert mode +on and off. When insert mode is on, the editor +inserts the text that you write. Otherwise each +character typed overwrites the one at the current +cursor position. +; ----------------------------------------- + +[<<] +[>>] +The Word Wrap Toggle +This [**toggle] command turns the editor's word wrap +feature on and off. When word wrap is on, the editor +will wrap words as you type at the right margin of +the document window. When word wrap is off, the +editor will scroll the display horizontally as you +type beyond the right margin. +; ----------------------------------------- + +[<<] +[>>] +The Tabs Command +This command allows you to +change the editor's tab settings. +; ----------------------------------------- + +[<<] +[>>] +The Display Command +This command displays the [..Display] dialog box to +allow you to modify the screen's colors and +configuration. +; ----------------------------------------- + +[<<] +[>>] +The Log Messages Command +This command is used primarily for debugging. It +opens the [..Log Message] dialog box to allow the +programmer to select the D-Flat messages to log and +to turn message logging on and off. +; ----------------------------------------- + +[<<] +The Save Options Command +This command saves the current options in a +configuration file that the application reads when +it first starts up. +; ----------------------------------------- + +[<<] +[>>] +The Close All Command +This command closes all the document windows on the +desktop. +; ----------------------------------------- + +[<<] +[>>] +The Open Window List +The [..Window] menu displays a list of open document +windows. You can select one of them as the current +active window by selecting its title on the Window +menu. When the menu first displays, the active +window has a check mark (û) next to it. + +[<<] +More Windows +This command indicates that there are more open document +windows than the [..Window] menu can display. +Choose this command to see the [..Windows] dialog box. +; ----------------------------------------- + +[<<] +[>>] +Help for Help +This command describes how to use the Help system. +; ----------------------------------------- + +[<<] +[>>] +Extended Help +Extended Help displays information about the +application. +; ----------------------------------------- + +[<<] +[>>] +Keys Help +This command displays a help window that shows the +keystrokes that you use to operate the application. +; ----------------------------------------- + +[<<] +[>>] +Help Index +The Help index lists the subjects covered in the +Help database. You can go directly to a subject from +the index by selecting the subject's name. +; ----------------------------------------- + +[<<] +[>>] +Reload Help Database +This command allows you to reload the Help +database. It is useful when you use the +Memopad program to modify its Help database. +You can change and save the MEMOPAD.TXT file, +use this command to reload it, then use the +Help system to view the results. Without this +command, your changes would corrupt the +current Memopad's picture of the database +with respect to its pointers. + +You must delete the MEMOPAD.HLP compressed +help database in order for this program to +load the most recent changes. +; ----------------------------------------- + +[<<] +The About Command +This command displays a message that tells you what +the application is. +; ----------------------------------------- + +[>>] +The Filename Field + +On the Open File dialog box: + Enter the name of the file you wish to + open into a document window, or enter + the file specification with wild cards + to display a list of files in the + [..Files] field. + +On the Save As dialog box: + Enter the name with which you wish to + save the file. +; ----------------------------------------- + +[<<] +[>>] +The Files Field +Select a file from the listbox by using one +of these methods: + +Keyboard: Move the selection cursor to + the file name and press Enter. + +Mouse: Double-click the file name. +; ----------------------------------------- + +[<<] +The Directories Field +Use this listbox to select a different +drive or subdirectory. Select a drive or +subdirectory from the listbox by using one +of these methods: + +Keyboard: Move the selection cursor to + the drive or subdirectory and + press Enter. + +Mouse: Double-click the drive or + subdirectory. +; ----------------------------------------- + +[<<] +[>>] +The Printer Port Combo Box +Use this combo box to change the printer +port and to set the report's margins. +; ----------------------------------------- + +[<<] +[>>] +The Left Margin Spin Button +Change the left margin by increasing +and decreasing the value in this +spin box. +; ----------------------------------------- + +[<<] +[>>] +The Right Margin Spin Button +Change the right margin by increasing +and decreasing the value in this +spin box. +; ----------------------------------------- + +[<<] +[>>] +The Top Margin Spin Button +Change the top margin by increasing +and decreasing the value in this +spin box. +; ----------------------------------------- + +[<<] +The Bottom Margin Spin Button +Change the bottom margin by increasing +and decreasing the value in this +spin box. +; ----------------------------------------- + +[>>] +The Search For Text Entry Box +Enter the text you want to search for in this +text box. Press Enter or the OK command button +to begin the search. Press Esc to forget it. +Use the [..Match Upper/Lower Case Check Box] to +select whether the search will match only if +the case matches or if the search is insensitive +to the case of the two strings. +; ----------------------------------------- + +[<<] +[>>] +The Replace With Text Entry Box +Enter the text string that will replace +the matching text string in the +[..Search For Text Entry Box]. +; ----------------------------------------- + +[<<] +[>>] +The Match Upper/Lower Case Check Box +Use this checkbox to select whether the search +will match only if the case matches or if the +search is insensitive to the case of the two +strings. +; ----------------------------------------- + +[<<] +The Replace Every Match Check Box +Use this checkbox to select whether the search +will replace every match in the document. +; ----------------------------------------- + +[<<] +[>>] +The Title Check Box +Select this Check Box to toggle the application +window's title on and off. Without a title, the +window also loses its [..Control Box]. +; ----------------------------------------- + +[<<] +[>>] +The Border Check Box +Select this Check Box to toggle the application +window's border on and off. Without a border, the +window also loses its [..Status Bar]. +; ----------------------------------------- + +[<<] +[>>] +The Status Bar Check Box +Select this Check Box to toggle the application +window's [..Status Bar] on and off. +; ----------------------------------------- + +[<<] +[>>] +The Texture Check Box +Select this Check Box to toggle the application +window's background texture on and off. +; ----------------------------------------- + +[<<] +[>>] +The Color Option Button +Select this option for a color display. +; ----------------------------------------- + +[<<] +[>>] +The Mono Option Button +Select this option for a monochrome display. +; ----------------------------------------- + +[<<] +[>>] +The Reverse Option Button +Select this option for a reverse monochrome +display. You might find that this option +works well with the LCD screens of some laptop +computers, particularly when you turn off the +[..Texture] check box. +; ----------------------------------------- + +[<<] +[>>] +The 25 Lines Option Button +Use this button to select a 25-line display. +; ----------------------------------------- + +[<<] +[>>] +The 43 Lines Option Button +Use this button to select a 43-line display. +(EGA and VGA) +; ----------------------------------------- + +[<<] +[>>] +The 50 Lines Option Button +Use this button to select a 50-line display. +(VGA only) +; ----------------------------------------- + +[<<] +Snowy Display +Select this check box if your display +(usually a CGA) displays video snow when +you change the screen. +; ----------------------------------------- + +[<<] +[>>] +The Messages Listbox +This is a list of D-Flat messages that +you can log when the [..Logging] checkbox is +selected. The list is a [..Multiple-Selection] +listbox. +; ----------------------------------------- + [<<] The Logging +CheckBox This checkbox turns message +logging on and off. ; +----------------------------------------- + The TEXTBOX Window Class + + ======== Text needed ========= + +; ----------------------------------------- + +The LISTBOX Window Class + + ======== Text needed ========= + +; ----------------------------------------- + +The EDITBOX Window Class + + ======== Text needed ========= + +; ----------------------------------------- + +[<<] +[>>] +Pull-down Menus +Pull-down menus contain the commands to operate +the program. Read about the [..Action Bar] to see +how to select the pull-down menus. Following +is a list of the pull-down menus. + + [..The File Menu] + [..The Edit Menu] + [..The Search Menu] + [..The Options Menu] + [..The Window Menu] + [..The Help Menu] + +The [..System Menu] is another kind of pull-down menu. +; ----------------------------------------- + +[<<] +[>>] +The File Menu +The File menu contains commands that +open, save, and print files. The menu +also has the command that exits the +program. Following are the commands +and associated [**function keys]. + + [..New] + [..Open] + [..Save] (Alt+S) + [..Save as] + [..Print] + [..Exit] (Alt+X or Alt+F4) + +[**Inactive] commands display in a dim font. +; ----------------------------------------- + +[<<] +[>>] +The Edit Menu +The Edit menu contains commands that support +text editing. Following are the commands and +associated [**function keys]. + + [..Undo] (Alt+BS) + [..Cut] (Shift+Del) + [..Copy] (Ctrl+Ins) + [..Paste] (Shift+Ins) + [..Clear] + [..Delete] (Del) + [..Paragraph] (Alt+P) + +[**Inactive] commands display in a dim font. +; ----------------------------------------- + +[<<] +[>>] +The Search Menu +The Search menu allows you to search the text +for a matching string. The commands are: + + [..Search] + [..Next] (F3) +; ----------------------------------------- + +[<<] +[>>] +The Utilities Menu +The Utilities Menu has two commands that +demonstrate the use of the PICTUREBOX window +class. The commands are: + + [..Calendar] + [..Bar Chart] +; ----------------------------------------- + +[<<] +[>>] +The Options Menu +The Options menu contains commands that let you +control the editor's behavior, the video display +characteristics, and whether to [**log] messages. +You can save the options in a configuration file. +Following are the commands on the Options menu. + + [..Insert] (Ins) + [..Word wrap] + [..Tabs] + [..Display] + [..Log Messages] + [..Save Options] +; ----------------------------------------- + +[<<] +[>>] +The Window Menu +The Window menu has no selections unless the +[..Application window] has one or more document +windows displayed. When documents are displayed, +the Window menu contains a [..Close All] command +and an entry for the first nine document windows. +You can select a document window from the Window +menu. If the Application window has more than nine +document windows, the Window menu has the [**More Windows] +command, which displays the [..Windows] dialog box. +; ----------------------------------------- + +[<<] +The Help Menu +The Help menu provides information about the +application and the desktop. The selections are: + + [..Help for help...] + [..Extended help...] + [..Keys help...] + [..Help index...] + [..About...] + +; ----------------------------------------- + +[<<] +[>>] +The System Menu +Most windows have a system menu. If the window has a +System Menu, the window will have a [..Control Box]. You +can select the System Menu by clicking the control +box or by pressing Alt+Spacebar for the application +window's system menu and Alt+Hyphen for the system +menu of other windows. + +Following are the commands on the System Menu: + + [..Restore] + [..Move] + [..Size] + [..Minimize] + [..Maximize] + [..Close] + +; ----------------------------------------- + +[<<] +[>>] +The Restore Command on the System Menu +This command restores a [..Minimized] or [..Maximized] +window to the size and position it had before it +was minimized or maximized. + +You can also restore a minimized or maximized +window by clicking its [..Restore Box]. +; ----------------------------------------- + +[<<] +[>>] +The Move Command on the System Menu +The Move command lets you move a window with the +keyboard. Select the command from the System Menu. A +movable window frame comes into view over the +window's border. Use the up, down, left, and right +arrow keys to move the frame to the new window +position. Press the Enter key when the movable frame +is where you want to move the window. Press the Esc +key to ignore the movement. + +You can move a window with the mouse by clicking on +the window's [..Title Bar] and dragging the window to +the new location. +; ----------------------------------------- + +[<<] +[>>] +The Size Command on the System Menu +The Size command lets you re-size a window with the +keyboard. Select the command from the System Menu. +A sizeable window frame comes into view over the +window's border. Use the up, down, left, and right +arrow keys to change the frame to the new window +size. Press the Enter key when the sizeable frame +is the size you want for the window. Press the Esc +key to ignore the size change. + +You can re-size a window with the mouse by clicking +on the window border's [..Resize Box] and dragging the +window to the new size. +; ----------------------------------------- + +[<<] +[>>] +The Minimize Command on the System Menu +This command minimizes the window to an icon at the +bottom of the application window. + +You can minimize a window with the mouse by clicking +on the window's [..Minimize Box]. + +The [..Restore] command restores a minimized window to +the size and position it had before it was +minimized. +; ----------------------------------------- + +[<<] +[>>] +The Maximize Command on the System Menu +This command maximizes the window to occupy all of +the application window's client area. + +You can maximize a window with the mouse by clicking +on the window's [..Maximize Box]. + +The [..Restore] command restores a maximized window to +the size and position it had before it was +maximized. +; ----------------------------------------- + +[<<] +The Close Command on the System Menu +This command closes the window with which the System +Menu is associated. + +You can also close the window by double-clicking the +[..Control Box] or pressing Ctrl+F4. +; ----------------------------------------- +; +; Following are dialog box help windows +; +; ----------------------------------------- + +[>>] +Dialog Boxes +Dialog Boxes allow you to enter data into the +application. A Dialog Box consists of these +controls: + + [..Command Buttons] + [..Check Boxes] + [..Option Buttons] + [..Edit Boxes] + [..List Boxes] + [..Multiple-Selection Listboxes] + [..Combo Boxes] + [..Spin Buttons] + +Move from control to control by using the Tab key +or by pressing Alt+ the highlighted character in +the control's label. Execute a control by pressing +the Enter key. + +Exit the Dialog Box and accept its data entries by +executing the OK command button. + +Exit the Dialog Box and reject its data entries by +executing the Cancel command button. +; ----------------------------------------- + +[<<] +[>>] +Command Buttons +Select a command button to execute its +command by using one of these procedures: + + 1. Click the button. + 2. Press Alt+ the shortcut key. + 3. Tab to the button and press Enter. +; ----------------------------------------- + +[<<] +[>>] +Check Boxes +A check box can be on [X] or off [ ]. +Toggle the check box with one of these +procedures: + + 1. Click the check box. + 2. Press Alt+ the shortcut key. +; ----------------------------------------- + +[<<] +[>>] +Option Buttons +Option buttons are in groups of 2 or +more. One option button in a group +is on () and the others are off ( ). +Select the option button with one of +these procedures: + + 1. Click the option button. + 2. Press Alt+ the shortcut key. +; ----------------------------------------- + +[<<] +[>>] +Edit Boxes + + ======== Text needed ========= + +; ----------------------------------------- + +[<<] +[>>] +List Boxes + + ======== Text needed ========= + +; ----------------------------------------- + +[<<] +[>>] +Multiple-Selection Listboxes + + ======== Text needed ========= + +; ----------------------------------------- + +[<<] +[>>] +Combo Boxes + + ======== Text needed ========= + +; ----------------------------------------- + +[<<] +Spin Buttons + + ======== Text needed ========= + +; ----------------------------------------- + +The File Open Dialog Box + + ======== Text needed ========= + +; ----------------------------------------- + +The Save As Dialog Box + + ======== Text needed ========= + +; ----------------------------------------- + +The Print Setup Dialog Box + + ======== Text needed ========= + +; ----------------------------------------- + +The Search Text Dialog Box + + ======== Text needed ========= + +; ----------------------------------------- + +The Replace Text Dialog Box + + ======== Text needed ========= + +; ----------------------------------------- + +The MsgBox Dialog Box + + ======== Text needed ========= + +; ----------------------------------------- + +The Display Dialog Box + + ======== Text needed ========= + + [..Title] + [..Border] + [..Status Bar] + [..Texture] + + [..Color] + [..Mono] + [..Reverse] + +; ----------------------------------------- + +The Windows Dialog Box +This dialog box lists all the open windows. +Select one and choose OK to make that window +the active one. +; ----------------------------------------- + +The Log Message Dialog Box + + ======== Text needed ========= + +; ----------------------------------------- +; +; Following are keyword reference definition windows +; +; ----------------------------------------- + +An inactive menu command is one that is, for +the moment, not available. The command becomes +active at another time when conditions within +the program require or permit its use. +; ----------------------------------------- + +Function keys are key combinations that +you can press to execute a menu command +without selecting the pull-down menu +itself. Not all menu commands have +function keys. The most frequently used +operations do. +; ----------------------------------------- + +The message log is a debug tool. You should +delete it from the system by turning off the +INCLUDE_LOGGING global definition in dflat.h. +You should then eliminate references to it in +the MEMOPAD.TXT help database. +; ----------------------------------------- + +A menu can have only so many selections. +The length of the screen is the limiting +factor. The CUA standard defines nine +windows as the maximum number of windows +that the Window menu can display. The +Windows menu has the More Windows command +to provide a way for you to choose from +the rest of the document windows. +; ----------------------------------------- + +Applications Program Interface (API): +The functions, messages, macros, and +data structures that a programmer +uses to interface with the processes +of a function library. +; ----------------------------------------- + +Marking Text Blocks +Marked text blocks affect the operation of these +commands: + + [..Cut] + [..Copy] + [..Paste] + [..Clear] + [..Delete] + [..Paragraph] + +Mark a text block by using one of these operations: + + Keyboard: + --------- + Hold the Shift key down and move the + keyboard cursor. The block will be marked in + reverse video. + + To clear the marked block, release the Shift + key and press any text entry or cursor movement + key. + + Mouse: + ------ + Click on the first or last character of the + block. Hold the mouse button down and move + the mouse cursor around. The marked block + will follow the mouse cursor. + + To clear the marked block, release the mouse + cursor and click anywhere. + +; ----------------------------------------- + +The Clipboard +The Clipboard is a scratchpad where you can save +text that can be pasted into a different location +in the same or another document. You save text with +the [..Copy] and [..Cut] commands, and you paste text into +from the Clipboard into a document with the [..Paste] +command. +; ----------------------------------------- + +A toggle command is one that is +either on or off. When it is on, +its command on the menu is preceded +by a check mark (û). + +Calendar +This command displays a calendar to demonstrate +the use of the PICTUREBOX class to draw line +vectors. + +Bar Chart +This command displays a bar chart to demonstrate +the use of the PICTUREBOX class to draw bars. + +Calendar +This calendar is an example of a picture box +with line vectors. The PgUp and PgDn keys +will page through the months. You can close +the window from the [..System Menu]. + +Bar Chart +This window is an example of a bar chart. You +can close the window from the [..System Menu]. + diff --git a/rosapps/dflat32/editbox.c b/rosapps/dflat32/editbox.c new file mode 100644 index 00000000000..cb7dc4731d7 --- /dev/null +++ b/rosapps/dflat32/editbox.c @@ -0,0 +1,1113 @@ +/* ------------- editbox.c ------------ */ +#include "dflat.h" + +#define EditBufLen(wnd) (isMultiLine(wnd) ? EDITLEN : ENTRYLEN) +#define SetLinePointer(wnd, ln) (wnd->CurrLine = ln) +#define isWhite(c) ((c)==' '||(c)=='\n') +/* ---------- local prototypes ----------- */ +static void SaveDeletedText(DFWINDOW, char *, int); +static void Forward(DFWINDOW); +static void Backward(DFWINDOW); +static void End(DFWINDOW); +static void Home(DFWINDOW); +static void Downward(DFWINDOW); +static void Upward(DFWINDOW); +static void StickEnd(DFWINDOW); +static void NextWord(DFWINDOW); +static void PrevWord(DFWINDOW); +static void ModTextPointers(DFWINDOW, int, int); +static void SetAnchor(DFWINDOW, int, int); +/* -------- local variables -------- */ +static BOOL KeyBoardMarking, ButtonDown; +static BOOL TextMarking; +static int ButtonX, ButtonY; +static int PrevY = -1; + +/* ----------- CREATE_WINDOW Message ---------- */ +static int CreateWindowMsg(DFWINDOW wnd) +{ + int rtn = BaseWndProc(EDITBOX, wnd, CREATE_WINDOW, 0, 0); + wnd->MaxTextLength = MAXTEXTLEN+1; + wnd->textlen = EditBufLen(wnd); + wnd->InsertMode = TRUE; + DfSendMessage(wnd, CLEARTEXT, 0, 0); + return rtn; +} +/* ----------- SETTEXT Message ---------- */ +static int SetTextMsg(DFWINDOW wnd, PARAM p1) +{ + int rtn = FALSE; + if (strlen((char *)p1) <= wnd->MaxTextLength) + rtn = BaseWndProc(EDITBOX, wnd, SETTEXT, p1, 0); + return rtn; +} +/* ----------- CLEARTEXT Message ------------ */ +static int ClearTextMsg(DFWINDOW wnd) +{ + int rtn = BaseWndProc(EDITBOX, wnd, CLEARTEXT, 0, 0); + unsigned blen = EditBufLen(wnd)+2; + wnd->text = DFrealloc(wnd->text, blen); + memset(wnd->text, 0, blen); + wnd->wlines = 0; + wnd->CurrLine = 0; + wnd->CurrCol = 0; + wnd->WndRow = 0; + wnd->wleft = 0; + wnd->wtop = 0; + wnd->textwidth = 0; + wnd->TextChanged = FALSE; + return rtn; +} +/* ----------- ADDTEXT Message ---------- */ +static int AddTextMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int rtn = FALSE; + if (strlen((char *)p1)+wnd->textlen <= wnd->MaxTextLength) { + rtn = BaseWndProc(EDITBOX, wnd, ADDTEXT, p1, p2); + if (rtn != FALSE) { + if (!isMultiLine(wnd)) { + wnd->CurrLine = 0; + wnd->CurrCol = strlen((char *)p1); + if (wnd->CurrCol >= ClientWidth(wnd)) { + wnd->wleft = wnd->CurrCol-ClientWidth(wnd); + wnd->CurrCol -= wnd->wleft; + } + wnd->BlkEndCol = wnd->CurrCol; + DfSendMessage(wnd, KEYBOARD_CURSOR, + WndCol, wnd->WndRow); + } + } + } + return rtn; +} +/* ----------- GETTEXT Message ---------- */ +static int GetTextMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + char *cp1 = (char *)p1; + char *cp2 = wnd->text; + if (cp2 != NULL) { + while (p2-- && *cp2 && *cp2 != '\n') + *cp1++ = *cp2++; + *cp1 = '\0'; + return TRUE; + } + return FALSE; +} +/* ----------- SETTEXTLENGTH Message ---------- */ +static int SetTextLengthMsg(DFWINDOW wnd, unsigned int len) +{ + if (++len < MAXTEXTLEN) { + wnd->MaxTextLength = len; + if (len < wnd->textlen) { + wnd->text=DFrealloc(wnd->text, len+2); + wnd->textlen = len; + *((wnd->text)+len) = '\0'; + *((wnd->text)+len+1) = '\0'; + BuildTextPointers(wnd); + } + return TRUE; + } + return FALSE; +} +/* ----------- KEYBOARD_CURSOR Message ---------- */ +static void KeyboardCursorMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + wnd->CurrCol = (int)p1 + wnd->wleft; + wnd->WndRow = (int)p2; + wnd->CurrLine = (int)p2 + wnd->wtop; + if (wnd == inFocus) { + if (CharInView(wnd, (int)p1, (int)p2)) + DfSendMessage(NULL, SHOW_CURSOR, + (wnd->InsertMode && !TextMarking), 0); + else + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + } +} +/* ----------- SIZE Message ---------- */ +int SizeMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int rtn = BaseWndProc(EDITBOX, wnd, DFM_SIZE, p1, p2); + if (WndCol > ClientWidth(wnd)-1) + wnd->CurrCol = ClientWidth(wnd)-1 + wnd->wleft; + if (wnd->WndRow > ClientHeight(wnd)-1) { + wnd->WndRow = ClientHeight(wnd)-1; + SetLinePointer(wnd, wnd->WndRow+wnd->wtop); + } + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + return rtn; +} +/* ----------- SCROLL Message ---------- */ +static int ScrollMsg(DFWINDOW wnd, PARAM p1) +{ + int rtn = FALSE; + if (isMultiLine(wnd)) { + rtn = BaseWndProc(EDITBOX,wnd,SCROLL,p1,0); + if (rtn != FALSE) { + if (p1) { + /* -------- scrolling up --------- */ + if (wnd->WndRow == 0) { + wnd->CurrLine++; + StickEnd(wnd); + } + else + --wnd->WndRow; + } + else { + /* -------- scrolling down --------- */ + if (wnd->WndRow == ClientHeight(wnd)-1) { + if (wnd->CurrLine > 0) + --wnd->CurrLine; + StickEnd(wnd); + } + else + wnd->WndRow++; + } + DfSendMessage(wnd,KEYBOARD_CURSOR,WndCol,wnd->WndRow); + } + } + return rtn; +} +/* ----------- HORIZSCROLL Message ---------- */ +static int HorizScrollMsg(DFWINDOW wnd, PARAM p1) +{ + int rtn = FALSE; + char *currchar = CurrChar; + if (!(p1 && + wnd->CurrCol == wnd->wleft && *currchar == '\n')) { + rtn = BaseWndProc(EDITBOX, wnd, HORIZSCROLL, p1, 0); + if (rtn != FALSE) { + if (wnd->CurrCol < wnd->wleft) + wnd->CurrCol++; + else if (WndCol == ClientWidth(wnd)) + --wnd->CurrCol; + DfSendMessage(wnd,KEYBOARD_CURSOR,WndCol,wnd->WndRow); + } + } + return rtn; +} +/* ----------- SCROLLPAGE Message ---------- */ +static int ScrollPageMsg(DFWINDOW wnd, PARAM p1) +{ + int rtn = FALSE; + if (isMultiLine(wnd)) { + rtn = BaseWndProc(EDITBOX, wnd, SCROLLPAGE, p1, 0); + SetLinePointer(wnd, wnd->wtop+wnd->WndRow); + StickEnd(wnd); + DfSendMessage(wnd, KEYBOARD_CURSOR,WndCol, wnd->WndRow); + } + return rtn; +} +/* ----------- HORIZSCROLLPAGE Message ---------- */ +static int HorizPageMsg(DFWINDOW wnd, PARAM p1) +{ + int rtn = BaseWndProc(EDITBOX, wnd, HORIZPAGE, p1, 0); + if ((int) p1 == FALSE) { + if (wnd->CurrCol > wnd->wleft+ClientWidth(wnd)-1) + wnd->CurrCol = wnd->wleft+ClientWidth(wnd)-1; + } + else if (wnd->CurrCol < wnd->wleft) + wnd->CurrCol = wnd->wleft; + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + return rtn; +} +/* ----- Extend the marked block to the new x,y position ---- */ +static void ExtendBlock(DFWINDOW wnd, int x, int y) +{ + int bbl, bel; + int ptop = min(wnd->BlkBegLine, wnd->BlkEndLine); + int pbot = max(wnd->BlkBegLine, wnd->BlkEndLine); + char *lp = TextLine(wnd, wnd->wtop+y); + int len = (int) (strchr(lp, '\n') - lp); + x = max(0, min(x, len)); + y = max(0, y); + wnd->BlkEndCol = min(len, x+wnd->wleft); + wnd->BlkEndLine = y+wnd->wtop; + DfSendMessage(wnd, KEYBOARD_CURSOR, wnd->BlkEndCol, wnd->BlkEndLine); + bbl = min(wnd->BlkBegLine, wnd->BlkEndLine); + bel = max(wnd->BlkBegLine, wnd->BlkEndLine); + while (ptop < bbl) { + WriteTextLine(wnd, NULL, ptop, FALSE); + ptop++; + } + for (y = bbl; y <= bel; y++) + WriteTextLine(wnd, NULL, y, FALSE); + while (pbot > bel) { + WriteTextLine(wnd, NULL, pbot, FALSE); + --pbot; + } +} +/* ----------- LEFT_BUTTON Message ---------- */ +static int LeftButtonMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int MouseX = (int) p1 - GetClientLeft(wnd); + int MouseY = (int) p2 - GetClientTop(wnd); + DFRECT rc = ClientRect(wnd); + char *lp; + int len; + if (KeyBoardMarking) + return TRUE; + if (WindowMoving || WindowSizing) + return FALSE; + if (isMultiLine(wnd)) { + if (TextMarking) { + if (!InsideRect(p1, p2, rc)) { + int x = MouseX, y = MouseY; + int dir; + DFMESSAGE msg = 0; + if ((int)p2 == GetTop(wnd)) + y++, dir = FALSE, msg = SCROLL; + else if ((int)p2 == GetBottom(wnd)) + --y, dir = TRUE, msg = SCROLL; + else if ((int)p1 == GetLeft(wnd)) + --x, dir = FALSE, msg = HORIZSCROLL; + else if ((int)p1 == GetRight(wnd)) + x++, dir = TRUE, msg = HORIZSCROLL; + if (msg != 0) { + if (DfSendMessage(wnd, msg, dir, 0)) + ExtendBlock(wnd, x, y); + DfSendMessage(wnd, PAINT, 0, 0); + } + } + return TRUE; + } + if (!InsideRect(p1, p2, rc)) + return FALSE; + if (TextBlockMarked(wnd)) { + ClearTextBlock(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + } + if (wnd->wlines) { + if (MouseY > wnd->wlines-1) + return TRUE; + lp = TextLine(wnd, MouseY+wnd->wtop); + len = (int) (strchr(lp, '\n') - lp); + MouseX = min(MouseX, len); + if (MouseX < wnd->wleft) { + MouseX = 0; + DfSendMessage(wnd, KEYBOARD, HOME, 0); + } + ButtonDown = TRUE; + ButtonX = MouseX; + ButtonY = MouseY; + } + else + MouseX = MouseY = 0; + wnd->WndRow = MouseY; + SetLinePointer(wnd, MouseY+wnd->wtop); + } + if (isMultiLine(wnd) || + (!TextBlockMarked(wnd) + && (int)(MouseX+wnd->wleft) < (int)strlen(wnd->text))) + wnd->CurrCol = MouseX+wnd->wleft; + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + return TRUE; +} +/* ----------- MOUSE_MOVED Message ---------- */ +static int MouseMovedMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int MouseX = (int) p1 - GetClientLeft(wnd); + int MouseY = (int) p2 - GetClientTop(wnd); + DFRECT rc = ClientRect(wnd); + if (!InsideRect(p1, p2, rc)) + return FALSE; + if (MouseY > wnd->wlines-1) + return FALSE; + if (ButtonDown) { + SetAnchor(wnd, ButtonX+wnd->wleft, ButtonY+wnd->wtop); + TextMarking = TRUE; + rc = WindowRect(wnd); + DfSendMessage(NULL,MOUSE_TRAVEL,(PARAM) &rc, 0); + ButtonDown = FALSE; + } + if (TextMarking && !(WindowMoving || WindowSizing)) { + ExtendBlock(wnd, MouseX, MouseY); + return TRUE; + } + return FALSE; +} +static void StopMarking(DFWINDOW wnd) +{ + TextMarking = FALSE; + if (wnd->BlkBegLine > wnd->BlkEndLine) { + swap(wnd->BlkBegLine, wnd->BlkEndLine); + swap(wnd->BlkBegCol, wnd->BlkEndCol); + } + if (wnd->BlkBegLine == wnd->BlkEndLine && + wnd->BlkBegCol > wnd->BlkEndCol) + swap(wnd->BlkBegCol, wnd->BlkEndCol); +} +/* ----------- BUTTON_RELEASED Message ---------- */ +static int ButtonReleasedMsg(DFWINDOW wnd) +{ + if (isMultiLine(wnd)) { + ButtonDown = FALSE; + if (TextMarking && !(WindowMoving || WindowSizing)) { + /* release the mouse ouside the edit box */ + DfSendMessage(NULL, MOUSE_TRAVEL, 0, 0); + StopMarking(wnd); + return TRUE; + } + else + PrevY = -1; + } + return FALSE; +} +/* ---- Process text block keys for multiline text box ---- */ +static void DoMultiLines(DFWINDOW wnd, int c, PARAM p2) +{ + if (isMultiLine(wnd) && !KeyBoardMarking) { + if ((int)p2 & (LEFTSHIFT | RIGHTSHIFT)) { + switch (c) { + case HOME: + case CTRL_HOME: + case CTRL_BS: + case PGUP: + case CTRL_PGUP: + case UP: + case BS: + case END: + case CTRL_END: + case PGDN: + case CTRL_PGDN: + case DN: + case FWD: + case CTRL_FWD: + KeyBoardMarking = TextMarking = TRUE; + SetAnchor(wnd, wnd->CurrCol, wnd->CurrLine); + break; + default: + break; + } + } + } +} +/* ---------- page/scroll keys ----------- */ +static int DoScrolling(DFWINDOW wnd, int c, PARAM p2) +{ + switch (c) { + case PGUP: + case PGDN: + if (isMultiLine(wnd)) + BaseWndProc(EDITBOX, wnd, KEYBOARD, c, p2); + break; + case CTRL_PGUP: + case CTRL_PGDN: + BaseWndProc(EDITBOX, wnd, KEYBOARD, c, p2); + break; + case HOME: + Home(wnd); + break; + case END: + End(wnd); + break; + case CTRL_FWD: + NextWord(wnd); + break; + case CTRL_BS: + PrevWord(wnd); + break; + case CTRL_HOME: + if (isMultiLine(wnd)) { + DfSendMessage(wnd, SCROLLDOC, TRUE, 0); + wnd->CurrLine = 0; + wnd->WndRow = 0; + } + Home(wnd); + break; + case CTRL_END: + if (isMultiLine(wnd) && + wnd->WndRow+wnd->wtop+1 < wnd->wlines + && wnd->wlines > 0) { + DfSendMessage(wnd, SCROLLDOC, FALSE, 0); + SetLinePointer(wnd, wnd->wlines-1); + wnd->WndRow = + min(ClientHeight(wnd)-1, wnd->wlines-1); + Home(wnd); + } + End(wnd); + break; + case UP: + if (isMultiLine(wnd)) + Upward(wnd); + break; + case DN: + if (isMultiLine(wnd)) + Downward(wnd); + break; + case FWD: + Forward(wnd); + break; + case BS: + Backward(wnd); + break; + default: + return FALSE; + } + if (!KeyBoardMarking && TextBlockMarked(wnd)) { + ClearTextBlock(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + } + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + return TRUE; +} +/* -------------- Del key ---------------- */ +static void DelKey(DFWINDOW wnd) +{ + char *currchar = CurrChar; + int repaint = *currchar == '\n'; + if (TextBlockMarked(wnd)) { + DfSendMessage(wnd, DFM_COMMAND, ID_DELETETEXT, 0); + DfSendMessage(wnd, PAINT, 0, 0); + return; + } + if (isMultiLine(wnd) && *currchar == '\n' && *(currchar+1) == '\0') + return; + strcpy(currchar, currchar+1); + if (repaint) { + BuildTextPointers(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + } + else { + ModTextPointers(wnd, wnd->CurrLine+1, -1); + WriteTextLine(wnd, NULL, wnd->WndRow+wnd->wtop, FALSE); + } + wnd->TextChanged = TRUE; +} +/* ------------ Tab key ------------ */ +static void TabKey(DFWINDOW wnd, PARAM p2) +{ + if (isMultiLine(wnd)) { + int insmd = wnd->InsertMode; + do { + char *cc = CurrChar+1; + if (!insmd && *cc == '\0') + break; + if (wnd->textlen == wnd->MaxTextLength) + break; + DfSendMessage(wnd,KEYBOARD,insmd ? ' ' : FWD,0); + } while (wnd->CurrCol % cfg.Tabs); + } + else + DfPostMessage(GetParent(wnd), KEYBOARD, '\t', p2); +} +/* ------------ Shift+Tab key ------------ */ +static void ShiftTabKey(DFWINDOW wnd, PARAM p2) +{ + if (isMultiLine(wnd)) { + do { + if (CurrChar == GetText(wnd)) + break; + DfSendMessage(wnd,KEYBOARD,BS,0); + } while (wnd->CurrCol % cfg.Tabs); + } + else + DfPostMessage(GetParent(wnd), KEYBOARD, SHIFT_HT, p2); +} +/* --------- All displayable typed keys ------------- */ +static void KeyTyped(DFWINDOW wnd, int c) +{ + char *currchar = CurrChar; + if ((c != '\n' && c < ' ') || (c & 0x1000)) + /* ---- not recognized by editor --- */ + return; + if (!isMultiLine(wnd) && TextBlockMarked(wnd)) { + DfSendMessage(wnd, CLEARTEXT, 0, 0); + currchar = CurrChar; + } + /* ---- test typing at end of text ---- */ + if (currchar == wnd->text+wnd->MaxTextLength) { + /* ---- typing at the end of maximum buffer ---- */ + beep(); + return; + } + if (*currchar == '\0') { + /* --- insert a newline at end of text --- */ + *currchar = '\n'; + *(currchar+1) = '\0'; + BuildTextPointers(wnd); + } + /* --- displayable char or newline --- */ + if (c == '\n' || wnd->InsertMode || *currchar == '\n') { + /* ------ inserting the keyed character ------ */ + if (wnd->text[wnd->textlen-1] != '\0') { + /* --- the current text buffer is full --- */ + if (wnd->textlen == wnd->MaxTextLength) { + /* --- text buffer is at maximum size --- */ + beep(); + return; + } + /* ---- increase the text buffer size ---- */ + wnd->textlen += GROWLENGTH; + /* --- but not above maximum size --- */ + if (wnd->textlen > wnd->MaxTextLength) + wnd->textlen = wnd->MaxTextLength; + wnd->text = DFrealloc(wnd->text, wnd->textlen+2); + wnd->text[wnd->textlen-1] = '\0'; + currchar = CurrChar; + } + memmove(currchar+1, currchar, strlen(currchar)+1); + ModTextPointers(wnd, wnd->CurrLine+1, 1); + if (isMultiLine(wnd) && wnd->wlines > 1) + wnd->textwidth = max(wnd->textwidth, + (int) (TextLine(wnd, wnd->CurrLine+1)- + TextLine(wnd, wnd->CurrLine))); + else + wnd->textwidth = max((int)wnd->textwidth, + (int)strlen(wnd->text)); + WriteTextLine(wnd, NULL, + wnd->wtop+wnd->WndRow, FALSE); + } + /* ----- put the char in the buffer ----- */ + *currchar = c; + wnd->TextChanged = TRUE; + if (c == '\n') { + wnd->wleft = 0; + BuildTextPointers(wnd); + End(wnd); + Forward(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + return; + } + /* ---------- test end of window --------- */ + if (WndCol == ClientWidth(wnd)-1) { + if (!isMultiLine(wnd)) { + if (!(currchar == wnd->text+wnd->MaxTextLength-2)) + DfSendMessage(wnd, HORIZSCROLL, TRUE, 0); + } + else { + char *cp = currchar; + while (*cp != ' ' && cp != TextLine(wnd, wnd->CurrLine)) + --cp; + if (cp == TextLine(wnd, wnd->CurrLine) || + !wnd->WordWrapMode) + DfSendMessage(wnd, HORIZSCROLL, TRUE, 0); + else { + int dif = 0; + if (c != ' ') { + dif = (int) (currchar - cp); + wnd->CurrCol -= dif; + DfSendMessage(wnd, KEYBOARD, DEL, 0); + --dif; + } + DfSendMessage(wnd, KEYBOARD, '\n', 0); + currchar = CurrChar; + wnd->CurrCol = dif; + if (c == ' ') + return; + } + } + } + /* ------ display the character ------ */ + SetStandardColor(wnd); + PutWindowChar(wnd, c, WndCol, wnd->WndRow); + /* ----- advance the pointers ------ */ + wnd->CurrCol++; +} +/* ------------ screen changing key strokes ------------- */ +static void DoKeyStroke(DFWINDOW wnd, int c, PARAM p2) +{ + switch (c) { + case RUBOUT: + if (wnd->CurrCol == 0 && wnd->CurrLine == 0) + break; + Backward(wnd); + case DEL: + DelKey(wnd); + break; + case SHIFT_HT: + ShiftTabKey(wnd, p2); + break; + case '\t': + TabKey(wnd, p2); + break; + case '\r': + if (!isMultiLine(wnd)) { + DfPostMessage(GetParent(wnd), KEYBOARD, c, p2); + break; + } + c = '\n'; + default: + if (TextBlockMarked(wnd)) { + DfSendMessage(wnd, DFM_COMMAND, ID_DELETETEXT, 0); + DfSendMessage(wnd, PAINT, 0, 0); + } + KeyTyped(wnd, c); + break; + } +} +/* ----------- KEYBOARD Message ---------- */ +static int KeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int c = (int) p1; + + if (WindowMoving || WindowSizing || ((int)p2 & ALTKEY)) + return FALSE; + + switch (c) + { + /* these keys get processed by lower classes */ + case ESC: + case F1: + case F2: + case F3: + case F4: + case F5: + case F6: + case F7: + case F8: + case F9: + case F10: + case INS: + case SHIFT_INS: + case SHIFT_DEL: + return FALSE; + + /* these keys get processed here */ + case CTRL_FWD: + case CTRL_BS: + case CTRL_HOME: + case CTRL_END: + case CTRL_PGUP: + case CTRL_PGDN: + break; + + default: + /* other ctrl keys get processed by lower classes */ + if ((int)p2 & CTRLKEY) + return FALSE; + /* all other keys get processed here */ + break; + } + + DoMultiLines(wnd, c, p2); + if (DoScrolling(wnd, c, p2)) + { + if (KeyBoardMarking) + ExtendBlock(wnd, WndCol, wnd->WndRow); + } + else if (!TestAttribute(wnd, READONLY)) + { + DoKeyStroke(wnd, c, p2); + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + } + else + beep(); + + return TRUE; +} + +/* ----------- SHIFT_CHANGED Message ---------- */ +static void ShiftChangedMsg(DFWINDOW wnd, PARAM p1) +{ + if (!((int)p1 & (LEFTSHIFT | RIGHTSHIFT)) && + KeyBoardMarking) { + StopMarking(wnd); + KeyBoardMarking = FALSE; + } +} +/* ----------- ID_DELETETEXT Command ---------- */ +static void DeleteTextCmd(DFWINDOW wnd) +{ + if (TextBlockMarked(wnd)) { + char *bbl=TextLine(wnd,wnd->BlkBegLine)+wnd->BlkBegCol; + char *bel=TextLine(wnd,wnd->BlkEndLine)+wnd->BlkEndCol; + int len = (int) (bel - bbl); + SaveDeletedText(wnd, bbl, len); + wnd->TextChanged = TRUE; + strcpy(bbl, bel); + wnd->CurrLine = TextLineNumber(wnd, bbl-wnd->BlkBegCol); + wnd->CurrCol = wnd->BlkBegCol; + wnd->WndRow = wnd->BlkBegLine - wnd->wtop; + if (wnd->WndRow < 0) { + wnd->wtop = wnd->BlkBegLine; + wnd->WndRow = 0; + } + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + ClearTextBlock(wnd); + BuildTextPointers(wnd); + } +} +/* ----------- ID_CLEAR Command ---------- */ +static void ClearCmd(DFWINDOW wnd) +{ + if (TextBlockMarked(wnd)) { + char *bbl=TextLine(wnd,wnd->BlkBegLine)+wnd->BlkBegCol; + char *bel=TextLine(wnd,wnd->BlkEndLine)+wnd->BlkEndCol; + int len = (int) (bel - bbl); + SaveDeletedText(wnd, bbl, len); + wnd->CurrLine = TextLineNumber(wnd, bbl); + wnd->CurrCol = wnd->BlkBegCol; + wnd->WndRow = wnd->BlkBegLine - wnd->wtop; + if (wnd->WndRow < 0) { + wnd->WndRow = 0; + wnd->wtop = wnd->BlkBegLine; + } + /* ------ change all text lines in block to \n ----- */ + while (bbl < bel) { + char *cp = strchr(bbl, '\n'); + if (cp > bel) + cp = bel; + strcpy(bbl, cp); + bel -= (int) (cp - bbl); + bbl++; + } + ClearTextBlock(wnd); + BuildTextPointers(wnd); + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + wnd->TextChanged = TRUE; + } +} +/* ----------- ID_UNDO Command ---------- */ +static void UndoCmd(DFWINDOW wnd) +{ + if (wnd->DeletedText != NULL) { + PasteText(wnd, wnd->DeletedText, wnd->DeletedLength); + free(wnd->DeletedText); + wnd->DeletedText = NULL; + wnd->DeletedLength = 0; + DfSendMessage(wnd, PAINT, 0, 0); + } +} +/* ----------- ID_PARAGRAPH Command ---------- */ +static void ParagraphCmd(DFWINDOW wnd) +{ + int bc, fl; + char *bl, *bbl, *bel, *bb; + + ClearTextBlock(wnd); + /* ---- forming paragraph from cursor position --- */ + fl = wnd->wtop + wnd->WndRow; + bbl = bel = bl = TextLine(wnd, wnd->CurrLine); + if ((bc = wnd->CurrCol) >= ClientWidth(wnd)) + bc = 0; + Home(wnd); + /* ---- locate the end of the paragraph ---- */ + while (*bel) { + int blank = TRUE; + char *bll = bel; + /* --- blank line marks end of paragraph --- */ + while (*bel && *bel != '\n') { + if (*bel != ' ') + blank = FALSE; + bel++; + } + if (blank) { + bel = bll; + break; + } + if (*bel) + bel++; + } + if (bel == bbl) { + DfSendMessage(wnd, KEYBOARD, DN, 0); + return; + } + if (*bel == '\0') + --bel; + if (*bel == '\n') + --bel; + /* --- change all newlines in block to spaces --- */ + while (CurrChar < bel) { + if (*CurrChar == '\n') { + *CurrChar = ' '; + wnd->CurrLine++; + wnd->CurrCol = 0; + } + else + wnd->CurrCol++; + } + /* ---- insert newlines at new margin boundaries ---- */ + bb = bbl; + while (bbl < bel) { + bbl++; + if ((int)(bbl - bb) == ClientWidth(wnd)-1) { + while (*bbl != ' ' && bbl > bb) + --bbl; + if (*bbl != ' ') { + bbl = strchr(bbl, ' '); + if (bbl == NULL || bbl >= bel) + break; + } + *bbl = '\n'; + bb = bbl+1; + } + } + BuildTextPointers(wnd); + /* --- put cursor back at beginning --- */ + wnd->CurrLine = TextLineNumber(wnd, bl); + wnd->CurrCol = bc; + if (fl < wnd->wtop) + wnd->wtop = fl; + wnd->WndRow = fl - wnd->wtop; + DfSendMessage(wnd, PAINT, 0, 0); + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + wnd->TextChanged = TRUE; + BuildTextPointers(wnd); +} +/* ----------- COMMAND Message ---------- */ +static int CommandMsg(DFWINDOW wnd, PARAM p1) +{ + switch ((int)p1) { + case ID_DELETETEXT: + DeleteTextCmd(wnd); + return TRUE; + case ID_CLEAR: + ClearCmd(wnd); + return TRUE; + case ID_UNDO: + UndoCmd(wnd); + return TRUE; + case ID_PARAGRAPH: + ParagraphCmd(wnd); + return TRUE; + default: + break; + } + return FALSE; +} +/* ---------- CLOSE_WINDOW Message ----------- */ +static int CloseWindowMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int rtn; + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + if (wnd->DeletedText != NULL) + free(wnd->DeletedText); + if (wnd->text != NULL) + { + free(wnd->text); + wnd->text = NULL; + } + rtn = BaseWndProc(EDITBOX, wnd, CLOSE_WINDOW, p1, p2); + return rtn; +} + +/* ------- Window processing module for EDITBOX class ------ */ +int EditBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + switch (msg) { + case CREATE_WINDOW: + return CreateWindowMsg(wnd); + case ADDTEXT: + return AddTextMsg(wnd, p1, p2); + case SETTEXT: + return SetTextMsg(wnd, p1); + case CLEARTEXT: + return ClearTextMsg(wnd); + case GETTEXT: + return GetTextMsg(wnd, p1, p2); + case SETTEXTLENGTH: + return SetTextLengthMsg(wnd, (unsigned) p1); + case KEYBOARD_CURSOR: + KeyboardCursorMsg(wnd, p1, p2); + return TRUE; + case SETFOCUS: + if (!(int)p1) + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + case PAINT: + case MOVE: + rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2); + DfSendMessage(wnd,KEYBOARD_CURSOR,WndCol,wnd->WndRow); + return rtn; + case DFM_SIZE: + return SizeMsg(wnd, p1, p2); + case SCROLL: + return ScrollMsg(wnd, p1); + case HORIZSCROLL: + return HorizScrollMsg(wnd, p1); + case SCROLLPAGE: + return ScrollPageMsg(wnd, p1); + case HORIZPAGE: + return HorizPageMsg(wnd, p1); + case LEFT_BUTTON: + if (LeftButtonMsg(wnd, p1, p2)) + return TRUE; + break; + case MOUSE_MOVED: + if (MouseMovedMsg(wnd, p1, p2)) + return TRUE; + break; + case DFM_BUTTON_RELEASED: + if (ButtonReleasedMsg(wnd)) + return TRUE; + break; + case KEYBOARD: + if (KeyboardMsg(wnd, p1, p2)) + return TRUE; + break; + case SHIFT_CHANGED: + ShiftChangedMsg(wnd, p1); + break; + case DFM_COMMAND: + if (CommandMsg(wnd, p1)) + return TRUE; + break; + case CLOSE_WINDOW: + return CloseWindowMsg(wnd, p1, p2); + default: + break; + } + return BaseWndProc(EDITBOX, wnd, msg, p1, p2); +} +/* ------ save deleted text for the Undo command ------ */ +static void SaveDeletedText(DFWINDOW wnd, char *bbl, int len) +{ + wnd->DeletedLength = len; + wnd->DeletedText=DFrealloc(wnd->DeletedText,len); + memmove(wnd->DeletedText, bbl, len); +} +/* ---- cursor right key: right one character position ---- */ +static void Forward(DFWINDOW wnd) +{ + char *cc = CurrChar+1; + if (*cc == '\0') + return; + if (*CurrChar == '\n') { + Home(wnd); + Downward(wnd); + } + else { + wnd->CurrCol++; + if (WndCol == ClientWidth(wnd)) + DfSendMessage(wnd, HORIZSCROLL, TRUE, 0); + } +} +/* ----- stick the moving cursor to the end of the line ---- */ +static void StickEnd(DFWINDOW wnd) +{ + char *cp = TextLine(wnd, wnd->CurrLine); + char *cp1 = strchr(cp, '\n'); + int len = cp1 ? (int) (cp1 - cp) : 0; + wnd->CurrCol = min(len, wnd->CurrCol); + if (wnd->wleft > wnd->CurrCol) { + wnd->wleft = max(0, wnd->CurrCol - 4); + DfSendMessage(wnd, PAINT, 0, 0); + } + else if (wnd->CurrCol-wnd->wleft >= ClientWidth(wnd)) { + wnd->wleft = wnd->CurrCol - (ClientWidth(wnd)-1); + DfSendMessage(wnd, PAINT, 0, 0); + } +} +/* --------- cursor down key: down one line --------- */ +static void Downward(DFWINDOW wnd) +{ + if (isMultiLine(wnd) && + wnd->WndRow+wnd->wtop+1 < wnd->wlines) { + wnd->CurrLine++; + if (wnd->WndRow == ClientHeight(wnd)-1) + BaseWndProc(EDITBOX, wnd, SCROLL, TRUE, 0); + else + wnd->WndRow++; + StickEnd(wnd); + } +} +/* -------- cursor up key: up one line ------------ */ +static void Upward(DFWINDOW wnd) +{ + if (isMultiLine(wnd) && wnd->CurrLine != 0) { + --wnd->CurrLine; + if (wnd->WndRow == 0) + BaseWndProc(EDITBOX, wnd, SCROLL, FALSE, 0); + else + --wnd->WndRow; + StickEnd(wnd); + } +} +/* ---- cursor left key: left one character position ---- */ +static void Backward(DFWINDOW wnd) +{ + if (wnd->CurrCol) { + --wnd->CurrCol; + if (wnd->CurrCol < wnd->wleft) + DfSendMessage(wnd, HORIZSCROLL, FALSE, 0); + } + else if (isMultiLine(wnd) && wnd->CurrLine != 0) { + Upward(wnd); + End(wnd); + } +} +/* -------- End key: to end of line ------- */ +static void End(DFWINDOW wnd) +{ + while (*CurrChar && *CurrChar != '\n') + ++wnd->CurrCol; + if (WndCol >= ClientWidth(wnd)) { + wnd->wleft = wnd->CurrCol - (ClientWidth(wnd)-1); + DfSendMessage(wnd, PAINT, 0, 0); + } +} +/* -------- Home key: to beginning of line ------- */ +static void Home(DFWINDOW wnd) +{ + wnd->CurrCol = 0; + if (wnd->wleft != 0) { + wnd->wleft = 0; + DfSendMessage(wnd, PAINT, 0, 0); + } +} +/* -- Ctrl+cursor right key: to beginning of next word -- */ +static void NextWord(DFWINDOW wnd) +{ + int savetop = wnd->wtop; + int saveleft = wnd->wleft; + ClearVisible(wnd); + while (!isWhite(*CurrChar)) { + char *cc = CurrChar+1; + if (*cc == '\0') + break; + Forward(wnd); + } + while (isWhite(*CurrChar)) { + char *cc = CurrChar+1; + if (*cc == '\0') + break; + Forward(wnd); + } + SetVisible(wnd); + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + if (wnd->wtop != savetop || wnd->wleft != saveleft) + DfSendMessage(wnd, PAINT, 0, 0); +} +/* -- Ctrl+cursor left key: to beginning of previous word -- */ +static void PrevWord(DFWINDOW wnd) +{ + int savetop = wnd->wtop; + int saveleft = wnd->wleft; + ClearVisible(wnd); + Backward(wnd); + while (isWhite(*CurrChar)) { + if (wnd->CurrLine == 0 && wnd->CurrCol == 0) + break; + Backward(wnd); + } + while (wnd->CurrCol != 0 && !isWhite(*CurrChar)) + Backward(wnd); + if (isWhite(*CurrChar)) + Forward(wnd); + SetVisible(wnd); + if (wnd->wleft != saveleft) + if (wnd->CurrCol >= saveleft) + if (wnd->CurrCol - saveleft < ClientWidth(wnd)) + wnd->wleft = saveleft; + DfSendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); + if (wnd->wtop != savetop || wnd->wleft != saveleft) + DfSendMessage(wnd, PAINT, 0, 0); +} +/* ----- modify text pointers from a specified position + by a specified plus or minus amount ----- */ +static void ModTextPointers(DFWINDOW wnd, int lineno, int var) +{ + while (lineno < wnd->wlines) + *((wnd->TextPointers) + lineno++) += var; +} +/* ----- set anchor point for marking text block ----- */ +static void SetAnchor(DFWINDOW wnd, int mx, int my) +{ + ClearTextBlock(wnd); + /* ------ set the anchor ------ */ + wnd->BlkBegLine = wnd->BlkEndLine = my; + wnd->BlkBegCol = wnd->BlkEndCol = mx; + DfSendMessage(wnd, PAINT, 0, 0); +} + +/* EOF */ diff --git a/rosapps/dflat32/fileopen.c b/rosapps/dflat32/fileopen.c new file mode 100644 index 00000000000..8a1a87042c2 --- /dev/null +++ b/rosapps/dflat32/fileopen.c @@ -0,0 +1,259 @@ +/* ----------- fileopen.c ------------- */ + +#include "dflat.h" + +static BOOL DlgFileOpen(char *, char *, DBOX *); +static int DlgFnOpen(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static void InitDlgBox(DFWINDOW); +static void StripPath(char *); +static BOOL IncompleteFilename(char *); + +static char *OrigSpec; +static char *FileSpec; +static char *FileName; +static char *NewFileName; + +static BOOL Saving; +extern DBOX FileOpen; +extern DBOX SaveAs; + +/* + * Dialog Box to select a file to open + */ +BOOL OpenFileDialogBox(char *Fpath, char *Fname) +{ + return DlgFileOpen(Fpath, Fname, &FileOpen); +} + +/* + * Dialog Box to select a file to save as + */ +BOOL SaveAsDialogBox(char *Fname) +{ + return DlgFileOpen(NULL, Fname, &SaveAs); +} + +/* --------- generic file open ---------- */ +static BOOL DlgFileOpen(char *Fpath, char *Fname, DBOX *db) +{ + BOOL rtn; + char savedir[MAX_PATH]; + char OSpec[80]; + char FSpec[80]; + char FName[80]; + char NewFName[80]; + + OrigSpec = OSpec; + FileSpec = FSpec; + FileName = FName; + NewFileName = NewFName; + + GetCurrentDirectory (MAX_PATH, savedir); + + if (Fpath != NULL) { + strncpy(FileSpec, Fpath, 80); + Saving = FALSE; + } + else { + *FileSpec = '\0'; + Saving = TRUE; + } + strcpy(FileName, FileSpec); + strcpy(OrigSpec, FileSpec); + + if ((rtn = DfDialogBox(NULL, db, TRUE, DlgFnOpen)) != FALSE) + strcpy(Fname, NewFileName); + else + *Fname = '\0'; + + SetCurrentDirectory (savedir); + + return rtn; +} + +/* + * Process dialog box messages + */ +static int DlgFnOpen(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + int rtn; + DBOX *db; + DFWINDOW cwnd; + + switch (msg) + { + case CREATE_WINDOW: + rtn = DefaultWndProc(wnd, msg, p1, p2); + db = wnd->extension; + cwnd = ControlWindow(db, ID_FILENAME); + DfSendMessage(cwnd, SETTEXTLENGTH, 64, 0); + return rtn; + + case INITIATE_DIALOG: + InitDlgBox(wnd); + break; + + case DFM_COMMAND: + switch ((int) p1) + { + case ID_FILENAME: + if (p2 != ENTERFOCUS) + { + /* allow user to modify the file spec */ + GetItemText(wnd, ID_FILENAME, + FileName, 65); + if (IncompleteFilename(FileName) || Saving) + { + strcpy(OrigSpec, FileName); + StripPath(OrigSpec); + } + if (p2 != LEAVEFOCUS) + DfSendMessage(wnd, DFM_COMMAND, ID_OK, 0); + } + return TRUE; + + case ID_OK: + if (p2 != 0) + break; + GetItemText(wnd, ID_FILENAME, + FileName, 65); + strcpy(FileSpec, FileName); + if (IncompleteFilename(FileName)) + { + /* no file name yet */ + InitDlgBox(wnd); + strcpy(OrigSpec, FileSpec); + return TRUE; + } + else { + GetItemText(wnd, ID_PATH, FileName, 65); + strcat(FileName, FileSpec); + strcpy(NewFileName, FileName); + } + break; + + case ID_FILES: + switch ((int) p2) + { + case ENTERFOCUS: + case LB_SELECTION: + /* selected a different filename */ + GetDlgListText(wnd, FileName, + ID_FILES); + PutItemText(wnd, ID_FILENAME, + FileName); + break; + case LB_CHOOSE: + /* chose a file name */ + GetDlgListText(wnd, FileName, + ID_FILES); + DfSendMessage(wnd, DFM_COMMAND, ID_OK, 0); + break; + default: + break; + } + return TRUE; + + case ID_DRIVE: + switch ((int) p2) { + case ENTERFOCUS: + if (Saving) + *FileSpec = '\0'; + break; + case LEAVEFOCUS: + if (Saving) + strcpy(FileSpec, FileName); + break; + + case LB_SELECTION: + { + char dd[25]; + /* selected different drive/dir */ + GetDlgListText(wnd, dd, ID_DRIVE); + if (*(dd+2) == ':') + *(dd+3) = '\0'; + else + *(dd+strlen(dd)-1) = '\0'; + strcpy(FileName, dd+1); + if (*(dd+2) != ':' && *OrigSpec != '\\') + strcat(FileName, "\\"); + strcat(FileName, OrigSpec); + if (*(FileName+1) != ':' && *FileName != '.') + { + GetItemText(wnd, ID_PATH, FileSpec, 65); + strcat(FileSpec, FileName); + } + else + strcpy(FileSpec, FileName); + } + break; + + case LB_CHOOSE: + /* chose drive/dir */ + if (Saving) + PutItemText(wnd, ID_FILENAME, ""); + InitDlgBox(wnd); + return TRUE; + default: + break; + } + PutItemText(wnd, ID_FILENAME, FileSpec); + return TRUE; + + + default: + break; + } + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +/* + * Initialize the dialog box + */ +static void InitDlgBox(DFWINDOW wnd) +{ + if (*FileSpec && !Saving) + PutItemText(wnd, ID_FILENAME, FileSpec); + if (DfDlgDirList(wnd, FileSpec, ID_FILES, ID_PATH, 0)) + { + StripPath(FileSpec); + DfDlgDirList(wnd, "*.*", ID_DRIVE, 0, 0xc010); + } +} + +/* + * Strip the drive and path information from a file spec + */ +static void StripPath(char *filespec) +{ + char *cp, *cp1; + + cp = strchr(filespec, ':'); + if (cp != NULL) + cp++; + else + cp = filespec; + while (TRUE) { + cp1 = strchr(cp, '\\'); + if (cp1 == NULL) + break; + cp = cp1+1; + } + strcpy(filespec, cp); +} + + +static BOOL IncompleteFilename(char *s) +{ + int lc = strlen(s)-1; + if (strchr(s, '?') || strchr(s, '*') || !*s) + return TRUE; + if (*(s+lc) == ':' || *(s+lc) == '\\') + return TRUE; + return FALSE; +} + +/* EOF */ \ No newline at end of file diff --git a/rosapps/dflat32/help.txt b/rosapps/dflat32/help.txt new file mode 100644 index 00000000000..4d2e34637bf --- /dev/null +++ b/rosapps/dflat32/help.txt @@ -0,0 +1 @@ +help.txt diff --git a/rosapps/dflat32/helpbox.c b/rosapps/dflat32/helpbox.c new file mode 100644 index 00000000000..571193e61a8 --- /dev/null +++ b/rosapps/dflat32/helpbox.c @@ -0,0 +1,717 @@ +/* ------------ helpbox.c ----------- */ + +#include "dflat.h" +#include "htree.h" + +extern DBOX HelpBox; + +/* -------- strings of D-Flat classes for calling default + help text collections -------- */ +char *ClassNames[] = { + #undef ClassDef + #define ClassDef(c,b,p,a) #c, + #include "classes.h" + NULL +}; + +#define MAXHEIGHT (SCREENHEIGHT-10) + +/* --------- linked list of help text collections -------- */ +struct helps { + char *hname; + char *NextName; + char *PrevName; + long hptr; + int bit; + int hheight; + int hwidth; + DFWINDOW hwnd; + struct helps *NextHelp; +}; +static struct helps *FirstHelp; +static struct helps *LastHelp; +static struct helps *ThisHelp; + +/* --- linked stack of help windows that have beed used --- */ +struct HelpStack { + char *hname; + struct HelpStack *PrevStack; +}; +static struct HelpStack *LastStack; +static struct HelpStack *ThisStack; + +/* --- linked list of keywords in the current help + text collection (listhead is in window) -------- */ +struct keywords { + char *hname; + int lineno; + int off1, off2, off3; + int isDefinition; + struct keywords *nextword; + struct keywords *prevword; +}; + +static FILE *helpfp; +static char hline [160]; +static BOOL Helping; + +static void SelectHelp(DFWINDOW, char *); +static void ReadHelp(DFWINDOW); +static void FindHelp(char *); +static void FindHelpWindow(DFWINDOW); +static void DisplayDefinition(DFWINDOW, char *); +static void BestFit(DFWINDOW, DIALOGWINDOW *); + +/* ------------- CREATE_WINDOW message ------------ */ +static void CreateWindowMsg(DFWINDOW wnd) +{ + Helping = TRUE; + GetClass(wnd) = HELPBOX; + InitWindowColors(wnd); + if (ThisHelp != NULL) + ThisHelp->hwnd = wnd; +} + +/* ------------- COMMAND message ------------ */ +static BOOL CommandMsg(DFWINDOW wnd, PARAM p1) +{ + switch ((int)p1) { + case ID_CANCEL: + ThisStack = LastStack; + while (ThisStack != NULL) { + LastStack = ThisStack->PrevStack; + if (ThisStack->hname != NULL) + free(ThisStack->hname); + free(ThisStack); + ThisStack = LastStack; + } + break; + case ID_PREV: + FindHelpWindow(wnd); + if (ThisHelp != NULL) + SelectHelp(wnd, ThisHelp->PrevName); + return TRUE; + case ID_NEXT: + FindHelpWindow(wnd); + if (ThisHelp != NULL) + SelectHelp(wnd, ThisHelp->NextName); + return TRUE; + case ID_BACK: + if (LastStack != NULL) { + if (LastStack->PrevStack != NULL) { + ThisStack = LastStack->PrevStack; + if (LastStack->hname != NULL) + free(LastStack->hname); + free(LastStack); + LastStack = ThisStack; + SelectHelp(wnd, ThisStack->hname); + } + } + return TRUE; + default: + break; + } + return FALSE; +} + +/* ------------- KEYBOARD message ------------ */ +static BOOL KeyboardMsg(DFWINDOW wnd, PARAM p1) +{ + DFWINDOW cwnd; + struct keywords *thisword; + static char HelpName[50]; + + cwnd = ControlWindow(wnd->extension, ID_HELPTEXT); + if (cwnd == NULL || inFocus != cwnd) + return FALSE; + thisword = cwnd->thisword; + switch ((int)p1) { + case '\r': + if (thisword != NULL) { + if (thisword->isDefinition) + DisplayDefinition(GetParent(wnd), + thisword->hname); + else { + strncpy(HelpName, thisword->hname, + sizeof HelpName); + SelectHelp(wnd, HelpName); + } + } + return TRUE; + case '\t': + if (thisword == NULL) + thisword = cwnd->firstword; + else { + if (thisword->nextword == NULL) + thisword = cwnd->firstword; + else + thisword = thisword->nextword; + } + break; + case SHIFT_HT: + if (thisword == NULL) + thisword = cwnd->lastword; + else { + if (thisword->prevword == NULL) + thisword = cwnd->lastword; + else + thisword = thisword->prevword; + } + break; + default: + thisword = NULL; + break; + } + if (thisword != NULL) { + cwnd->thisword = thisword; + if (thisword->lineno < cwnd->wtop || + thisword->lineno >= + cwnd->wtop + ClientHeight(cwnd)) { + int distance = ClientHeight(cwnd)/2; + do { + cwnd->wtop = thisword->lineno-distance; + distance /= 2; + } + while (cwnd->wtop < 0); + } + DfSendMessage(cwnd, PAINT, 0, 0); + return TRUE; + } + return FALSE; +} + +/* ---- window processing module for the HELPBOX ------- */ +int HelpBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + DBOX *db = wnd->extension; + + switch (msg) { + case CREATE_WINDOW: + CreateWindowMsg(wnd); + break; + case INITIATE_DIALOG: + ReadHelp(wnd); + break; + case DFM_COMMAND: + if (p2 != 0) + break; + if (CommandMsg(wnd, p1)) + return TRUE; + break; + case KEYBOARD: + if (WindowMoving) + break; + if (KeyboardMsg(wnd, p1)) + return TRUE; + break; + case CLOSE_WINDOW: + if (db != NULL) { + if (db->dwnd.title != NULL) { + free(db->dwnd.title); + db->dwnd.title = NULL; + } + } + FindHelpWindow(wnd); + if (ThisHelp != NULL) + ThisHelp->hwnd = NULL; + Helping = FALSE; + break; + default: + break; + } + return BaseWndProc(HELPBOX, wnd, msg, p1, p2); +} + +/* ----- select a new help window from its name ----- */ +static void SelectHelp(DFWINDOW wnd, char *hname) +{ + if (hname != NULL) { + DFWINDOW pwnd = GetParent(wnd); + DfPostMessage(wnd, ENDDIALOG, 0, 0); + DfPostMessage(pwnd, DISPLAY_HELP, (PARAM) hname, 0); + } +} + +/* ---- PAINT message for the helpbox text editbox ---- */ +static int PaintMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + struct keywords *thisword; + int rtn; + if (wnd->thisword != NULL) { + DFWINDOW pwnd = GetParent(wnd); + char *cp; + thisword = wnd->thisword; + cp = TextLine(wnd, thisword->lineno); + cp += thisword->off1; + *(cp+1) = + (pwnd->WindowColors[SELECT_COLOR][FG] & 255) | 0x80; + *(cp+2) = + (pwnd->WindowColors[SELECT_COLOR][BG] & 255) | 0x80; + rtn = DefaultWndProc(wnd, PAINT, p1, p2); + *(cp+1) = + (pwnd->WindowColors[HILITE_COLOR][FG] & 255) | 0x80; + *(cp+2) = + (pwnd->WindowColors[HILITE_COLOR][BG] & 255) | 0x80; + return rtn; + } + return DefaultWndProc(wnd, PAINT, p1, p2); +} + +/* ---- LEFT_BUTTON message for the helpbox text editbox ---- */ +static int LeftButtonMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + struct keywords *thisword; + int rtn, mx, my; + + rtn = DefaultWndProc(wnd, LEFT_BUTTON, p1, p2); + mx = (int)p1 - GetClientLeft(wnd); + my = (int)p2 - GetClientTop(wnd); + my += wnd->wtop; + thisword = wnd->firstword; + while (thisword != NULL) { + if (my == thisword->lineno) { + if (mx >= thisword->off2 && + mx < thisword->off3) { + wnd->thisword = thisword; + DfSendMessage(wnd, PAINT, 0, 0); + if (thisword->isDefinition) { + DFWINDOW pwnd = GetParent(wnd); + if (pwnd != NULL) + DisplayDefinition(GetParent(pwnd), + thisword->hname); + } + break; + } + } + thisword = thisword->nextword; + } + return rtn; +} + +/* --- window processing module for HELPBOX's text EDITBOX -- */ +int HelpTextProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + struct keywords *thisword; + switch (msg) { + case PAINT: + return PaintMsg(wnd, p1, p2); + case LEFT_BUTTON: + return LeftButtonMsg(wnd, p1, p2); + case DOUBLE_CLICK: + DfPostMessage(wnd, KEYBOARD, '\r', 0); + break; + case CLOSE_WINDOW: + thisword = wnd->firstword; + while (thisword != NULL) { + struct keywords *nextword = thisword->nextword; + if (thisword->hname != NULL) + free(thisword->hname); + free(thisword); + thisword = nextword; + } + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +/* -------- read the help text into the editbox ------- */ +static void ReadHelp(DFWINDOW wnd) +{ + DFWINDOW cwnd = ControlWindow(wnd->extension, ID_HELPTEXT); + int linectr = 0; + if (cwnd == NULL) + return; + cwnd->wndproc = HelpTextProc; + /* ----- read the help text ------- */ + while (TRUE) { + unsigned char *cp = hline, *cp1; + int colorct = 0; + if (GetHelpLine(hline) == NULL) + break; + if (*hline == '<') + break; + hline[strlen(hline)-1] = '\0'; + /* --- add help text to the help window --- */ + while (cp != NULL) { + if ((cp = strchr(cp, '[')) != NULL) { + /* ----- hit a new key word ----- */ + struct keywords *thisword; + if (*(cp+1) != '.' && *(cp+1) != '*') { + cp++; + continue; + } + thisword = DFcalloc(1, sizeof(struct keywords)); + if (cwnd->firstword == NULL) + cwnd->firstword = thisword; + if (cwnd->lastword != NULL) { + ((struct keywords *) + (cwnd->lastword))->nextword = thisword; + thisword->prevword = cwnd->lastword; + } + cwnd->lastword = thisword; + thisword->lineno = cwnd->wlines; + thisword->off1 = (int) ((int)cp - (int)hline); + thisword->off2 = thisword->off1 - colorct * 4; + thisword->isDefinition = *(cp+1) == '*'; + colorct++; + *cp++ = CHANGECOLOR; + *cp++ = + (wnd->WindowColors [HILITE_COLOR] [FG] & 255) | 0x80; + *cp++ = + (wnd->WindowColors [HILITE_COLOR] [BG] & 255) | 0x80; + cp1 = cp; + if ((cp = strchr(cp, ']')) != NULL) { + if (thisword != NULL) + thisword->off3 = + thisword->off2 + (int) (cp - cp1); + *cp++ = RESETCOLOR; + } + if ((cp = strchr(cp, '<')) != NULL) { + char *cp1 = strchr(cp, '>'); + if (cp1 != NULL) { + int len = (int) ((int)cp1 - (int)cp); + thisword->hname = DFcalloc(1, len); + strncpy(thisword->hname, cp+1, len-1); + memmove(cp, cp1+1, strlen(cp1)); + } + } + } + } + PutItemText(wnd, ID_HELPTEXT, hline); + /* -- display help text as soon as window is full -- */ + if (++linectr == ClientHeight(cwnd)) + DfSendMessage(cwnd, PAINT, 0, 0); + if (linectr > ClientHeight(cwnd) && + !TestAttribute(cwnd, VSCROLLBAR)) { + AddAttribute(cwnd, VSCROLLBAR); + DfSendMessage(cwnd, BORDER, 0, 0); + } + } +} + +/* ---- compute the displayed length of a help text line --- */ +static int HelpLength(char *s) +{ + int len = strlen(s); + char *cp = strchr(s, '['); + while (cp != NULL) { + len -= 4; + cp = strchr(cp+1, '['); + } + cp = strchr(s, '<'); + while (cp != NULL) { + char *cp1 = strchr(cp, '>'); + if (cp1 != NULL) + len -= (int) (cp1-cp)+1; + cp = strchr(cp1, '<'); + } + return len; +} + +/* ----------- load the help text file ------------ */ +void LoadHelpFile() +{ + char *cp; + + if (Helping) + return; + UnLoadHelpFile(); + if ((helpfp = OpenHelpFile()) == NULL) + return; + *hline = '\0'; + while (*hline != '<') { + if (GetHelpLine(hline) == NULL) { + fclose(helpfp); + return; + } + } + while (*hline == '<') { + if (strncmp(hline, "", 5) == 0) + break; + + /* -------- parse the help window's text name ----- */ + if ((cp = strchr(hline, '>')) != NULL) { + ThisHelp = DFcalloc(1, sizeof(struct helps)); + if (FirstHelp == NULL) + FirstHelp = ThisHelp; + *cp = '\0'; + ThisHelp->hname=DFmalloc(strlen(hline+1)+1); + strcpy(ThisHelp->hname, hline+1); + + HelpFilePosition(&ThisHelp->hptr, &ThisHelp->bit); + + if (GetHelpLine(hline) == NULL) + break; + + /* ------- build the help linked list entry --- */ + while (*hline == '[') { + HelpFilePosition(&ThisHelp->hptr, + &ThisHelp->bit); + /* ---- parse the <'); + if (cp1 != NULL) { + int len = (int) (cp1-cp); + ThisHelp->PrevName=DFcalloc(1,len); + strncpy(ThisHelp->PrevName, + cp+1,len-1); + } + } + if (GetHelpLine(hline) == NULL) + break; + continue; + } + /* ---- parse the next>> button pointer ---- */ + else if (strncmp(hline, "[>>]", 4) == 0) { + char *cp = strchr(hline+4, '<'); + if (cp != NULL) { + char *cp1 = strchr(cp, '>'); + if (cp1 != NULL) { + int len = (int) (cp1-cp); + ThisHelp->NextName=DFcalloc(1,len); + strncpy(ThisHelp->NextName, + cp+1,len-1); + } + } + if (GetHelpLine(hline) == NULL) + break; + continue; + } + else + break; + } + ThisHelp->hheight = 0; + ThisHelp->hwidth = 0; + ThisHelp->NextHelp = NULL; + + /* ------ append entry to the linked list ------ */ + if (LastHelp != NULL) + LastHelp->NextHelp = ThisHelp; + LastHelp = ThisHelp; + } + /* -------- move to the next token ------ */ + if (GetHelpLine(hline) == NULL) + strcpy(hline, ""); + while (*hline != '<') { + ThisHelp->hwidth = + max(ThisHelp->hwidth, HelpLength(hline)); + ThisHelp->hheight++; + if (GetHelpLine(hline) == NULL) + strcpy(hline, ""); + } + } + fclose(helpfp); +} + +/* ------ free the memory used by the help file table ------ */ +void UnLoadHelpFile(void) +{ + while (FirstHelp != NULL) { + ThisHelp = FirstHelp; + if (ThisHelp->hname != NULL) + free(ThisHelp->hname); + if (ThisHelp->PrevName != NULL) + free(ThisHelp->PrevName); + if (ThisHelp->NextName != NULL) + free(ThisHelp->NextName); + FirstHelp = ThisHelp->NextHelp; + free(ThisHelp); + } + ThisHelp = LastHelp = NULL; + free(HelpTree); + HelpTree = NULL; +} + +/* ---------- display a specified help text ----------- */ +BOOL DisplayHelp(DFWINDOW wnd, char *Help) +{ + BOOL rtn = FALSE; + if (Helping) + return TRUE; + wnd->isHelping++; + FindHelp(Help); + if (ThisHelp != NULL) { + if (LastStack == NULL || + stricmp(Help, LastStack->hname)) { + /* ---- add the window to the history stack ---- */ + ThisStack = DFcalloc(1,sizeof(struct HelpStack)); + ThisStack->hname = DFmalloc(strlen(Help)+1); + if (ThisStack->hname != NULL) + strcpy(ThisStack->hname, Help); + ThisStack->PrevStack = LastStack; + LastStack = ThisStack; + } + if ((helpfp = OpenHelpFile()) != NULL) { + DBOX *db; + int offset, i; + + db = DFcalloc(1,sizeof HelpBox); + memcpy(db, &HelpBox, sizeof HelpBox); + /* -- seek to the first line of the help text -- */ + SeekHelpLine(ThisHelp->hptr, ThisHelp->bit); + /* ----- read the title ----- */ + GetHelpLine(hline); + hline[strlen(hline)-1] = '\0'; + db->dwnd.title = DFmalloc(strlen(hline)+1); + strcpy(db->dwnd.title, hline); + /* ----- set the height and width ----- */ + db->dwnd.h = min(ThisHelp->hheight, MAXHEIGHT)+7; + db->dwnd.w = max(45, ThisHelp->hwidth+6); + /* ------ position the help window ----- */ + BestFit(wnd, &db->dwnd); + /* ------- position the command buttons ------ */ + db->ctl[0].dwnd.w = max(40, ThisHelp->hwidth+2); + db->ctl[0].dwnd.h = + min(ThisHelp->hheight, MAXHEIGHT)+2; + offset = (db->dwnd.w-40) / 2; + for (i = 1; i < 5; i++) { + db->ctl[i].dwnd.y = + min(ThisHelp->hheight, MAXHEIGHT)+3; + db->ctl[i].dwnd.x += offset; + } + /* ---- disable ineffective buttons ---- */ + if (ThisStack != NULL) + if (ThisStack->PrevStack == NULL) + DisableButton(db, ID_BACK); + if (ThisHelp->NextName == NULL) + DisableButton(db, ID_NEXT); + if (ThisHelp->PrevName == NULL) + DisableButton(db, ID_PREV); + /* ------- display the help window ----- */ + DfDialogBox(NULL, db, TRUE, HelpBoxProc); + free(db); + fclose(helpfp); + rtn = TRUE; + } + } + --wnd->isHelping; + return rtn; +} + +/* ------- display a definition window --------- */ +static void DisplayDefinition(DFWINDOW wnd, char *def) +{ + DFWINDOW dwnd; + DFWINDOW hwnd = wnd; + int y; + + if (GetClass(wnd) == POPDOWNMENU) + hwnd = GetParent(wnd); + y = GetClass(hwnd) == MENUBAR ? 2 : 1; + FindHelp(def); + if (ThisHelp != NULL) { + if ((helpfp = OpenHelpFile()) != NULL) { + dwnd = DfCreateWindow( + TEXTBOX, + NULL, + GetClientLeft(hwnd), + GetClientTop(hwnd)+y, + min(ThisHelp->hheight, MAXHEIGHT)+3, + ThisHelp->hwidth+2, + NULL, + wnd, + NULL, + HASBORDER | NOCLIP | SAVESELF); + if (dwnd != NULL) { + /* ----- read the help text ------- */ + SeekHelpLine(ThisHelp->hptr, ThisHelp->bit); + while (TRUE) { + if (GetHelpLine(hline) == NULL) + break; + if (*hline == '<') + break; + hline[strlen(hline)-1] = '\0'; + DfSendMessage(dwnd,ADDTEXT,(PARAM)hline,0); + } + DfSendMessage(dwnd, SHOW_WINDOW, 0, 0); + DfSendMessage(NULL, WAITKEYBOARD, 0, 0); + DfSendMessage(NULL, WAITMOUSE, 0, 0); + DfSendMessage(dwnd, CLOSE_WINDOW, 0, 0); + } + fclose(helpfp); + } + } +} + +/* ------ compare help names with wild cards ----- */ +static BOOL wildcmp(char *s1, char *s2) +{ + while (*s1 || *s2) { + if (tolower(*s1) != tolower(*s2)) + if (*s1 != '?' && *s2 != '?') + return TRUE; + s1++, s2++; + } + return FALSE; +} + +/* --- ThisHelp = the help window matching specified name --- */ +static void FindHelp(char *Help) +{ + ThisHelp = FirstHelp; + while (ThisHelp != NULL) { + if (wildcmp(Help, ThisHelp->hname) == FALSE) + break; + ThisHelp = ThisHelp->NextHelp; + } +} + +/* --- ThisHelp = the help window matching specified wnd --- */ +static void FindHelpWindow(DFWINDOW wnd) +{ + ThisHelp = FirstHelp; + while (ThisHelp != NULL) { + if (wnd == ThisHelp->hwnd) + break; + ThisHelp = ThisHelp->NextHelp; + } +} + +static int OverLap(int a, int b) +{ + int ov = a - b; + if (ov < 0) + ov = 0; + return ov; +} + +/* ----- compute the best location for a help dialogbox ----- */ +static void BestFit(DFWINDOW wnd, DIALOGWINDOW *dwnd) +{ + int above, below, right, left; + if (GetClass(wnd) == MENUBAR || + GetClass(wnd) == APPLICATION) { + dwnd->x = dwnd->y = -1; + return; + } + /* --- compute above overlap ---- */ + above = OverLap(dwnd->h, GetTop(wnd)); + /* --- compute below overlap ---- */ + below = OverLap(GetBottom(wnd), SCREENHEIGHT-dwnd->h); + /* --- compute right overlap ---- */ + right = OverLap(GetRight(wnd), SCREENWIDTH-dwnd->w); + /* --- compute left overlap ---- */ + left = OverLap(dwnd->w, GetLeft(wnd)); + + if (above < below) + dwnd->y = max(0, GetTop(wnd)-dwnd->h-2); + else + dwnd->y = min(SCREENHEIGHT-dwnd->h, GetBottom(wnd)+2); + if (right < left) + dwnd->x = min(GetRight(wnd)+2, SCREENWIDTH-dwnd->w); + else + dwnd->x = max(0, GetLeft(wnd)-dwnd->w-2); + + if (dwnd->x == GetRight(wnd)+2 || + dwnd->x == GetLeft(wnd)-dwnd->w-2) + dwnd->y = -1; + if (dwnd->y ==GetTop(wnd)-dwnd->h-2 || + dwnd->y == GetBottom(wnd)+2) + dwnd->x = -1; +} + +/* EOF */ diff --git a/rosapps/dflat32/htree.c b/rosapps/dflat32/htree.c new file mode 100644 index 00000000000..fb5b97613a0 --- /dev/null +++ b/rosapps/dflat32/htree.c @@ -0,0 +1,64 @@ +/* ------------------- htree.c -------------------- */ + +#include "dflat.h" +#include "htree.h" + +struct htree *ht; +int root; +int treect; + +/* ------ build a Huffman tree from a frequency array ------ */ +void buildtree(void) +{ + int i; + + treect = 256; + /* ---- preset node pointers to -1 ---- */ + for (i = 0; i < treect; i++) { + ht[i].parent = -1; + ht[i].right = -1; + ht[i].left = -1; + } + /* ---- build the huffman tree ----- */ + while (1) { + int h1 = -1, h2 = -1; + /* ---- find the two lowest frequencies ---- */ + for (i = 0; i < treect; i++) { + if (i != h1) { + struct htree *htt = ht+i; + /* --- find a node without a parent --- */ + if (htt->cnt > 0 && htt->parent == -1) { + /* ---- h1 & h2 -> lowest nodes ---- */ + if (h1 == -1 || htt->cnt < ht[h1].cnt) { + if (h2 == -1 || ht[h1].cnt < ht[h2].cnt) + h2 = h1; + h1 = i; + } + else if (h2 == -1 || htt->cnt < ht[h2].cnt) + h2 = i; + } + } + } + /* --- if only h1 -> a node, that's the root --- */ + if (h2 == -1) { + root = h1; + break; + } + /* --- combine two nodes and add one --- */ + ht[h1].parent = treect; + ht[h2].parent = treect; + ht = realloc(ht, (treect+1) * sizeof(struct htree)); + if (ht == NULL) + break; + /* --- the new node's frequency is the sum of the two + nodes with the lowest frequencies --- */ + ht[treect].cnt = ht[h1].cnt + ht[h2].cnt; + /* - the new node points to the two that it combines */ + ht[treect].right = h1; + ht[treect].left = h2; + /* --- the new node has no parent (yet) --- */ + ht[treect].parent = -1; + treect++; + } +} + diff --git a/rosapps/dflat32/htree.h b/rosapps/dflat32/htree.h new file mode 100644 index 00000000000..db25e0a3039 --- /dev/null +++ b/rosapps/dflat32/htree.h @@ -0,0 +1,31 @@ +/* ------------------- htree.h -------------------- */ + +#ifndef HTREE_H +#define HTREE_H + +typedef unsigned int BYTECOUNTER; + +/* ---- Huffman tree structure for building ---- */ +struct htree { + BYTECOUNTER cnt; /* character frequency */ + int parent; /* offset to parent node */ + int right; /* offset to right child node */ + int left; /* offset to left child node */ +}; + +/* ---- Huffman tree structure in compressed file ---- */ +struct htr { + int right; /* offset to right child node */ + int left; /* offset to left child node */ +}; + +extern struct htr *HelpTree; + +void buildtree(void); +FILE *OpenHelpFile(void); +void HelpFilePosition(long *, int *); +void *GetHelpLine(char *); +void SeekHelpLine(long, int); + +#endif + diff --git a/rosapps/dflat32/huffc.c b/rosapps/dflat32/huffc.c new file mode 100644 index 00000000000..98b1f761f03 --- /dev/null +++ b/rosapps/dflat32/huffc.c @@ -0,0 +1,118 @@ +/* ------------------- huffc.c -------------------- */ + +#include "dflat.h" +#include "htree.h" + +extern struct htree *ht; +extern int root; +extern int treect; +static int lastchar = '\n'; + +static void compress(FILE *, int, int); +static void outbit(FILE *fo, int bit); + +static int fgetcx(FILE *fi) +{ + int c; + + /* ------- bypass comments ------- */ + if ((c = fgetc(fi)) == ';' && lastchar == '\n') + do { + while (c != '\n' && c != EOF) + c = fgetc(fi); + } while (c == ';'); + lastchar = c; + return c; +} + +void main(int argc, char *argv[]) +{ + FILE *fi, *fo; + int c; + BYTECOUNTER bytectr = 0; + + if (argc < 3) { + printf("\nusage: huffc infile outfile"); + exit(1); + } + + if ((fi = fopen(argv[1], "rb")) == NULL) { + printf("\nCannot open %s", argv[1]); + exit(1); + } + if ((fo = fopen(argv[2], "wb")) == NULL) { + printf("\nCannot open %s", argv[2]); + fclose(fi); + exit(1); + } + + ht = calloc(256, sizeof(struct htree)); + + /* - read the input file and count character frequency - */ + while ((c = fgetcx(fi)) != EOF) { + c &= 255; + ht[c].cnt++; + bytectr++; + } + + /* ---- build the huffman tree ---- */ + buildtree(); + + /* --- write the byte count to the output file --- */ + fwrite(&bytectr, sizeof bytectr, 1, fo); + + /* --- write the tree count to the output file --- */ + fwrite(&treect, sizeof treect, 1, fo); + + /* --- write the root offset to the output file --- */ + fwrite(&root, sizeof root, 1, fo); + + /* -- write the tree to the output file -- */ + for (c = 256; c < treect; c++) { + int lf = ht[c].left; + int rt = ht[c].right; + fwrite(&lf, sizeof lf, 1, fo); + fwrite(&rt, sizeof rt, 1, fo); + } + + /* ------ compress the file ------ */ + fseek(fi, 0L, 0); + while ((c = fgetcx(fi)) != EOF) + compress(fo, (c & 255), 0); + outbit(fo, -1); + fclose(fi); + fclose(fo); + free(ht); + exit(0); +} + +/* ---- compress a character value into a bit stream ---- */ +static void compress(FILE *fo, int h, int child) +{ + if (ht[h].parent != -1) + compress(fo, ht[h].parent, h); + if (child) { + if (child == ht[h].right) + outbit(fo, 0); + else if (child == ht[h].left) + outbit(fo, 1); + } +} + +static char out8; +static int ct8; + +/* -- collect and write bits to the compressed output file -- */ +static void outbit(FILE *fo, int bit) +{ + if (ct8 == 8 || bit == -1) { + while (ct8 < 8) { + out8 <<= 1; + ct8++; + } + fputc(out8, fo); + ct8 = 0; + } + out8 = (out8 << 1) | bit; + ct8++; +} diff --git a/rosapps/dflat32/keys.c b/rosapps/dflat32/keys.c new file mode 100644 index 00000000000..1aeba0bb95c --- /dev/null +++ b/rosapps/dflat32/keys.c @@ -0,0 +1,86 @@ +/* ------------- keys.c ----------- */ + +#include +#include "keys.h" + +struct keys keys[] = { + {F1, "F1"}, + {F2, "F2"}, + {F3, "F3"}, + {F4, "F4"}, + {F5, "F5"}, + {F6, "F6"}, + {F7, "F7"}, + {F8, "F8"}, + {F9, "F9"}, + {F10, "F10"}, + {CTRL_F1, "Ctrl+F1"}, + {CTRL_F2, "Ctrl+F2"}, + {CTRL_F3, "Ctrl+F3"}, + {CTRL_F4, "Ctrl+F4"}, + {CTRL_F5, "Ctrl+F5"}, + {CTRL_F6, "Ctrl+F6"}, + {CTRL_F7, "Ctrl+F7"}, + {CTRL_F8, "Ctrl+F8"}, + {CTRL_F9, "Ctrl+F9"}, + {CTRL_F10, "Ctrl+F10"}, + {ALT_F1, "Alt+F1"}, + {ALT_F2, "Alt+F2"}, + {ALT_F3, "Alt+F3"}, + {ALT_F4, "Alt+F4"}, + {ALT_F5, "Alt+F5"}, + {ALT_F6, "Alt+F6"}, + {ALT_F7, "Alt+F7"}, + {ALT_F8, "Alt+F8"}, + {ALT_F9, "Alt+F9"}, + {ALT_F10, "Alt+F10"}, + {HOME, "Home"}, + {UP, "Up"}, + {PGUP, "PgUp"}, + {BS, "BS"}, + {END, "End"}, + {DN, "Dn"}, + {PGDN, "PgDn"}, + {INS, "Ins"}, + {DEL, "Del"}, + {CTRL_HOME, "Ctrl+Home"}, + {CTRL_PGUP, "Ctrl+PgUp"}, + {CTRL_BS, "Ctrl+BS"}, + {CTRL_END, "Ctrl+End"}, + {CTRL_PGDN, "Ctrl+PgDn"}, + {SHIFT_HT, "Shift+Tab"}, + {ALT_BS, "Alt+BS"}, + {ALT_DEL, "Alt+Del"}, + {SHIFT_DEL, "Shift+Del"}, + {SHIFT_INS, "Shift+Ins"}, + {CTRL_INS, "Ctrl+Ins"}, + {ALT_A, "Alt+A"}, + {ALT_B, "Alt+B"}, + {ALT_C, "Alt+C"}, + {ALT_D, "Alt+D"}, + {ALT_E, "Alt+E"}, + {ALT_F, "Alt+F"}, + {ALT_G, "Alt+G"}, + {ALT_H, "Alt+H"}, + {ALT_I, "Alt+I"}, + {ALT_J, "Alt+J"}, + {ALT_K, "Alt+K"}, + {ALT_L, "Alt+L"}, + {ALT_M, "Alt+M"}, + {ALT_N, "Alt+N"}, + {ALT_O, "Alt+O"}, + {ALT_P, "Alt+P"}, + {ALT_Q, "Alt+Q"}, + {ALT_R, "Alt+R"}, + {ALT_S, "Alt+S"}, + {ALT_T, "Alt+T"}, + {ALT_U, "Alt+U"}, + {ALT_V, "Alt+V"}, + {ALT_W, "Alt+W"}, + {ALT_X, "Alt+X"}, + {ALT_Y, "Alt+Y"}, + {ALT_Z, "Alt+Z"}, + {-1, NULL} +}; + +/* EOF */ diff --git a/rosapps/dflat32/keys.h b/rosapps/dflat32/keys.h new file mode 100644 index 00000000000..51707d889b6 --- /dev/null +++ b/rosapps/dflat32/keys.h @@ -0,0 +1,119 @@ +/* ----------- keys.h ------------ */ + +#ifndef KEYS_H +#define KEYS_H + +#define OFFSET 0x1000 + +#define RUBOUT 8 /* BACHSPACE KEY */ +#define BELL 7 +#define ESC 27 +#define ALT_BS (197+OFFSET) +#define ALT_DEL (184+OFFSET) +#define SHIFT_DEL (198+OFFSET) +#define CTRL_INS (186+OFFSET) +#define SHIFT_INS (185+OFFSET) +#define SHIFT_F8 (219+OFFSET) +#define F1 (187+OFFSET) +#define F2 (188+OFFSET) +#define F3 (189+OFFSET) +#define F4 (190+OFFSET) +#define F5 (191+OFFSET) +#define F6 (192+OFFSET) +#define F7 (193+OFFSET) +#define F8 (194+OFFSET) +#define F9 (195+OFFSET) +#define F10 (196+OFFSET) +#define CTRL_F1 (222+OFFSET) +#define CTRL_F2 (223+OFFSET) +#define CTRL_F3 (224+OFFSET) +#define CTRL_F4 (225+OFFSET) +#define CTRL_F5 (226+OFFSET) +#define CTRL_F6 (227+OFFSET) +#define CTRL_F7 (228+OFFSET) +#define CTRL_F8 (229+OFFSET) +#define CTRL_F9 (230+OFFSET) +#define CTRL_F10 (231+OFFSET) +#define ALT_F1 (232+OFFSET) +#define ALT_F2 (233+OFFSET) +#define ALT_F3 (234+OFFSET) +#define ALT_F4 (235+OFFSET) +#define ALT_F5 (236+OFFSET) +#define ALT_F6 (237+OFFSET) +#define ALT_F7 (238+OFFSET) +#define ALT_F8 (239+OFFSET) +#define ALT_F9 (240+OFFSET) +#define ALT_F10 (241+OFFSET) +#define HOME (199+OFFSET) +#define UP (200+OFFSET) +#define PGUP (201+OFFSET) +#define BS (203+OFFSET) /* CURSOR LEFT KEY */ +#define FWD (205+OFFSET) /* CURSOR RIGHT KEY */ +#define END (207+OFFSET) +#define DN (208+OFFSET) +#define PGDN (209+OFFSET) +#define INS (210+OFFSET) +#define DEL (211+OFFSET) +#define CTRL_HOME (247+OFFSET) +#define CTRL_PGUP (132+OFFSET) +#define CTRL_BS (243+OFFSET) +#define CTRL_FIVE (143+OFFSET) +#define CTRL_FWD (244+OFFSET) +#define CTRL_END (245+OFFSET) +#define CTRL_PGDN (246+OFFSET) +#define SHIFT_HT (143+OFFSET) +#define ALT_A (158+OFFSET) +#define ALT_B (176+OFFSET) +#define ALT_C (174+OFFSET) +#define ALT_D (160+OFFSET) +#define ALT_E (146+OFFSET) +#define ALT_F (161+OFFSET) +#define ALT_G (162+OFFSET) +#define ALT_H (163+OFFSET) +#define ALT_I (151+OFFSET) +#define ALT_J (164+OFFSET) +#define ALT_K (165+OFFSET) +#define ALT_L (166+OFFSET) +#define ALT_M (178+OFFSET) +#define ALT_N (177+OFFSET) +#define ALT_O (152+OFFSET) +#define ALT_P (153+OFFSET) +#define ALT_Q (144+OFFSET) +#define ALT_R (147+OFFSET) +#define ALT_S (159+OFFSET) +#define ALT_T (148+OFFSET) +#define ALT_U (150+OFFSET) +#define ALT_V (175+OFFSET) +#define ALT_W (145+OFFSET) +#define ALT_X (173+OFFSET) +#define ALT_Y (149+OFFSET) +#define ALT_Z (172+OFFSET) +#define ALT_1 (0xf8+OFFSET) +#define ALT_2 (0xf9+OFFSET) +#define ALT_3 (0xfa+OFFSET) +#define ALT_4 (0xfb+OFFSET) +#define ALT_5 (0xfc+OFFSET) +#define ALT_6 (0xfd+OFFSET) +#define ALT_7 (0xfe+OFFSET) +#define ALT_8 (0xff+OFFSET) +#define ALT_9 (0x80+OFFSET) +#define ALT_0 (0x81+OFFSET) +#define ALT_HYPHEN (130+OFFSET) + +#define RIGHTSHIFT 0x01 +#define LEFTSHIFT 0x02 +#define CTRLKEY 0x04 +#define ALTKEY 0x08 +#define SCROLLLOCK 0x10 +#define NUMLOCK 0x20 +#define CAPSLOCK 0x40 +#define INSERTKEY 0x80 + +struct keys { + int keycode; + char *keylabel; +}; +extern struct keys keys[]; + +#endif + diff --git a/rosapps/dflat32/listbox.c b/rosapps/dflat32/listbox.c new file mode 100644 index 00000000000..cc31110fb40 --- /dev/null +++ b/rosapps/dflat32/listbox.c @@ -0,0 +1,469 @@ +/* ------------- listbox.c ------------ */ + +#include "dflat.h" + +#ifdef INCLUDE_EXTENDEDSELECTIONS +static int ExtendSelections(DFWINDOW, int, int); +static void TestExtended(DFWINDOW, PARAM); +static void ClearAllSelections(DFWINDOW); +static void SetSelection(DFWINDOW, int); +static void FlipSelection(DFWINDOW, int); +static void ClearSelection(DFWINDOW, int); +#else +#define TestExtended(w,p) /**/ +#endif +static void ChangeSelection(DFWINDOW, int, int); +static void WriteSelection(DFWINDOW, int, int, DFRECT *); +static BOOL SelectionInWindow(DFWINDOW, int); + +static int py = -1; /* the previous y mouse coordinate */ + +#ifdef INCLUDE_EXTENDEDSELECTIONS +/* --------- SHIFT_F8 Key ------------ */ +static void AddModeKey(DFWINDOW wnd) +{ + if (isMultiLine(wnd)) { + wnd->AddMode ^= TRUE; + DfSendMessage(GetParent(wnd), ADDSTATUS, + wnd->AddMode ? ((PARAM) "Add Mode") : 0, 0); + } +} +#endif + +/* --------- UP (Up Arrow) Key ------------ */ +static void UpKey(DFWINDOW wnd, PARAM p2) +{ + if (wnd->selection > 0) { + if (wnd->selection == wnd->wtop) { + BaseWndProc(LISTBOX, wnd, KEYBOARD, UP, p2); + DfPostMessage(wnd, LB_SELECTION, wnd->selection-1, + isMultiLine(wnd) ? p2 : FALSE); + } + else { + int newsel = wnd->selection-1; + if (wnd->wlines == ClientHeight(wnd)) + while (*TextLine(wnd, newsel) == LINE) + --newsel; + DfPostMessage(wnd, LB_SELECTION, newsel, +#ifdef INCLUDE_EXTENDEDSELECTIONS + isMultiLine(wnd) ? p2 : +#endif + FALSE); + } + } +} + +/* --------- DN (Down Arrow) Key ------------ */ +static void DnKey(DFWINDOW wnd, PARAM p2) +{ + if (wnd->selection < wnd->wlines-1) { + if (wnd->selection == wnd->wtop+ClientHeight(wnd)-1) { + BaseWndProc(LISTBOX, wnd, KEYBOARD, DN, p2); + DfPostMessage(wnd, LB_SELECTION, wnd->selection+1, + isMultiLine(wnd) ? p2 : FALSE); + } + else { + int newsel = wnd->selection+1; + if (wnd->wlines == ClientHeight(wnd)) + while (*TextLine(wnd, newsel) == LINE) + newsel++; + DfPostMessage(wnd, LB_SELECTION, newsel, +#ifdef INCLUDE_EXTENDEDSELECTIONS + isMultiLine(wnd) ? p2 : +#endif + FALSE); + } + } +} + +/* --------- HOME and PGUP Keys ------------ */ +static void HomePgUpKey(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + BaseWndProc(LISTBOX, wnd, KEYBOARD, p1, p2); + DfPostMessage(wnd, LB_SELECTION, wnd->wtop, +#ifdef INCLUDE_EXTENDEDSELECTIONS + isMultiLine(wnd) ? p2 : +#endif + FALSE); +} + +/* --------- END and PGDN Keys ------------ */ +static void EndPgDnKey(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int bot; + BaseWndProc(LISTBOX, wnd, KEYBOARD, p1, p2); + bot = wnd->wtop+ClientHeight(wnd)-1; + if (bot > wnd->wlines-1) + bot = wnd->wlines-1; + DfPostMessage(wnd, LB_SELECTION, bot, +#ifdef INCLUDE_EXTENDEDSELECTIONS + isMultiLine(wnd) ? p2 : +#endif + FALSE); +} + +#ifdef INCLUDE_EXTENDEDSELECTIONS +/* --------- Space Bar Key ------------ */ +static void SpacebarKey(DFWINDOW wnd, PARAM p2) +{ + if (isMultiLine(wnd)) { + int sel = DfSendMessage(wnd, LB_CURRENTSELECTION, 0, 0); + if (sel != -1) { + if (wnd->AddMode) + FlipSelection(wnd, sel); + if (ItemSelected(wnd, sel)) { + if (!((int) p2 & (LEFTSHIFT | RIGHTSHIFT))) + wnd->AnchorPoint = sel; + ExtendSelections(wnd, sel, (int) p2); + } + else + wnd->AnchorPoint = -1; + DfSendMessage(wnd, PAINT, 0, 0); + } + } +} +#endif + +/* --------- Enter ('\r') Key ------------ */ +static void EnterKey(DFWINDOW wnd) +{ + if (wnd->selection != -1) { + DfSendMessage(wnd, LB_SELECTION, wnd->selection, TRUE); + DfSendMessage(wnd, LB_CHOOSE, wnd->selection, 0); + } +} + +/* --------- All Other Key Presses ------------ */ +static void KeyPress(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int sel = wnd->selection+1; + while (sel < wnd->wlines) { + char *cp = TextLine(wnd, sel); + if (cp == NULL) + break; +#ifdef INCLUDE_EXTENDEDSELECTIONS + if (isMultiLine(wnd)) + cp++; +#endif + /* --- special for directory list box --- */ + if (*cp == '[') + cp++; + if (tolower(*cp) == (int)p1) { + DfSendMessage(wnd, LB_SELECTION, sel, + isMultiLine(wnd) ? p2 : FALSE); + if (!SelectionInWindow(wnd, sel)) { + wnd->wtop = sel-ClientHeight(wnd)+1; + DfSendMessage(wnd, PAINT, 0, 0); + } + break; + } + sel++; + } +} + +/* --------- KEYBOARD Message ------------ */ +static int KeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + switch ((int) p1) { +#ifdef INCLUDE_EXTENDEDSELECTIONS + case SHIFT_F8: + AddModeKey(wnd); + return TRUE; +#endif + case UP: + TestExtended(wnd, p2); + UpKey(wnd, p2); + return TRUE; + case DN: + TestExtended(wnd, p2); + DnKey(wnd, p2); + return TRUE; + case PGUP: + case HOME: + TestExtended(wnd, p2); + HomePgUpKey(wnd, p1, p2); + return TRUE; + case PGDN: + case END: + TestExtended(wnd, p2); + EndPgDnKey(wnd, p1, p2); + return TRUE; +#ifdef INCLUDE_EXTENDEDSELECTIONS + case ' ': + SpacebarKey(wnd, p2); + break; +#endif + case '\r': + EnterKey(wnd); + return TRUE; + default: + KeyPress(wnd, p1, p2); + break; + } + return FALSE; +} + +/* ------- LEFT_BUTTON Message -------- */ +static int LeftButtonMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int my = (int) p2 - GetTop(wnd); + if (my >= wnd->wlines-wnd->wtop) + my = wnd->wlines - wnd->wtop; + + if (!InsideRect(p1, p2, ClientRect(wnd))) + return FALSE; + if (wnd->wlines && my != py) { + int sel = wnd->wtop+my-1; +#ifdef INCLUDE_EXTENDEDSELECTIONS + int sh = getshift(); + if (!(sh & (LEFTSHIFT | RIGHTSHIFT))) { + if (!(sh & CTRLKEY)) + ClearAllSelections(wnd); + wnd->AnchorPoint = sel; + DfSendMessage(wnd, PAINT, 0, 0); + } +#endif + DfSendMessage(wnd, LB_SELECTION, sel, TRUE); + py = my; + } + return TRUE; +} + +/* ------------- DOUBLE_CLICK Message ------------ */ +static int DoubleClickMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + if (WindowMoving || WindowSizing) + return FALSE; + if (wnd->wlines) { + DFRECT rc = ClientRect(wnd); + BaseWndProc(LISTBOX, wnd, DOUBLE_CLICK, p1, p2); + if (InsideRect(p1, p2, rc)) + DfSendMessage(wnd, LB_CHOOSE, wnd->selection, 0); + } + return TRUE; +} + +/* ------------ ADDTEXT Message -------------- */ +static int AddTextMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int rtn = BaseWndProc(LISTBOX, wnd, ADDTEXT, p1, p2); + if (wnd->selection == -1) + DfSendMessage(wnd, LB_SETSELECTION, 0, 0); +#ifdef INCLUDE_EXTENDEDSELECTIONS + if (*(char *)p1 == LISTSELECTOR) + wnd->SelectCount++; +#endif + return rtn; +} + +/* --------- GETTEXT Message ------------ */ +static void GetTextMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + if ((int)p2 != -1) { + char *cp1 = (char *)p1; + char *cp2 = TextLine(wnd, (int)p2); + while (cp2 && *cp2 && *cp2 != '\n') + *cp1++ = *cp2++; + *cp1 = '\0'; + } +} + +/* --------- LISTBOX Window Processing Module ------------ */ +int ListBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + BaseWndProc(LISTBOX, wnd, msg, p1, p2); + wnd->selection = -1; +#ifdef INCLUDE_EXTENDEDSELECTIONS + wnd->AnchorPoint = -1; +#endif + return TRUE; + case KEYBOARD: + if (WindowMoving || WindowSizing) + break; + if (KeyboardMsg(wnd, p1, p2)) + return TRUE; + break; + case LEFT_BUTTON: + if (LeftButtonMsg(wnd, p1, p2) == TRUE) + return TRUE; + break; + case DOUBLE_CLICK: + if (DoubleClickMsg(wnd, p1, p2)) + return TRUE; + break; + case DFM_BUTTON_RELEASED: + if (WindowMoving || WindowSizing || VSliding) + break; + py = -1; + return TRUE; + case ADDTEXT: + return AddTextMsg(wnd, p1, p2); + case DFM_LB_GETTEXT: + GetTextMsg(wnd, p1, p2); + return TRUE; + case CLEARTEXT: + wnd->selection = -1; +#ifdef INCLUDE_EXTENDEDSELECTIONS + wnd->AnchorPoint = -1; +#endif + wnd->SelectCount = 0; + break; + case PAINT: + BaseWndProc(LISTBOX, wnd, msg, p1, p2); + WriteSelection(wnd, wnd->selection, TRUE, (DFRECT *)p1); + return TRUE; + case SCROLL: + case HORIZSCROLL: + case SCROLLPAGE: + case HORIZPAGE: + case SCROLLDOC: + BaseWndProc(LISTBOX, wnd, msg, p1, p2); + WriteSelection(wnd,wnd->selection,TRUE,NULL); + return TRUE; + case LB_CHOOSE: + DfSendMessage(GetParent(wnd), LB_CHOOSE, p1, p2); + return TRUE; + case LB_SELECTION: + ChangeSelection(wnd, (int) p1, (int) p2); + DfSendMessage(GetParent(wnd), LB_SELECTION, + wnd->selection, 0); + return TRUE; + case LB_CURRENTSELECTION: + return wnd->selection; + case LB_SETSELECTION: + ChangeSelection(wnd, (int) p1, 0); + return TRUE; +#ifdef INCLUDE_EXTENDEDSELECTIONS + case CLOSE_WINDOW: + if (isMultiLine(wnd) && wnd->AddMode) { + wnd->AddMode = FALSE; + DfSendMessage(GetParent(wnd), ADDSTATUS, 0, 0); + } + break; +#endif + default: + break; + } + return BaseWndProc(LISTBOX, wnd, msg, p1, p2); +} + +static BOOL SelectionInWindow(DFWINDOW wnd, int sel) +{ + return (wnd->wlines && sel >= wnd->wtop && + sel < wnd->wtop+ClientHeight(wnd)); +} + +static void WriteSelection(DFWINDOW wnd, int sel, + int reverse, DFRECT *rc) +{ + if (isVisible(wnd)) + if (SelectionInWindow(wnd, sel)) + WriteTextLine(wnd, rc, sel, reverse); +} + +#ifdef INCLUDE_EXTENDEDSELECTIONS +/* ----- Test for extended selections in the listbox ----- */ +static void TestExtended(DFWINDOW wnd, PARAM p2) +{ + if (isMultiLine(wnd) && !wnd->AddMode && + !((int) p2 & (LEFTSHIFT | RIGHTSHIFT))) { + if (wnd->SelectCount > 1) { + ClearAllSelections(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + } + } +} + +/* ----- Clear selections in the listbox ----- */ +static void ClearAllSelections(DFWINDOW wnd) +{ + if (isMultiLine(wnd) && wnd->SelectCount > 0) { + int sel; + for (sel = 0; sel < wnd->wlines; sel++) + ClearSelection(wnd, sel); + } +} + +/* ----- Invert a selection in the listbox ----- */ +static void FlipSelection(DFWINDOW wnd, int sel) +{ + if (isMultiLine(wnd)) { + if (ItemSelected(wnd, sel)) + ClearSelection(wnd, sel); + else + SetSelection(wnd, sel); + } +} + +static int ExtendSelections(DFWINDOW wnd, int sel, int shift) +{ + if (shift & (LEFTSHIFT | RIGHTSHIFT) && + wnd->AnchorPoint != -1) { + int i = sel; + int j = wnd->AnchorPoint; + int rtn; + if (j > i) + swap(i,j); + rtn = i - j; + while (j <= i) + SetSelection(wnd, j++); + return rtn; + } + return 0; +} + +static void SetSelection(DFWINDOW wnd, int sel) +{ + if (isMultiLine(wnd) && !ItemSelected(wnd, sel)) { + char *lp = TextLine(wnd, sel); + *lp = LISTSELECTOR; + wnd->SelectCount++; + } +} + +static void ClearSelection(DFWINDOW wnd, int sel) +{ + if (isMultiLine(wnd) && ItemSelected(wnd, sel)) { + char *lp = TextLine(wnd, sel); + *lp = ' '; + --wnd->SelectCount; + } +} + +BOOL ItemSelected(DFWINDOW wnd, int sel) +{ + if (sel != -1 && isMultiLine(wnd) && sel < wnd->wlines) { + char *cp = TextLine(wnd, sel); + return (int)((*cp) & 255) == LISTSELECTOR; + } + return FALSE; +} +#endif + +static void ChangeSelection(DFWINDOW wnd,int sel,int shift) +{ + if (sel != wnd->selection) { +#ifdef INCLUDE_EXTENDEDSELECTIONS + if (isMultiLine(wnd)) { + int sels; + if (!wnd->AddMode) + ClearAllSelections(wnd); + sels = ExtendSelections(wnd, sel, shift); + if (sels > 1) + DfSendMessage(wnd, PAINT, 0, 0); + if (sels == 0 && !wnd->AddMode) { + ClearSelection(wnd, wnd->selection); + SetSelection(wnd, sel); + wnd->AnchorPoint = sel; + } + } +#endif + WriteSelection(wnd, wnd->selection, FALSE, NULL); + wnd->selection = sel; + WriteSelection(wnd, sel, TRUE, NULL); + } +} + +/* EOF */ diff --git a/rosapps/dflat32/lists.c b/rosapps/dflat32/lists.c new file mode 100644 index 00000000000..f907293ff61 --- /dev/null +++ b/rosapps/dflat32/lists.c @@ -0,0 +1,152 @@ +/* --------------- lists.c -------------- */ + +#include "dflat.h" + +/* ----- set focus to the next sibling ----- */ +void SetNextFocus (void) +{ + if (inFocus != NULL) + { + DFWINDOW wnd1 = inFocus, pwnd; + while (TRUE) + { + pwnd = GetParent(wnd1); + if (NextWindow(wnd1) != NULL) + wnd1 = NextWindow(wnd1); + else if (pwnd != NULL) + wnd1 = FirstWindow(pwnd); + if (wnd1 == NULL || wnd1 == inFocus) + { + wnd1 = pwnd; + break; + } + if (GetClass(wnd1) == STATUSBAR || GetClass(wnd1) == MENUBAR) + continue; + if (isVisible(wnd1)) + break; + } + if (wnd1 != NULL) + { + while (wnd1->childfocus != NULL) + wnd1 = wnd1->childfocus; + if (wnd1->condition != ISCLOSING) + DfSendMessage(wnd1, SETFOCUS, TRUE, 0); + } + } +} + +/* ----- set focus to the previous sibling ----- */ +void SetPrevFocus(void) +{ + if (inFocus != NULL) + { + DFWINDOW wnd1 = inFocus, pwnd; + while (TRUE) + { + pwnd = GetParent(wnd1); + if (PrevWindow(wnd1) != NULL) + wnd1 = PrevWindow(wnd1); + else if (pwnd != NULL) + wnd1 = LastWindow(pwnd); + if (wnd1 == NULL || wnd1 == inFocus) + { + wnd1 = pwnd; + break; + } + if (GetClass(wnd1) == STATUSBAR) + continue; + if (isVisible(wnd1)) + break; + } + if (wnd1 != NULL) + { + while (wnd1->childfocus != NULL) + wnd1 = wnd1->childfocus; + if (wnd1->condition != ISCLOSING) + DfSendMessage(wnd1, SETFOCUS, TRUE, 0); + } + } +} + +/* ------- move a window to the end of its parents list ----- */ +void ReFocus(DFWINDOW wnd) +{ + if (GetParent(wnd) != NULL) + { + RemoveWindow(wnd); + AppendWindow(wnd); + ReFocus(GetParent(wnd)); + } +} + +/* ---- remove a window from the linked list ---- */ +void RemoveWindow(DFWINDOW wnd) +{ + if (wnd != NULL) { + DFWINDOW pwnd = GetParent(wnd); + if (PrevWindow(wnd) != NULL) + NextWindow(PrevWindow(wnd)) = NextWindow(wnd); + if (NextWindow(wnd) != NULL) + PrevWindow(NextWindow(wnd)) = PrevWindow(wnd); + if (pwnd != NULL) { + if (wnd == FirstWindow(pwnd)) + FirstWindow(pwnd) = NextWindow(wnd); + if (wnd == LastWindow(pwnd)) + LastWindow(pwnd) = PrevWindow(wnd); + } + } +} + +/* ---- append a window to the linked list ---- */ +void AppendWindow(DFWINDOW wnd) +{ + if (wnd != NULL) + { + DFWINDOW pwnd = GetParent(wnd); + if (pwnd != NULL) + { +/* + if (FirstWindow(pwnd) == NULL) + FirstWindow(pwnd) = wnd; + if (LastWindow(pwnd) != NULL) + NextWindow(LastWindow(pwnd)) = wnd; + PrevWindow(wnd) = LastWindow(pwnd); + LastWindow(pwnd) = wnd; +*/ + if (FirstWindow(pwnd) == NULL) + { + FirstWindow(pwnd) = wnd; + LastWindow(pwnd) = wnd; + PrevWindow(wnd) = NULL; + } + else + { + NextWindow(LastWindow(pwnd)) = wnd; + PrevWindow(wnd) = LastWindow(pwnd); + LastWindow(pwnd) = wnd; + } + } + NextWindow(wnd) = NULL; + } +} + +/* ----- if document windows and statusbar or menubar get the focus, + pass it on ------- */ +void SkipApplicationControls(void) +{ + BOOL EmptyAppl = FALSE; + int ct = 0; + while (!EmptyAppl && inFocus != NULL) + { + DFCLASS cl = GetClass(inFocus); + if (cl == MENUBAR || cl == STATUSBAR) + { + SetPrevFocus(); + EmptyAppl = (cl == MENUBAR && ct++); + } + else + break; + } +} + +/* EOF */ diff --git a/rosapps/dflat32/log.c b/rosapps/dflat32/log.c new file mode 100644 index 00000000000..d947d3d16d9 --- /dev/null +++ b/rosapps/dflat32/log.c @@ -0,0 +1,75 @@ +/* ------------ log .c ------------ */ + +#include "dflat.h" + +#ifdef INCLUDE_LOGGING + +static char *message[] = { + #undef DFlatMsg + #define DFlatMsg(m) " " #m, + #include "dflatmsg.h" + NULL +}; + +static FILE *logfile = NULL; +extern DBOX Log; + +void LogMessages (DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + if (logfile != NULL && message[msg][0] != ' ') + fprintf(logfile, + "%-20.20s %-12.12s %-20.20s, %5.5ld, %5.5ld\n", + wnd ? (GetTitle(wnd) ? GetTitle(wnd) : "") : "", + wnd ? ClassNames[GetClass(wnd)] : "", + message[msg]+1, p1, p2); +} + +static int LogProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + DFWINDOW cwnd = ControlWindow(&Log, ID_LOGLIST); + char **mn = message; + switch (msg) { + case INITIATE_DIALOG: + AddAttribute(cwnd, MULTILINE | VSCROLLBAR); + while (*mn) { + DfSendMessage(cwnd, ADDTEXT, (PARAM) (*mn), 0); + mn++; + } + DfSendMessage(cwnd, SHOW_WINDOW, 0, 0); + break; + case DFM_COMMAND: + if ((int) p1 == ID_OK) { + int item; + int tl = GetTextLines(cwnd); + for (item = 0; item < tl; item++) + if (ItemSelected(cwnd, item)) + mn[item][0] = LISTSELECTOR; + } + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +void MessageLog(DFWINDOW wnd) +{ + if (DfDialogBox(wnd, &Log, TRUE, LogProc)) + { + if (CheckBoxSetting(&Log, ID_LOGGING)) + { + logfile = fopen("DFLAT.LOG", "wt"); + SetCommandToggle(&MainMenu, ID_LOG); + } + else if (logfile != NULL) + { + fclose(logfile); + logfile = NULL; + ClearCommandToggle(&MainMenu, ID_LOG); + } + } +} + +#endif + +/* EOF */ \ No newline at end of file diff --git a/rosapps/dflat32/makefile b/rosapps/dflat32/makefile new file mode 100644 index 00000000000..6391be09e58 --- /dev/null +++ b/rosapps/dflat32/makefile @@ -0,0 +1,56 @@ +# +# ReactOS makefile for D-Flat/32 +# + +TARGET=edit.exe + +all: $(TARGET) + +OBJECTS = applicat.o barchart.o box.o button.o calendar.o checkbox.o clipbord.o \ + combobox.o config.o console.o decomp.o dfalloc.o dialbox.o dialogs.o \ + direct.o edit.o editbox.o fileopen.o helpbox.o htree.o keys.o \ + listbox.o lists.o log.o menu.o menubar.o menus.o message.o msgbox.o \ + normal.o pictbox.o popdown.o radio.o rect.o search.o slidebox.o spinbutt.o \ + statbar.o sysmenu.o text.o textbox.o video.o watch.o window.o + +CLEAN_FILES = *.o *.exe *.sym *.coff + + +edit.exe: $(OBJECTS) + $(CC) $(OBJECTS) -lkernel32 -lcrtdll -luser32 -o edit.exe + $(NM) --numeric-sort edit.exe > edit.sym + + +clean: $(CLEAN_FILES:%=%_clean) + +$(CLEAN_FILES:%=%_clean): %_clean: + - $(RM) $* + +.phony: clean $(CLEAN_FILES:%=%_clean) + + +floppy: $(TARGET:%=$(FLOPPY_DIR)/apps/%) + +$(TARGET:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* $(FLOPPY_DIR)\apps\$* +else + $(CP) $* $(FLOPPY_DIR)/apps/$* +endif + + +dist: $(TARGET:%=../$(DIST_DIR)/apps/%) + +$(TARGET:%=../$(DIST_DIR)/apps/%): ../$(DIST_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* ..\$(DIST_DIR)\apps\$* +else + $(CP) $* ../$(DIST_DIR)/apps\$* +endif + + +WITH_DEBUGGING=yes + +include ../rules.mak + +# EOF diff --git a/rosapps/dflat32/memopad.c b/rosapps/dflat32/memopad.c new file mode 100644 index 00000000000..b94a924f604 --- /dev/null +++ b/rosapps/dflat32/memopad.c @@ -0,0 +1,638 @@ +/* --------------- memopad.c ----------- */ + +#include "dflat.h" + +extern DBOX PrintSetup; + +char DFlatApplication[] = "MemoPad"; + +static char Untitled[] = "Untitled"; +static int wndpos; + +static int MemoPadProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static void NewFile(DFWINDOW); +static void SelectFile(DFWINDOW); +static void PadWindow(DFWINDOW, char *); +static void OpenPadWindow(DFWINDOW, char *); +static void LoadFile(DFWINDOW); +static void PrintPad(DFWINDOW); +static void SaveFile(DFWINDOW, int); +static void MemoPadDeleteFile(DFWINDOW); +static int EditorProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static char *NameComponent(char *); +static int PrintSetupProc(DFWINDOW, DFMESSAGE, PARAM, PARAM); +static void FixTabMenu(void); +#ifndef TURBOC +void Calendar(DFWINDOW); +#endif +//void BarChart(DFWINDOW); +char **Argv; + +#define CHARSLINE 80 +#define LINESPAGE 66 + +void main(int argc, char *argv[]) +{ + DFWINDOW wnd; + if (!init_messages()) + return; + Argv = argv; + LoadConfig(); +// if (!LoadConfig()) +// cfg.ScreenLines = SCREENHEIGHT; + wnd = DfCreateWindow(APPLICATION, + "FreeDos Edit " VERSION, + 0, 0, -1, -1, + &MainMenu, + NULL, + MemoPadProc, + MOVEABLE | + SIZEABLE | + HASBORDER | + MINMAXBOX | + HASSTATUSBAR + ); + + LoadHelpFile(); + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + while (argc > 1) { + PadWindow(wnd, argv[1]); + --argc; + argv++; + } + while (dispatch_message()) + ; +} + +/* ------ open text files and put them into editboxes ----- */ +static void PadWindow(DFWINDOW wnd, char *FileName) +{ + int ax; + struct _finddata_t ff; + char path[64]; + char *cp; + + CreatePath(path, FileName, FALSE, FALSE); + cp = path+strlen(path); + CreatePath(path, FileName, TRUE, FALSE); + ax = _findfirst(path, &ff); + if (ax == -1) + return; + do + { + strcpy(cp, ff.name); + OpenPadWindow(wnd, path); + } + while (_findnext (ax, &ff) == 0); + _findclose (ax); +} + + +/* ------- window processing module for the + memopad application window ----- */ +static int MemoPadProc(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + int rtn; + switch (msg) { + case CREATE_WINDOW: + rtn = DefaultWndProc(wnd, msg, p1, p2); + if (cfg.InsertMode) + SetCommandToggle(&MainMenu, ID_INSERT); + if (cfg.WordWrap) + SetCommandToggle(&MainMenu, ID_WRAP); + FixTabMenu(); + return rtn; + case DFM_COMMAND: + switch ((int)p1) { + case ID_NEW: + NewFile(wnd); + return TRUE; + case ID_OPEN: + SelectFile(wnd); + return TRUE; + case ID_SAVE: + SaveFile(inFocus, FALSE); + return TRUE; + case ID_SAVEAS: + SaveFile(inFocus, TRUE); + return TRUE; + case ID_DELETEFILE: + MemoPadDeleteFile(inFocus); + return TRUE; + case ID_PRINTSETUP: + DfDialogBox(wnd, &PrintSetup, TRUE, PrintSetupProc); + return TRUE; + case ID_PRINT: + PrintPad(inFocus); + return TRUE; + case ID_EXIT: + if (!DfYesNoBox("Exit Memopad?")) + return FALSE; + break; + case ID_WRAP: + cfg.WordWrap = GetCommandToggle(&MainMenu, ID_WRAP); + return TRUE; + case ID_INSERT: + cfg.InsertMode = GetCommandToggle(&MainMenu, ID_INSERT); + return TRUE; + case ID_TAB2: + cfg.Tabs = 2; + FixTabMenu(); + return TRUE; + case ID_TAB4: + cfg.Tabs = 4; + FixTabMenu(); + return TRUE; + case ID_TAB6: + cfg.Tabs = 6; + FixTabMenu(); + return TRUE; + case ID_TAB8: + cfg.Tabs = 8; + FixTabMenu(); + return TRUE; + case ID_CALENDAR: +#ifndef TURBOC + Calendar(wnd); +#endif + return TRUE; +// case ID_BARCHART: +// BarChart(wnd); +// return TRUE; + case ID_ABOUT: + DfMessageBox( + "About D-Flat and the MemoPad", + " ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n" + " ³ ÜÜÜ ÜÜÜ Ü ³\n" + " ³ Û Û Û Û Û ³\n" + " ³ Û Û Û Û Û ³\n" + " ³ Û Û Û Û Û Û ³\n" + " ³ ßßß ßßß ßß ³\n" + " ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n" + "D-Flat implements the SAA/CUA\n" + "interface in a public domain\n" + "C language library originally\n" + "published in Dr. Dobb's Journal\n" + " ------------------------ \n" + "MemoPad is a multiple document\n" + "editor that demonstrates D-Flat"); + return TRUE; + default: + break; + } + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} +/* --- The New command. Open an empty editor window --- */ +static void NewFile(DFWINDOW wnd) +{ + OpenPadWindow(wnd, Untitled); +} +/* --- The Open... command. Select a file --- */ +static void SelectFile(DFWINDOW wnd) +{ + char FileName[64]; + if (OpenFileDialogBox("*.PAD", FileName)) { + /* --- see if the document is already in a window --- */ + DFWINDOW wnd1 = FirstWindow(wnd); + while (wnd1 != NULL) { + if (stricmp(FileName, wnd1->extension) == 0) { + DfSendMessage(wnd1, SETFOCUS, TRUE, 0); + DfSendMessage(wnd1, RESTORE, 0, 0); + return; + } + wnd1 = NextWindow(wnd1); + } + OpenPadWindow(wnd, FileName); + } +} + +/* --- open a document window and load a file --- */ +static void OpenPadWindow(DFWINDOW wnd, char *FileName) +{ + static DFWINDOW wnd1 = NULL; + DFWINDOW wwnd; + struct stat sb; + char *Fname = FileName; + char *ermsg; + if (strcmp(FileName, Untitled)) { + if (stat(FileName, &sb)) { + ermsg = DFmalloc(strlen(FileName)+20); + strcpy(ermsg, "No such file as\n"); + strcat(ermsg, FileName); + DfErrorMessage(ermsg); + free(ermsg); + return; + } + Fname = NameComponent(FileName); + } + wwnd = WatchIcon(); + wndpos += 2; + if (wndpos == 20) + wndpos = 2; + wnd1 = DfCreateWindow(EDITBOX, + Fname, + (wndpos-1)*2, wndpos, 10, 40, + NULL, wnd, EditorProc, + SHADOW | + MINMAXBOX | + CONTROLBOX | + VSCROLLBAR | + HSCROLLBAR | + MOVEABLE | + HASBORDER | + SIZEABLE | + MULTILINE + ); + if (strcmp(FileName, Untitled)) { + wnd1->extension = DFmalloc(strlen(FileName)+1); + strcpy(wnd1->extension, FileName); + LoadFile(wnd1); + } + DfSendMessage(wwnd, CLOSE_WINDOW, 0, 0); + DfSendMessage(wnd1, SETFOCUS, TRUE, 0); + DfSendMessage(wnd1, MAXIMIZE, 0, 0); +} + +/* --- Load the notepad file into the editor text buffer --- */ +static void LoadFile(DFWINDOW wnd) +{ + char *Buf = NULL; + int recptr = 0; + FILE *fp; + + if ((fp = fopen(wnd->extension, "rt")) != NULL) { + while (!feof(fp)) { + handshake(); + Buf = DFrealloc(Buf, recptr+150); + memset(Buf+recptr, 0, 150); + fgets(Buf+recptr, 150, fp); + recptr += strlen(Buf+recptr); + } + fclose(fp); + if (Buf != NULL) { + DfSendMessage(wnd, SETTEXT, (PARAM) Buf, 0); + free(Buf); + } + } +} + +static int LineCtr; +static int CharCtr; + +/* ------- print a character -------- */ +static void PrintChar(FILE *prn, int c) +{ + int i; + if (c == '\n' || CharCtr == cfg.RightMargin) { + fputs("\r\n", prn); + LineCtr++; + if (LineCtr == cfg.BottomMargin) { + fputc('\f', prn); + for (i = 0; i < cfg.TopMargin; i++) + fputc('\n', prn); + LineCtr = cfg.TopMargin; + } + CharCtr = 0; + if (c == '\n') + return; + } + if (CharCtr == 0) { + for (i = 0; i < cfg.LeftMargin; i++) { + fputc(' ', prn); + CharCtr++; + } + } + CharCtr++; + fputc(c, prn); +} + +/* --- print the current notepad --- */ +static void PrintPad(DFWINDOW wnd) +{ + if (*cfg.PrinterPort) { + FILE *prn; + if ((prn = fopen(cfg.PrinterPort, "wt")) != NULL) { + long percent; + BOOL KeepPrinting = TRUE; + unsigned char *text = GetText(wnd); + unsigned oldpct = 100, cct = 0, len = strlen(text); + DFWINDOW swnd = SliderBox(20, GetTitle(wnd), "Printing"); + /* ------- print the notepad text --------- */ + LineCtr = CharCtr = 0; + while (KeepPrinting && *text) { + PrintChar(prn, *text++); + percent = ((long) ++cct * 100) / len; + if ((int)percent != (int)oldpct) { + oldpct = (int) percent; + KeepPrinting = DfSendMessage(swnd, PAINT, 0, oldpct); + } + } + if (KeepPrinting) + /* ---- user did not cancel ---- */ + if (oldpct < 100) + DfSendMessage(swnd, PAINT, 0, 100); + /* ------- follow with a form feed? --------- */ + if (DfYesNoBox("Form Feed?")) + fputc('\f', prn); + fclose(prn); + } + else + DfErrorMessage("Cannot open printer file"); + } + else + DfErrorMessage("No printer selected"); +} + +/* ---------- save a file to disk ------------ */ +static void SaveFile(DFWINDOW wnd, int Saveas) +{ + FILE *fp; + if (wnd->extension == NULL || Saveas) { + char FileName[64]; + if (SaveAsDialogBox(FileName)) { + if (wnd->extension != NULL) + free(wnd->extension); + wnd->extension = DFmalloc(strlen(FileName)+1); + strcpy(wnd->extension, FileName); + AddTitle(wnd, NameComponent(FileName)); + DfSendMessage(wnd, BORDER, 0, 0); + } + else + return; + } + if (wnd->extension != NULL) { + DFWINDOW mwnd = MomentaryMessage("Saving the file"); + if ((fp = fopen(wnd->extension, "wt")) != NULL) { + fwrite(GetText(wnd), strlen(GetText(wnd)), 1, fp); + fclose(fp); + wnd->TextChanged = FALSE; + } + DfSendMessage(mwnd, CLOSE_WINDOW, 0, 0); + } +} +/* -------- delete a file ------------ */ +static void MemoPadDeleteFile(DFWINDOW wnd) +{ + if (wnd->extension != NULL) { + if (strcmp(wnd->extension, Untitled)) { + char *fn = NameComponent(wnd->extension); + if (fn != NULL) { + char msg[30]; + sprintf(msg, "Delete %s?", fn); + if (DfYesNoBox(msg)) { + unlink(wnd->extension); + DfSendMessage(wnd, CLOSE_WINDOW, 0, 0); + } + } + } + } +} + +/* ------ display the row and column in the statusbar ------ */ +static void ShowPosition(DFWINDOW wnd) +{ + char status[30]; + sprintf(status, "Line:%4d Column: %2d", + wnd->CurrLine, wnd->CurrCol); + DfSendMessage(GetParent(wnd), ADDSTATUS, (PARAM) status, 0); +} + +/* ----- window processing module for the editboxes ----- */ +static int EditorProc(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + int rtn; + switch (msg) { + case SETFOCUS: + if ((int)p1) { + wnd->InsertMode = GetCommandToggle(&MainMenu, ID_INSERT); + wnd->WordWrapMode = GetCommandToggle(&MainMenu, ID_WRAP); + } + rtn = DefaultWndProc(wnd, msg, p1, p2); + if ((int)p1 == FALSE) + DfSendMessage(GetParent(wnd), ADDSTATUS, 0, 0); + else + ShowPosition(wnd); + return rtn; + case KEYBOARD_CURSOR: + rtn = DefaultWndProc(wnd, msg, p1, p2); + ShowPosition(wnd); + return rtn; + case DFM_COMMAND: + switch ((int) p1) { + case ID_SEARCH: + SearchText(wnd); + return TRUE; + case ID_REPLACE: + ReplaceText(wnd); + return TRUE; + case ID_SEARCHNEXT: + SearchNext(wnd); + return TRUE; + case ID_CUT: + CopyToClipboard(wnd); + DfSendMessage(wnd, DFM_COMMAND, ID_DELETETEXT, 0); + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + case ID_COPY: + CopyToClipboard(wnd); + ClearTextBlock(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + case ID_PASTE: + PasteFromClipboard(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + case ID_DELETETEXT: + case ID_CLEAR: + rtn = DefaultWndProc(wnd, msg, p1, p2); + DfSendMessage(wnd, PAINT, 0, 0); + return rtn; + case ID_HELP: + DisplayHelp(wnd, "MEMOPADDOC"); + return TRUE; + case ID_WRAP: + DfSendMessage(GetParent(wnd), DFM_COMMAND, ID_WRAP, 0); + wnd->WordWrapMode = cfg.WordWrap; + return TRUE; + case ID_INSERT: + DfSendMessage(GetParent(wnd), DFM_COMMAND, ID_INSERT, 0); + wnd->InsertMode = cfg.InsertMode; + DfSendMessage(NULL, SHOW_CURSOR, wnd->InsertMode, 0); + return TRUE; + default: + break; + } + break; + case CLOSE_WINDOW: + if (wnd->TextChanged) { + char *cp = DFmalloc(25+strlen(GetTitle(wnd))); + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + strcpy(cp, GetTitle(wnd)); + strcat(cp, "\nText changed. Save it?"); + if (DfYesNoBox(cp)) + DfSendMessage(GetParent(wnd), + DFM_COMMAND, ID_SAVE, 0); + free(cp); + } + wndpos = 0; + if (wnd->extension != NULL) { + free(wnd->extension); + wnd->extension = NULL; + } + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} +/* -- point to the name component of a file specification -- */ +static char *NameComponent(char *FileName) +{ + char *Fname; + if ((Fname = strrchr(FileName, '\\')) == NULL) + if ((Fname = strrchr(FileName, ':')) == NULL) + Fname = FileName-1; + return Fname + 1; +} + +static char *ports[] = { + "Lpt1", "Lpt2", "Lpt3", + "Com1", "Com2", "Com3", "Com4", + NULL +}; + +static int PrintSetupProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn, i = 0, mar; + char marg[10]; + DFWINDOW cwnd; + switch (msg) { + case CREATE_WINDOW: + rtn = DefaultWndProc(wnd, msg, p1, p2); + PutItemText(wnd, ID_PRINTERPORT, cfg.PrinterPort); + while (ports[i] != NULL) + PutComboListText(wnd, ID_PRINTERPORT, ports[i++]); + for (mar = CHARSLINE; mar >= 0; --mar) { + sprintf(marg, "%3d", mar); + PutItemText(wnd, ID_LEFTMARGIN, marg); + PutItemText(wnd, ID_RIGHTMARGIN, marg); + } + for (mar = LINESPAGE; mar >= 0; --mar) { + sprintf(marg, "%3d", mar); + PutItemText(wnd, ID_TOPMARGIN, marg); + PutItemText(wnd, ID_BOTTOMMARGIN, marg); + } + cwnd = ControlWindow(&PrintSetup, ID_LEFTMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + CHARSLINE-cfg.LeftMargin, 0); + cwnd = ControlWindow(&PrintSetup, ID_RIGHTMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + CHARSLINE-cfg.RightMargin, 0); + cwnd = ControlWindow(&PrintSetup, ID_TOPMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + LINESPAGE-cfg.TopMargin, 0); + cwnd = ControlWindow(&PrintSetup, ID_BOTTOMMARGIN); + DfSendMessage(cwnd, LB_SETSELECTION, + LINESPAGE-cfg.BottomMargin, 0); + return rtn; + case DFM_COMMAND: + if ((int) p1 == ID_OK && (int) p2 == 0) { + GetItemText(wnd, ID_PRINTERPORT, cfg.PrinterPort, 4); + cwnd = ControlWindow(&PrintSetup, ID_LEFTMARGIN); + cfg.LeftMargin = CHARSLINE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + cwnd = ControlWindow(&PrintSetup, ID_RIGHTMARGIN); + cfg.RightMargin = CHARSLINE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + cwnd = ControlWindow(&PrintSetup, ID_TOPMARGIN); + cfg.TopMargin = LINESPAGE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + cwnd = ControlWindow(&PrintSetup, ID_BOTTOMMARGIN); + cfg.BottomMargin = LINESPAGE - + DfSendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); + } + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +static void FixTabMenu(void) +{ + char *cp = GetCommandText(&MainMenu, ID_TABS); + if (cp != NULL) { + cp = strchr(cp, '('); + if (cp != NULL) { + *(cp+1) = cfg.Tabs + '0'; + if (GetClass(inFocus) == POPDOWNMENU) + DfSendMessage(inFocus, PAINT, 0, 0); + } + } +} + +void PrepFileMenu(void *w, struct Menu *mnu) +{ + DFWINDOW wnd = w; + DeactivateCommand(&MainMenu, ID_SAVE); + DeactivateCommand(&MainMenu, ID_SAVEAS); + DeactivateCommand(&MainMenu, ID_DELETEFILE); + DeactivateCommand(&MainMenu, ID_PRINT); + if (wnd != NULL && GetClass(wnd) == EDITBOX) { + if (isMultiLine(wnd)) { + ActivateCommand(&MainMenu, ID_SAVE); + ActivateCommand(&MainMenu, ID_SAVEAS); + ActivateCommand(&MainMenu, ID_DELETEFILE); + ActivateCommand(&MainMenu, ID_PRINT); + } + } +} + +void PrepSearchMenu(void *w, struct Menu *mnu) +{ + DFWINDOW wnd = w; + DeactivateCommand(&MainMenu, ID_SEARCH); + DeactivateCommand(&MainMenu, ID_REPLACE); + DeactivateCommand(&MainMenu, ID_SEARCHNEXT); + if (wnd != NULL && GetClass(wnd) == EDITBOX) { + if (isMultiLine(wnd)) { + ActivateCommand(&MainMenu, ID_SEARCH); + ActivateCommand(&MainMenu, ID_REPLACE); + ActivateCommand(&MainMenu, ID_SEARCHNEXT); + } + } +} + +void PrepEditMenu(void *w, struct Menu *mnu) +{ + DFWINDOW wnd = w; + DeactivateCommand(&MainMenu, ID_CUT); + DeactivateCommand(&MainMenu, ID_COPY); + DeactivateCommand(&MainMenu, ID_CLEAR); + DeactivateCommand(&MainMenu, ID_DELETETEXT); + DeactivateCommand(&MainMenu, ID_PARAGRAPH); + DeactivateCommand(&MainMenu, ID_PASTE); + DeactivateCommand(&MainMenu, ID_UNDO); + if (wnd != NULL && GetClass(wnd) == EDITBOX) { + if (isMultiLine(wnd)) { + if (TextBlockMarked(wnd)) { + ActivateCommand(&MainMenu, ID_CUT); + ActivateCommand(&MainMenu, ID_COPY); + ActivateCommand(&MainMenu, ID_CLEAR); + ActivateCommand(&MainMenu, ID_DELETETEXT); + } + ActivateCommand(&MainMenu, ID_PARAGRAPH); + if (!TestAttribute(wnd, READONLY) && + Clipboard != NULL) + ActivateCommand(&MainMenu, ID_PASTE); + if (wnd->DeletedText != NULL) + ActivateCommand(&MainMenu, ID_UNDO); + } + } +} + +/* EOF */ diff --git a/rosapps/dflat32/menu.c b/rosapps/dflat32/menu.c new file mode 100644 index 00000000000..5c9ef115dc6 --- /dev/null +++ b/rosapps/dflat32/menu.c @@ -0,0 +1,85 @@ +/* ------------- menu.c ------------- */ + +#include "dflat.h" + +static struct PopDown *FindCmd(MBAR *mn, int cmd) +{ + MENU *mnu = mn->PullDown; + while (mnu->Title != (void *)-1) { + struct PopDown *pd = mnu->Selections; + while (pd->SelectionTitle != NULL) { + if (pd->ActionId == cmd) + return pd; + pd++; + } + mnu++; + } + return NULL; +} + +char *GetCommandText(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + return pd->SelectionTitle; + return NULL; +} + +BOOL isCascadedCommand(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + return pd->Attrib & CASCADED; + return FALSE; +} + +void ActivateCommand(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + pd->Attrib &= ~INACTIVE; +} + +void DeactivateCommand(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + pd->Attrib |= INACTIVE; +} + +BOOL isActive(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + return !(pd->Attrib & INACTIVE); + return FALSE; +} + +BOOL GetCommandToggle(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + return (pd->Attrib & CHECKED) != 0; + return FALSE; +} + +void SetCommandToggle(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + pd->Attrib |= CHECKED; +} + +void ClearCommandToggle(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + pd->Attrib &= ~CHECKED; +} + +void InvertCommandToggle(MBAR *mn, int cmd) +{ + struct PopDown *pd = FindCmd(mn, cmd); + if (pd != NULL) + pd->Attrib ^= CHECKED; +} diff --git a/rosapps/dflat32/menu.h b/rosapps/dflat32/menu.h new file mode 100644 index 00000000000..28c509ac02c --- /dev/null +++ b/rosapps/dflat32/menu.h @@ -0,0 +1,63 @@ +/* ------------ menu.h ------------- */ + +#ifndef MENU_H +#define MENU_H + +#define MAXPULLDOWNS 15 +#define MAXSELECTIONS 20 +#define MAXCASCADES 3 /* nesting level of cascaded menus */ + +/* ----------- popdown menu selection structure + one for each selection on a popdown menu --------- */ +struct PopDown { + unsigned char *SelectionTitle; /* title of the selection */ + int ActionId; /* the command executed */ + int Accelerator; /* the accelerator key */ + int Attrib; /* INACTIVE | CHECKED | TOGGLE | CASCADED*/ + char *help; /* Help mnemonic */ +}; + +/* ----------- popdown menu structure + one for each popdown menu on the menu bar -------- */ +typedef struct Menu { + char *Title; /* title on the menu bar */ + void (*PrepMenu)(void *, struct Menu *); /* function */ + char *StatusText; /* text for the status bar */ + int CascadeId; /* command id of cascading selection */ + int Selection; /* most recent selection */ + struct PopDown Selections[MAXSELECTIONS+1]; +} MENU; + +/* ----- one for each menu bar ----- */ +typedef struct MenuBar { + int ActiveSelection; + MENU PullDown[MAXPULLDOWNS+1]; +} MBAR; + +/* --------- macros to define a menu bar with + popdowns and selections ------------- */ +#define SEPCHAR "\xc4" +#define DEFMENU(m) MBAR m = {-1,{ +#define POPDOWN(ttl,func,stat) {ttl,func,stat,-1,0,{ +#define CASCADED_POPDOWN(id,func) {NULL,func,NULL,id,0,{ +#define SELECTION(stxt,acc,id,attr) {stxt,acc,id,attr,#acc}, +#define SEPARATOR {SEPCHAR}, +#define ENDPOPDOWN {NULL}}}, +#define ENDMENU {(void *)-1} }}; + +/* -------- menu selection attributes -------- */ +#define INACTIVE 1 +#define CHECKED 2 +#define TOGGLE 4 +#define CASCADED 8 + +/* --------- the standard menus ---------- */ +extern MBAR MainMenu; +extern MBAR SystemMenu; +extern MBAR *ActiveMenuBar; + +int MenuHeight(struct PopDown *); +int MenuWidth(struct PopDown *); + +#endif + diff --git a/rosapps/dflat32/menubar.c b/rosapps/dflat32/menubar.c new file mode 100644 index 00000000000..09649db074d --- /dev/null +++ b/rosapps/dflat32/menubar.c @@ -0,0 +1,428 @@ +/* ---------------- menubar.c ------------------ */ + +#include "dflat.h" + +static void reset_menubar(DFWINDOW); + +static struct { + int x1, x2; /* position in menu bar */ + char sc; /* shortcut key value */ +} menu[10]; +static int mctr; + +MBAR *ActiveMenuBar; +static MENU *ActiveMenu; + +static DFWINDOW mwnd; +static BOOL Selecting; + +static DFWINDOW Cascaders[MAXCASCADES]; +static int casc; +static DFWINDOW GetDocFocus(void); + +/* ----------- SETFOCUS Message ----------- */ +static int SetFocusMsg(DFWINDOW wnd, PARAM p1) +{ + int rtn; + rtn = BaseWndProc(MENUBAR, wnd, SETFOCUS, p1, 0); + if (!(int)p1) + DfSendMessage(GetParent(wnd), ADDSTATUS, 0, 0); + return rtn; +} + +/* --------- BUILDMENU Message --------- */ +static void BuildMenuMsg(DFWINDOW wnd, PARAM p1) +{ + int offset = 3; + reset_menubar(wnd); + mctr = 0; + ActiveMenuBar = (MBAR *) p1; + ActiveMenu = ActiveMenuBar->PullDown; + while (ActiveMenu->Title != NULL && + ActiveMenu->Title != (void*)-1) + { + char *cp; + if (strlen(GetText(wnd)+offset) < + strlen(ActiveMenu->Title)+3) + break; + GetText(wnd) = DFrealloc(GetText(wnd), + strlen(GetText(wnd))+5); + memmove(GetText(wnd) + offset+4, GetText(wnd) + offset, + strlen(GetText(wnd))-offset+1); + CopyCommand(GetText(wnd)+offset,ActiveMenu->Title,FALSE, + wnd->WindowColors [STD_COLOR] [BG]); + menu[mctr].x1 = offset; + offset += strlen(ActiveMenu->Title) + (3+MSPACE); + menu[mctr].x2 = offset-MSPACE; + cp = strchr(ActiveMenu->Title, SHORTCUTCHAR); + if (cp) + menu[mctr].sc = tolower(*(cp+1)); + mctr++; + ActiveMenu++; + } + ActiveMenu = ActiveMenuBar->PullDown; +} + +/* ---------- PAINT Message ---------- */ +static void PaintMsg(DFWINDOW wnd) +{ + if (Selecting) + return; + if (wnd == inFocus) + DfSendMessage(GetParent(wnd), ADDSTATUS, 0, 0); + SetStandardColor(wnd); + wputs(wnd, GetText(wnd), 0, 0); + if (ActiveMenuBar == NULL) + return; + if (ActiveMenuBar->ActiveSelection != -1 && + (wnd == inFocus || mwnd != NULL)) { + char *sel, *cp; + int offset, offset1; + + sel = DFmalloc(200); + offset=menu[ActiveMenuBar->ActiveSelection].x1; + offset1=menu[ActiveMenuBar->ActiveSelection].x2; + GetText(wnd)[offset1] = '\0'; + SetReverseColor(wnd); + memset(sel, '\0', 200); + strcpy(sel, GetText(wnd)+offset); + cp = strchr(sel, CHANGECOLOR); + if (cp != NULL) + *(cp + 2) = background | 0x80; + wputs(wnd, sel, + offset-ActiveMenuBar->ActiveSelection*4, 0); + GetText(wnd)[offset1] = ' '; + if (mwnd == NULL && wnd == inFocus) { + char *st = ActiveMenu + [ActiveMenuBar->ActiveSelection].StatusText; + if (st != NULL) + DfSendMessage(GetParent(wnd), ADDSTATUS, + (PARAM)st, 0); + } + free(sel); + } +} + +/* ------------ KEYBOARD Message ------------- */ +static void KeyboardMsg(DFWINDOW wnd, PARAM p1) +{ + MENU *mnu; + int sel; + if (mwnd == NULL) + { + /* ----- search for menu bar shortcut keys ---- */ + int c = tolower((int)p1); + int a = AltConvert((int)p1); + int j; + for (j = 0; j < mctr; j++) { + if ((inFocus == wnd && menu[j].sc == c) || + (a && menu[j].sc == a)) { + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + DfSendMessage(wnd, MB_SELECTION, j, 0); + return; + } + } + } + /* -------- search for accelerator keys -------- */ + mnu = ActiveMenu; + while (mnu->Title != (void *)-1) { + struct PopDown *pd = mnu->Selections; + if (mnu->PrepMenu) + (*(mnu->PrepMenu))(GetDocFocus(), mnu); + while (pd->SelectionTitle != NULL) { + if (pd->Accelerator == (int) p1) { + if (pd->Attrib & INACTIVE) + beep(); + else { + if (pd->Attrib & TOGGLE) + pd->Attrib ^= CHECKED; + DfSendMessage(GetDocFocus(), + SETFOCUS, TRUE, 0); + DfPostMessage(GetParent(wnd), + DFM_COMMAND, pd->ActionId, 0); + } + return; + } + pd++; + } + mnu++; + } + switch ((int)p1) + { + case F1: + if (ActiveMenu == NULL || ActiveMenuBar == NULL) + break; + sel = ActiveMenuBar->ActiveSelection; + if (sel == -1) + { + BaseWndProc(MENUBAR, wnd, KEYBOARD, F1, 0); + return; + } + mnu = ActiveMenu+sel; + if (mwnd == NULL || + mnu->Selections[0].SelectionTitle == NULL) + { + DisplayHelp(wnd,mnu->Title+1); + return; + } + break; + + case '\r': + if (mwnd == NULL && + ActiveMenuBar->ActiveSelection != -1) + DfSendMessage(wnd, MB_SELECTION, + ActiveMenuBar->ActiveSelection, 0); + break; + case F10: + if (wnd != inFocus && mwnd == NULL) { + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + if ( ActiveMenuBar->ActiveSelection == -1) + ActiveMenuBar->ActiveSelection = 0; + DfSendMessage(wnd, PAINT, 0, 0); + break; + } + /* ------- fall through ------- */ + case ESC: + if (inFocus == wnd && mwnd == NULL) { + ActiveMenuBar->ActiveSelection = -1; + DfSendMessage(GetDocFocus(),SETFOCUS,TRUE,0); + DfSendMessage(wnd, PAINT, 0, 0); + } + break; + case FWD: + ActiveMenuBar->ActiveSelection++; + if (ActiveMenuBar->ActiveSelection == mctr) + ActiveMenuBar->ActiveSelection = 0; + if (mwnd != NULL) + DfSendMessage(wnd, MB_SELECTION, + ActiveMenuBar->ActiveSelection, 0); + else + DfSendMessage(wnd, PAINT, 0, 0); + break; + case BS: + if (ActiveMenuBar->ActiveSelection == 0 || + ActiveMenuBar->ActiveSelection == -1) + ActiveMenuBar->ActiveSelection = mctr; + --ActiveMenuBar->ActiveSelection; + if (mwnd != NULL) + DfSendMessage(wnd, MB_SELECTION, + ActiveMenuBar->ActiveSelection, 0); + else + DfSendMessage(wnd, PAINT, 0, 0); + break; + default: + break; + } +} + +/* --------------- LEFT_BUTTON Message ---------- */ +static void LeftButtonMsg(DFWINDOW wnd, PARAM p1) +{ + int i; + int mx = (int) p1 - GetLeft(wnd); + /* --- compute the selection that the left button hit --- */ + for (i = 0; i < mctr; i++) + if (mx >= menu[i].x1-4*i && + mx <= menu[i].x2-4*i-5) + break; + if (i < mctr) + if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL) + DfSendMessage(wnd, MB_SELECTION, i, 0); +} + +/* -------------- MB_SELECTION Message -------------- */ +static void SelectionMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int wd, mx, my; + MENU *mnu; + + if (!p2) + { + ActiveMenuBar->ActiveSelection = -1; + DfSendMessage(wnd, PAINT, 0, 0); + } + Selecting = TRUE; + mnu = ActiveMenu+(int)p1; + if (mnu->PrepMenu != NULL) + (*(mnu->PrepMenu))(GetDocFocus(), mnu); + wd = MenuWidth(mnu->Selections); + if (p2) + { + int brd = GetRight(wnd); + mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1; + if (mx + wd > brd) + mx = brd - wd; + my = GetTop(mwnd) + mwnd->selection; + } + else + { + int offset = menu[(int)p1].x1 - 4 * (int)p1; + if (mwnd != NULL) + DfSendMessage(mwnd, CLOSE_WINDOW, 0, 0); + ActiveMenuBar->ActiveSelection = (int) p1; + if (offset > WindowWidth(wnd)-wd) + offset = WindowWidth(wnd)-wd; + mx = GetLeft(wnd)+offset; + my = GetTop(wnd)+1; + } + mwnd = DfCreateWindow(POPDOWNMENU, NULL, + mx, my, + MenuHeight(mnu->Selections), + wd, + NULL, + wnd, + NULL, + SHADOW); + if (!p2) + { + Selecting = FALSE; + DfSendMessage(wnd, PAINT, 0, 0); + Selecting = TRUE; + } + if (mnu->Selections[0].SelectionTitle != NULL) + { + DfSendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0); + DfSendMessage(mwnd, SETFOCUS, TRUE, 0); + DfSendMessage(mwnd, SHOW_WINDOW, 0, 0); + } + Selecting = FALSE; +} + +/* --------- COMMAND Message ---------- */ +static void CommandMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + if (p1 == ID_HELP) + { + BaseWndProc(MENUBAR, wnd, DFM_COMMAND, p1, p2); + return; + } + + if (isCascadedCommand(ActiveMenuBar, (int)p1)) + { + /* find the cascaded menu based on command id in p1 */ + MENU *mnu = ActiveMenu+mctr; + while (mnu->Title != (void *)-1) { + if (mnu->CascadeId == (int) p1) { + if (casc < MAXCASCADES) { + Cascaders[casc++] = mwnd; + DfSendMessage(wnd, MB_SELECTION, + (PARAM)(mnu-ActiveMenu), TRUE); + } + break; + } + mnu++; + } + } + else { + if (mwnd != NULL) + DfSendMessage(mwnd, CLOSE_WINDOW, 0, 0); + DfSendMessage(GetDocFocus(), SETFOCUS, TRUE, 0); + DfPostMessage(GetParent(wnd), DFM_COMMAND, p1, p2); + } +} + +/* --------------- CLOSE_POPDOWN Message --------------- */ +static void ClosePopdownMsg(DFWINDOW wnd) +{ + if (casc > 0) + DfSendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0); + else + { + mwnd = NULL; + ActiveMenuBar->ActiveSelection = -1; + if (!Selecting) + { + DfSendMessage(GetDocFocus(), SETFOCUS, TRUE, 0); + DfSendMessage(wnd, PAINT, 0, 0); + } + } +} + +/* ---------------- CLOSE_WINDOW Message --------------- */ +static void CloseWindowMsg(DFWINDOW wnd) +{ + if (GetText(wnd) != NULL) + { + free(GetText(wnd)); + GetText(wnd) = NULL; + } + mctr = 0; + ActiveMenuBar->ActiveSelection = -1; + ActiveMenu = NULL; + ActiveMenuBar = NULL; +} + +/* --- Window processing module for MENUBAR window class --- */ +int MenuBarProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + + switch (msg) { + case CREATE_WINDOW: + reset_menubar(wnd); + break; + case SETFOCUS: + return SetFocusMsg(wnd, p1); + case BUILDMENU: + BuildMenuMsg(wnd, p1); + break; + case PAINT: + if (!isVisible(wnd) || GetText(wnd) == NULL) + break; + PaintMsg(wnd); + return FALSE; + case BORDER: + if (mwnd == NULL) + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; + case KEYBOARD: + KeyboardMsg(wnd, p1); + return TRUE; + case LEFT_BUTTON: + LeftButtonMsg(wnd, p1); + return TRUE; + case MB_SELECTION: + SelectionMsg(wnd, p1, p2); + break; + case DFM_COMMAND: + CommandMsg(wnd, p1, p2); + return TRUE; + case INSIDE_WINDOW: + return InsideRect(p1, p2, WindowRect(wnd)); + case CLOSE_POPDOWN: + ClosePopdownMsg(wnd); + return TRUE; + case CLOSE_WINDOW: + CloseWindowMsg(wnd); + rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2); + return rtn; + default: + break; + } + return BaseWndProc(MENUBAR, wnd, msg, p1, p2); +} + +/* ------------- reset the MENUBAR -------------- */ +static void reset_menubar(DFWINDOW wnd) +{ + GetText(wnd) = DFrealloc(GetText(wnd), SCREENWIDTH+5); + memset(GetText(wnd), ' ', SCREENWIDTH); + *(GetText(wnd)+WindowWidth(wnd)) = '\0'; +} + +static DFWINDOW GetDocFocus(void) +{ + DFWINDOW wnd = ApplicationWindow; + if (wnd != NULL) { + wnd = LastWindow(wnd); + while (wnd != NULL && (GetClass(wnd) == MENUBAR || + GetClass(wnd) == STATUSBAR)) + wnd = PrevWindow(wnd); + if (wnd != NULL) + while (wnd->childfocus != NULL) + wnd = wnd->childfocus; + } + return wnd ? wnd : ApplicationWindow; +} + +/* EOF */ diff --git a/rosapps/dflat32/menus.c b/rosapps/dflat32/menus.c new file mode 100644 index 00000000000..573161c8381 --- /dev/null +++ b/rosapps/dflat32/menus.c @@ -0,0 +1,126 @@ +/* -------------- menus.c ------------- */ + +#include "dflat.h" + +/* --------------------- the main menu --------------------- */ +DEFMENU(MainMenu) + /* --------------- the File popdown menu ----------------*/ + POPDOWN( "~File", PrepFileMenu, "Read/write/print files. Go to DOS" ) + SELECTION( "~New", ID_NEW, 0, 0 ) + SELECTION( "~Open...", ID_OPEN, 0, 0 ) + SEPARATOR + SELECTION( "~Save", ID_SAVE, ALT_S, INACTIVE) + SELECTION( "Save ~as...", ID_SAVEAS, 0, INACTIVE) + SELECTION( "D~elete", ID_DELETEFILE, 0, INACTIVE) + SEPARATOR + SELECTION( "~Print", ID_PRINT, 0, INACTIVE) + SELECTION( "P~rinter setup...", ID_PRINTSETUP, 0, 0 ) + SEPARATOR + SELECTION( "~DOS", ID_DOS, 0, 0 ) + SELECTION( "E~xit", ID_EXIT, ALT_X, 0 ) + ENDPOPDOWN + + /* --------------- the Edit popdown menu ----------------*/ + POPDOWN( "~Edit", PrepEditMenu, "Clipboard, delete text, paragraph" ) + SELECTION( "~Undo", ID_UNDO, ALT_BS, INACTIVE) + SEPARATOR + SELECTION( "Cu~t", ID_CUT, SHIFT_DEL, INACTIVE) + SELECTION( "~Copy", ID_COPY, CTRL_INS, INACTIVE) + SELECTION( "~Paste", ID_PASTE, SHIFT_INS, INACTIVE) + SEPARATOR + SELECTION( "Cl~ear", ID_CLEAR, 0, INACTIVE) + SELECTION( "~Delete", ID_DELETETEXT, DEL, INACTIVE) + SEPARATOR + SELECTION( "Pa~ragraph", ID_PARAGRAPH, ALT_P,INACTIVE) + ENDPOPDOWN + + /* --------------- the Search popdown menu ----------------*/ + POPDOWN( "~Search", PrepSearchMenu, "Search and replace" ) + SELECTION( "~Search...", ID_SEARCH, 0, INACTIVE) + SELECTION( "~Replace...",ID_REPLACE, 0, INACTIVE) + SELECTION( "~Next", ID_SEARCHNEXT, F3, INACTIVE) + ENDPOPDOWN + + /* ------------ the Utilities popdown menu --------------- */ + POPDOWN( "~Utilities", NULL, "Utility programs" ) + SELECTION( "~Calendar", ID_CALENDAR, 0, 0) +// SELECTION( "~Bar chart", ID_BARCHART, 0, 0) + ENDPOPDOWN + + /* ------------- the Options popdown menu ---------------*/ + POPDOWN( "~Options", NULL, "Editor and display options" ) + SELECTION( "~Display...", ID_DISPLAY, 0, 0 ) + SEPARATOR +#ifdef INCLUDE_LOGGING + SELECTION( "~Log messages", ID_LOG, ALT_L, 0 ) + SEPARATOR +#endif + SELECTION( "~Insert", ID_INSERT, INS, TOGGLE) + SELECTION( "~Word wrap", ID_WRAP, 0, TOGGLE) + SELECTION( "~Tabs ( )", ID_TABS, 0, CASCADED) + SEPARATOR + SELECTION( "~Save options", ID_SAVEOPTIONS, 0, 0 ) + ENDPOPDOWN + + /* --------------- the Window popdown menu --------------*/ + POPDOWN( "~Window", PrepWindowMenu, "Select/close document windows" ) + SELECTION( NULL, ID_CLOSEALL, 0, 0) + SEPARATOR + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + SELECTION( "~More Windows...", ID_MOREWINDOWS, 0, 0) + SELECTION( NULL, ID_WINDOW, 0, 0 ) + ENDPOPDOWN + + /* --------------- the Help popdown menu ----------------*/ + POPDOWN( "~Help", NULL, "Get help" ) + SELECTION( "~Help for help...", ID_HELPHELP, 0, 0 ) + SELECTION( "~Extended help...", ID_EXTHELP, 0, 0 ) + SELECTION( "~Keys help...", ID_KEYSHELP, 0, 0 ) + SELECTION( "Help ~index...", ID_HELPINDEX, 0, 0 ) + SEPARATOR + SELECTION( "~About...", ID_ABOUT, 0, 0 ) +#ifdef TESTING_DFLAT + SEPARATOR + SELECTION( "~Reload help database",ID_LOADHELP,0, 0 ) +#endif + ENDPOPDOWN + + /* ----- cascaded pulldown from Tabs... above ----- */ + CASCADED_POPDOWN( ID_TABS, NULL ) + SELECTION( "~2 tab stops", ID_TAB2, 0, 0) + SELECTION( "~4 tab stops", ID_TAB4, 0, 0) + SELECTION( "~6 tab stops", ID_TAB6, 0, 0) + SELECTION( "~8 tab stops", ID_TAB8, 0, 0) + ENDPOPDOWN + +ENDMENU + +/* ------------- the System Menu --------------------- */ +DEFMENU(SystemMenu) + POPDOWN("System Menu", NULL, NULL) +#ifdef INCLUDE_RESTORE + SELECTION("~Restore", ID_SYSRESTORE, 0, 0 ) +#endif + SELECTION("~Move", ID_SYSMOVE, 0, 0 ) + SELECTION("~Size", ID_SYSSIZE, 0, 0 ) +#ifdef INCLUDE_MINIMIZE + SELECTION("Mi~nimize", ID_SYSMINIMIZE, 0, 0 ) +#endif +#ifdef INCLUDE_MAXIMIZE + SELECTION("Ma~ximize", ID_SYSMAXIMIZE, 0, 0 ) +#endif + SEPARATOR + SELECTION("~Close", ID_SYSCLOSE, CTRL_F4, 0 ) + ENDPOPDOWN +ENDMENU + diff --git a/rosapps/dflat32/message.c b/rosapps/dflat32/message.c new file mode 100644 index 00000000000..e3d865c953b --- /dev/null +++ b/rosapps/dflat32/message.c @@ -0,0 +1,692 @@ +/* --------- message.c ---------- */ + +#include "dflat.h" + +static int handshaking = 0; + +BOOL AllocTesting = FALSE; +jmp_buf AllocError; +BOOL AltDown = FALSE; + +/* ---------- event queue ---------- */ +static struct events +{ + DFMESSAGE event; + int mx; + int my; +} EventQueue[MAXMESSAGES]; + +/* ---------- message queue --------- */ +static struct msgs +{ + DFWINDOW wnd; + DFMESSAGE msg; + PARAM p1; + PARAM p2; +} MsgQueue[MAXMESSAGES]; + +static int EventQueueOnCtr; +static int EventQueueOffCtr; +static int EventQueueCtr; + +static int MsgQueueOnCtr; +static int MsgQueueOffCtr; +static int MsgQueueCtr; + + +DFWINDOW CaptureMouse; +DFWINDOW CaptureKeyboard; +static BOOL NoChildCaptureMouse; +static BOOL NoChildCaptureKeyboard; + +static int doubletimer = -1; +static int delaytimer = -1; +static int clocktimer = -1; + +static DFWINDOW Cwnd; + +static char ermsg[] = "Error accessing drive x"; + + +static void StopMsg(void) +{ + ClearClipboard(); + ClearDialogBoxes(); + restorecursor(); + unhidecursor(); +} + +/* ------------ initialize the message system --------- */ +BOOL init_messages (VOID) +{ + AllocTesting = TRUE; + if (setjmp(AllocError) != 0) + { + StopMsg(); + return FALSE; + } + + /* enable mouse events */ + SetConsoleMode (GetStdHandle (STD_INPUT_HANDLE), + ENABLE_MOUSE_INPUT); + + savecursor(); + hidecursor(); + + CaptureMouse = NULL; + CaptureKeyboard = NULL; + NoChildCaptureMouse = FALSE; + NoChildCaptureKeyboard = FALSE; + MsgQueueOnCtr = 0; + MsgQueueOffCtr = 0; + MsgQueueCtr = 0; + EventQueueOnCtr = 0; + EventQueueOffCtr = 0; + EventQueueCtr = 0; + DfPostMessage (NULL, DFM_START, 0, 0); + + return TRUE; +} + +/* ----- post an event and parameters to event queue ---- */ +static void PostEvent(DFMESSAGE event, int p1, int p2) +{ + if (EventQueueCtr != MAXMESSAGES) { + EventQueue[EventQueueOnCtr].event = event; + EventQueue[EventQueueOnCtr].mx = p1; + EventQueue[EventQueueOnCtr].my = p2; + if (++EventQueueOnCtr == MAXMESSAGES) + EventQueueOnCtr = 0; + EventQueueCtr++; + } +} + +/* ------ collect mouse, clock, and keyboard events ----- */ +static void collect_events(void) +{ + static int OldShiftKeys = 0; + int sk = 0; + +#ifdef TIMER_AVAILABLE + static BOOL flipflop = FALSE; + static char timestr[9]; + struct tm *now; + int hr; +#endif + + HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); + INPUT_RECORD ir; + DWORD dwRead; + int c; + +#ifdef TIMER_AVAILABLE + /* -------- test for a clock event (one/second) ------- */ + if (timed_out(clocktimer)) + { + /* ----- get the current time ----- */ + time_t t = time(NULL); + now = localtime(&t); + hr = now->tm_hour > 12 ? + now->tm_hour - 12 : + now->tm_hour; + if (hr == 0) + hr = 12; + sprintf(timestr, "%2d:%02d", hr, now->tm_min); + strcpy(timestr+5, now->tm_hour > 11 ? "pm " : "am "); + /* ------- blink the : at one-second intervals ----- */ + if (flipflop) + *(timestr+2) = ' '; + flipflop ^= TRUE; + /* -------- reset the timer -------- */ + set_timer(clocktimer, 1); + /* -------- post the clock event -------- */ + PostEvent(CLOCKTICK, (PARAM)timestr, 0); + } +#endif + +// WaitForSingleObject (hInput, INFINITE); + ReadConsoleInput (hInput, &ir, 1, &dwRead); + + if ((ir.EventType == KEY_EVENT) && + (ir.Event.KeyEvent.bKeyDown == TRUE)) + { + /* handle key down events */ + + /* handle shift state changes */ + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + { + sk |= ALTKEY; + } + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + sk |= CTRLKEY; + } + +#if 0 + if (sk != OldShiftKeys) + { + OldShiftKeys = sk; + /* the shift status changed */ + PostEvent(SHIFT_CHANGED, sk, 0); + if (sk & ALTKEY) + AltDown = TRUE; + else + AltDown = FALSE; + } +#endif + + if (ir.Event.KeyEvent.uChar.AsciiChar == 0) + { + switch (ir.Event.KeyEvent.wVirtualKeyCode) + { + case VK_F1: + c = F1; + break; + + case VK_F4: + if (sk & ALTKEY) + c = ALT_F4; + else if (sk & CTRLKEY) + c = CTRL_F4; + else + c = F4; + + case VK_F10: + c = F10; + break; + + case VK_UP: + c = UP; + break; + + case VK_DOWN: + c = DN; + break; + + case VK_LEFT: + c = BS; + break; + + case VK_RIGHT: + c = FWD; + break; + + case VK_HOME: + c = HOME; + break; + + case VK_END: + c = END; + break; + + case VK_PRIOR: + c = PGUP; + break; + + case VK_NEXT: + c = PGDN; + break; + + default: + return; + } + } + else + c = ir.Event.KeyEvent.uChar.AsciiChar; + + PostEvent (KEYBOARD, c, sk); + } + else if (ir.EventType == MOUSE_EVENT) + { + /* handle mouse events */ + if (ir.Event.MouseEvent.dwEventFlags == MOUSE_MOVED) + { + PostEvent (MOUSE_MOVED, + ir.Event.MouseEvent.dwMousePosition.X, + ir.Event.MouseEvent.dwMousePosition.Y); + } + else if (ir.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) + { + if (ir.Event.MouseEvent.dwButtonState == + FROM_LEFT_1ST_BUTTON_PRESSED) + { + PostEvent (DOUBLE_CLICK, + ir.Event.MouseEvent.dwMousePosition.X, + ir.Event.MouseEvent.dwMousePosition.Y); + } + } + else if (ir.Event.MouseEvent.dwEventFlags == 0) + { + /* single click */ + if (ir.Event.MouseEvent.dwButtonState == + FROM_LEFT_1ST_BUTTON_PRESSED) + { + PostEvent (LEFT_BUTTON, + ir.Event.MouseEvent.dwMousePosition.X, + ir.Event.MouseEvent.dwMousePosition.Y); + } + else if (ir.Event.MouseEvent.dwButtonState == + RIGHTMOST_BUTTON_PRESSED) + { + PostEvent (RIGHT_BUTTON, + ir.Event.MouseEvent.dwMousePosition.X, + ir.Event.MouseEvent.dwMousePosition.Y); + } + else if (ir.Event.MouseEvent.dwButtonState == 0) + { + PostEvent (DFM_BUTTON_RELEASED, + ir.Event.MouseEvent.dwMousePosition.X, + ir.Event.MouseEvent.dwMousePosition.Y); + } + } + } + + +#if 0 + /* --------- keyboard events ---------- */ + if ((sk = getshift()) != ShiftKeys) + { + ShiftKeys = sk; + /* ---- the shift status changed ---- */ + PostEvent(SHIFT_CHANGED, sk, 0); + if (sk & ALTKEY) + AltDown = TRUE; + } + + /* ---- build keyboard events for key combinations that + BIOS doesn't report --------- */ + if (sk & ALTKEY) { + if (keyportvalue == 14) { + AltDown = FALSE; + PostEvent(KEYBOARD, ALT_BS, sk); + } + if (keyportvalue == 83) { + AltDown = FALSE; + PostEvent(KEYBOARD, ALT_DEL, sk); + } + } + + if (sk & CTRLKEY) + { + AltDown = FALSE; + if (keyportvalue == 82) { + PostEvent(KEYBOARD, CTRL_INS, sk); + } + } + /* ----------- test for keystroke ------- */ + if (keyhit()) { + static int cvt[] = {SHIFT_INS,END,DN,PGDN,BS,'5', + FWD,HOME,UP,PGUP}; + INPUT_RECORD ir; + int c; + + GetKey(&ir); + c = ir.Event.KeyEvent.uChar.AsciiChar; + + AltDown = FALSE; + /* -------- convert numeric pad keys ------- */ + if (sk & (LEFTSHIFT | RIGHTSHIFT)) + { + if (c >= '0' && c <= '9') + c = cvt[c-'0']; + else if (c == '.' || c == DEL) + c = SHIFT_DEL; + else if (c == INS) + c = SHIFT_INS; + } + /* ------ post the keyboard event ------ */ + PostEvent(KEYBOARD, c, sk); + } +#endif +} + +/* ----- post a message and parameters to msg queue ---- */ +void DfPostMessage(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + if (msg == ENDDIALOG) + { + msg++; + --msg; + } + + if (MsgQueueCtr != MAXMESSAGES) + { + MsgQueue[MsgQueueOnCtr].wnd = wnd; + MsgQueue[MsgQueueOnCtr].msg = msg; + MsgQueue[MsgQueueOnCtr].p1 = p1; + MsgQueue[MsgQueueOnCtr].p2 = p2; + if (++MsgQueueOnCtr == MAXMESSAGES) + MsgQueueOnCtr = 0; + MsgQueueCtr++; + } +} + +/* --------- send a message to a window ----------- */ +int DfSendMessage(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn = TRUE, x, y; + +#ifdef INCLUDE_LOGGING + LogMessages(wnd, msg, p1, p2); +#endif + if (wnd != NULL) + switch (msg) { + case PAINT: + case BORDER: + /* ------- don't send these messages unless the + window is visible -------- */ + if (isVisible(wnd)) + rtn = (*wnd->wndproc)(wnd, msg, p1, p2); + break; + case RIGHT_BUTTON: + case LEFT_BUTTON: + case DOUBLE_CLICK: + case DFM_BUTTON_RELEASED: + /* --- don't send these messages unless the + window is visible or has captured the mouse -- */ + if (isVisible(wnd) || wnd == CaptureMouse) + rtn = (*wnd->wndproc)(wnd, msg, p1, p2); + break; + case KEYBOARD: + case SHIFT_CHANGED: + /* ------- don't send these messages unless the + window is visible or has captured the keyboard -- */ + if (!(isVisible(wnd) || wnd == CaptureKeyboard)) + break; + default: + rtn = (*wnd->wndproc)(wnd, msg, p1, p2); + break; + } + /* ----- window processor returned true or the message was sent + to no window at all (NULL) ----- */ + if (rtn != FALSE) { + /* --------- process messages that a window sends to the + system itself ---------- */ + switch (msg) { + case DFM_STOP: + StopMsg(); + break; + /* ------- clock messages --------- */ + case CAPTURE_CLOCK: + Cwnd = wnd; + set_timer(clocktimer, 0); + break; + case RELEASE_CLOCK: + Cwnd = NULL; + disable_timer(clocktimer); + break; + /* -------- keyboard messages ------- */ + case KEYBOARD_CURSOR: + if (wnd == NULL) + cursor((int)p1, (int)p2); + else if (wnd == inFocus) + cursor(GetClientLeft(wnd)+(int)p1, + GetClientTop(wnd)+(int)p2); + break; + case CAPTURE_KEYBOARD: + if (p2) + ((DFWINDOW)p2)->PrevKeyboard=CaptureKeyboard; + else + wnd->PrevKeyboard = CaptureKeyboard; + CaptureKeyboard = wnd; + NoChildCaptureKeyboard = (int)p1; + break; + case RELEASE_KEYBOARD: + if (wnd != NULL) + { + if (CaptureKeyboard == wnd || (int)p1) + CaptureKeyboard = wnd->PrevKeyboard; + else + { + DFWINDOW twnd = CaptureKeyboard; + while (twnd != NULL) + { + if (twnd->PrevKeyboard == wnd) + { + twnd->PrevKeyboard = wnd->PrevKeyboard; + break; + } + twnd = twnd->PrevKeyboard; + } + if (twnd == NULL) + CaptureKeyboard = NULL; + } + wnd->PrevKeyboard = NULL; + } + else + CaptureKeyboard = NULL; + NoChildCaptureKeyboard = FALSE; + break; + case CURRENT_KEYBOARD_CURSOR: + curr_cursor(&x, &y); + *(int*)p1 = x; + *(int*)p2 = y; + break; + case SAVE_CURSOR: + savecursor(); + break; + case RESTORE_CURSOR: + restorecursor(); + break; + case HIDE_CURSOR: + normalcursor(); + hidecursor(); + break; + case SHOW_CURSOR: + if (p1) + set_cursor_type(0x0106); + else + set_cursor_type(0x0607); + unhidecursor(); + break; + + case CAPTURE_MOUSE: + if (p2) + ((DFWINDOW)p2)->PrevMouse = CaptureMouse; + else + wnd->PrevMouse = CaptureMouse; + CaptureMouse = wnd; + NoChildCaptureMouse = (int)p1; + break; + + case RELEASE_MOUSE: + if (wnd != NULL) + { + if (CaptureMouse == wnd || (int)p1) + CaptureMouse = wnd->PrevMouse; + else + { + DFWINDOW twnd = CaptureMouse; + while (twnd != NULL) + { + if (twnd->PrevMouse == wnd) + { + twnd->PrevMouse = wnd->PrevMouse; + break; + } + twnd = twnd->PrevMouse; + } + if (twnd == NULL) + CaptureMouse = NULL; + } + wnd->PrevMouse = NULL; + } + else + CaptureMouse = NULL; + NoChildCaptureMouse = FALSE; + break; + + default: + break; + } + } + return rtn; +} + +static DFRECT VisibleRect(DFWINDOW wnd) +{ + DFRECT rc = WindowRect(wnd); + if (!TestAttribute(wnd, NOCLIP)) + { + DFWINDOW pwnd = GetParent(wnd); + DFRECT prc; + prc = ClientRect(pwnd); + while (pwnd != NULL) + { + if (TestAttribute(pwnd, NOCLIP)) + break; + rc = subRectangle(rc, prc); + if (!ValidRect(rc)) + break; + if ((pwnd = GetParent(pwnd)) != NULL) + prc = ClientRect(pwnd); + } + } + return rc; +} + +/* ----- find window that mouse coordinates are in --- */ +static DFWINDOW inWindow(DFWINDOW wnd, int x, int y) +{ + DFWINDOW Hit = NULL; + while (wnd != NULL) { + if (isVisible(wnd)) { + DFWINDOW wnd1; + DFRECT rc = VisibleRect(wnd); + if (InsideRect(x, y, rc)) + Hit = wnd; + if ((wnd1 = inWindow(LastWindow(wnd), x, y)) != NULL) + Hit = wnd1; + if (Hit != NULL) + break; + } + wnd = PrevWindow(wnd); + } + return Hit; +} + +static DFWINDOW MouseWindow(int x, int y) +{ + /* get the window in which a mouse event occurred */ + DFWINDOW Mwnd = inWindow(ApplicationWindow, x, y); + + /* ---- process mouse captures ----- */ + if (CaptureMouse != NULL) + { + if (NoChildCaptureMouse || + Mwnd == NULL || + !isAncestor(Mwnd, CaptureMouse)) + Mwnd = CaptureMouse; + } + return Mwnd; +} + + +void handshake(void) +{ + handshaking++; + DfDispatchMessage (); + --handshaking; +} + + +/* ---- dispatch messages to the message proc function ---- */ +BOOL DfDispatchMessage (void) +{ + DFWINDOW Mwnd, Kwnd; + + /* -------- collect mouse and keyboard events ------- */ + collect_events(); + + /* --------- dequeue and process events -------- */ + while (EventQueueCtr > 0) + { + struct events ev; + + ev = EventQueue[EventQueueOffCtr]; + if (++EventQueueOffCtr == MAXMESSAGES) + EventQueueOffCtr = 0; + --EventQueueCtr; + + /* get the window in which a keyboard event occurred */ + Kwnd = inFocus; + + /* process keyboard captures */ + if (CaptureKeyboard != NULL) + { + if (Kwnd == NULL || + NoChildCaptureKeyboard || + !isAncestor(Kwnd, CaptureKeyboard)) + Kwnd = CaptureKeyboard; + } + + /* send mouse and keyboard messages to the + window that should get them */ + switch (ev.event) + { + case SHIFT_CHANGED: + case KEYBOARD: + if (!handshaking) + DfSendMessage(Kwnd, ev.event, ev.mx, ev.my); + break; + + case LEFT_BUTTON: + if (!handshaking) + { + Mwnd = MouseWindow(ev.mx, ev.my); + if (!CaptureMouse || + (!NoChildCaptureMouse && + isAncestor(Mwnd, CaptureMouse))) + { + if (Mwnd != inFocus) + DfSendMessage(Mwnd, SETFOCUS, TRUE, 0); + DfSendMessage(Mwnd, LEFT_BUTTON, ev.mx, ev.my); + } + } + break; + + case DFM_BUTTON_RELEASED: + case DOUBLE_CLICK: + case RIGHT_BUTTON: + if (handshaking) + break; + + case MOUSE_MOVED: + Mwnd = MouseWindow(ev.mx, ev.my); + DfSendMessage(Mwnd, ev.event, ev.mx, ev.my); + break; + + case CLOCKTICK: + DfSendMessage(Cwnd, ev.event, ev.mx, ev.my); + break; + + default: + break; + } + } + + /* ------ dequeue and process messages ----- */ + while (MsgQueueCtr > 0) + { + struct msgs mq; + + mq = MsgQueue[MsgQueueOffCtr]; + + if (++MsgQueueOffCtr == MAXMESSAGES) + MsgQueueOffCtr = 0; + --MsgQueueCtr; + + DfSendMessage (mq.wnd, mq.msg, mq.p1, mq.p2); + if (mq.msg == ENDDIALOG) + return FALSE; + + if (mq.msg == DFM_STOP) + return FALSE; + } + + return TRUE; +} + +/* EOF */ diff --git a/rosapps/dflat32/msgbox.c b/rosapps/dflat32/msgbox.c new file mode 100644 index 00000000000..8e46766ee92 --- /dev/null +++ b/rosapps/dflat32/msgbox.c @@ -0,0 +1,210 @@ +/* ------------------ msgbox.c ------------------ */ + +#include "dflat.h" + +extern DBOX MsgBox; +extern DBOX InputBoxDB; +DFWINDOW CancelWnd; + +static int ReturnValue; + +int MessageBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + GetClass(wnd) = MESSAGEBOX; + InitWindowColors(wnd); + ClearAttribute(wnd, CONTROLBOX); + break; + case KEYBOARD: + if (p1 == '\r' || p1 == ESC) + ReturnValue = (int)p1; + break; + default: + break; + } + return BaseWndProc(MESSAGEBOX, wnd, msg, p1, p2); +} + +int YesNoBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + GetClass(wnd) = MESSAGEBOX; + InitWindowColors(wnd); + ClearAttribute(wnd, CONTROLBOX); + break; + case KEYBOARD: { + int c = tolower((int)p1); + if (c == 'y') + DfSendMessage(wnd, DFM_COMMAND, ID_OK, 0); + else if (c == 'n') + DfSendMessage(wnd, DFM_COMMAND, ID_CANCEL, 0); + break; + } + default: + break; + } + return BaseWndProc(MESSAGEBOX, wnd, msg, p1, p2); +} + +int ErrorBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + GetClass(wnd) = ERRORBOX; + InitWindowColors(wnd); + break; + case KEYBOARD: + if (p1 == '\r' || p1 == ESC) + ReturnValue = (int)p1; + break; + default: + break; + } + return BaseWndProc(ERRORBOX, wnd, msg, p1, p2); +} + +int CancelBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + CancelWnd = wnd; + DfSendMessage(wnd, CAPTURE_MOUSE, 0, 0); + DfSendMessage(wnd, CAPTURE_KEYBOARD, 0, 0); + break; + case DFM_COMMAND: + if ((int) p1 == ID_CANCEL && (int) p2 == 0) + DfSendMessage(GetParent(wnd), msg, p1, p2); + return TRUE; + case CLOSE_WINDOW: + CancelWnd = NULL; + DfSendMessage(wnd, RELEASE_MOUSE, 0, 0); + DfSendMessage(wnd, RELEASE_KEYBOARD, 0, 0); + p1 = TRUE; + break; + default: + break; + } + return BaseWndProc(MESSAGEBOX, wnd, msg, p1, p2); +} + +void CloseCancelBox(void) +{ + if (CancelWnd != NULL) + DfSendMessage(CancelWnd, CLOSE_WINDOW, 0, 0); +} + +static char *InputText; +static int TextLength; + +int InputBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + switch (msg) { + case CREATE_WINDOW: + rtn = DefaultWndProc(wnd, msg, p1, p2); + DfSendMessage(ControlWindow(&InputBoxDB,ID_INPUTTEXT), + SETTEXTLENGTH, TextLength, 0); + return rtn; + case DFM_COMMAND: + if ((int) p1 == ID_OK && (int) p2 == 0) + GetItemText(wnd, ID_INPUTTEXT, + InputText, TextLength); + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +BOOL InputBox(DFWINDOW wnd,char *ttl,char *msg,char *text,int len) +{ + InputText = text; + TextLength = len; + InputBoxDB.dwnd.title = ttl; + InputBoxDB.dwnd.w = 4 + + max(20, max(len, max((int)strlen(ttl), (int)strlen(msg)))); + InputBoxDB.ctl[1].dwnd.x = (InputBoxDB.dwnd.w-2-len)/2; + InputBoxDB.ctl[0].dwnd.w = strlen(msg); + InputBoxDB.ctl[0].itext = msg; + InputBoxDB.ctl[1].dwnd.w = len; + InputBoxDB.ctl[2].dwnd.x = (InputBoxDB.dwnd.w - 20) / 2; + InputBoxDB.ctl[3].dwnd.x = InputBoxDB.ctl[2].dwnd.x + 10; + InputBoxDB.ctl[2].isetting = ON; + InputBoxDB.ctl[3].isetting = ON; + return DfDialogBox(wnd, &InputBoxDB, TRUE, InputBoxProc); +} + +BOOL GenericMessage(DFWINDOW wnd,char *ttl,char *msg,int buttonct, + int (*wndproc)(struct window *,enum messages,PARAM,PARAM), + char *b1, char *b2, int c1, int c2, int isModal) +{ + BOOL rtn; + MsgBox.dwnd.title = ttl; + MsgBox.ctl[0].dwnd.h = MsgHeight(msg); + if (ttl) + MsgBox.ctl[0].dwnd.w = max(max(MsgWidth(msg), + (int)(buttonct*8 + buttonct + 2)), (int)strlen(ttl)+2); + else + MsgBox.ctl[0].dwnd.w = max(MsgWidth(msg), (int)(buttonct*8 + buttonct + 2)); + MsgBox.dwnd.h = MsgBox.ctl[0].dwnd.h+6; + MsgBox.dwnd.w = MsgBox.ctl[0].dwnd.w+4; + if (buttonct == 1) + MsgBox.ctl[1].dwnd.x = (MsgBox.dwnd.w - 10) / 2; + else { + MsgBox.ctl[1].dwnd.x = (MsgBox.dwnd.w - 20) / 2; + MsgBox.ctl[2].dwnd.x = MsgBox.ctl[1].dwnd.x + 10; + MsgBox.ctl[2].class = BUTTON; + } + MsgBox.ctl[1].dwnd.y = MsgBox.dwnd.h - 4; + MsgBox.ctl[2].dwnd.y = MsgBox.dwnd.h - 4; + MsgBox.ctl[0].itext = msg; + MsgBox.ctl[1].itext = b1; + MsgBox.ctl[2].itext = b2; + MsgBox.ctl[1].command = c1; + MsgBox.ctl[2].command = c2; + MsgBox.ctl[1].isetting = ON; + MsgBox.ctl[2].isetting = ON; + rtn = DfDialogBox(wnd, &MsgBox, isModal, wndproc); + MsgBox.ctl[2].class = 0; + return rtn; +} + +DFWINDOW MomentaryMessage(char *msg) +{ + DFWINDOW wnd = DfCreateWindow( + TEXTBOX, + NULL, + -1,-1,MsgHeight(msg)+2,MsgWidth(msg)+2, + NULL,NULL,NULL, + HASBORDER | SHADOW | SAVESELF); + DfSendMessage(wnd, SETTEXT, (PARAM) msg, 0); + WindowClientColor(wnd, WHITE, GREEN); + WindowFrameColor(wnd, WHITE, GREEN); + DfSendMessage (wnd, SHOW_WINDOW, 0, 0); + return wnd; +} + +int MsgHeight(char *msg) +{ + int h = 1; + while ((msg = strchr(msg, '\n')) != NULL) { + h++; + msg++; + } + return min(h, SCREENHEIGHT-10); +} + +int MsgWidth(char *msg) +{ + int w = 0; + char *cp = msg; + while ((cp = strchr(msg, '\n')) != NULL) { + w = max(w, (int) (cp-msg)); + msg = cp+1; + } + return min(max((int)strlen(msg), (int)w), SCREENWIDTH-10); +} + +/* EOF */ \ No newline at end of file diff --git a/rosapps/dflat32/normal.c b/rosapps/dflat32/normal.c new file mode 100644 index 00000000000..bf5f423e143 --- /dev/null +++ b/rosapps/dflat32/normal.c @@ -0,0 +1,1085 @@ +/* ------------- 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 window dwnd = {DUMMY, NULL, NormalProc, + {-1,-1,-1,-1}}; +static PCHAR_INFO Bsave; +static int Bht, Bwd; +BOOL WindowMoving; +BOOL WindowSizing; +/* -------- array of class definitions -------- */ +CLASSDEFS classdefs[] = { + #undef ClassDef + #define ClassDef(c,b,p,a) {b,p,a}, + #include "classes.h" +}; +DFWINDOW HiddenWindow; + +/* --------- CREATE_WINDOW Message ---------- */ +static void CreateWindowMsg(DFWINDOW wnd) +{ + AppendWindow(wnd); +// ClearAttribute(wnd, VSCROLLBAR | HSCROLLBAR); + if (TestAttribute(wnd, SAVESELF) && isVisible(wnd)) + GetVideoBuffer(wnd); +} + +/* --------- SHOW_WINDOW Message ---------- */ +static void ShowWindowMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + if (GetParent(wnd) == NULL || isVisible(GetParent(wnd))) + { + DFWINDOW cwnd; + + if (TestAttribute(wnd, SAVESELF) && wnd->videosave == NULL) + GetVideoBuffer(wnd); + SetVisible(wnd); + DfSendMessage(wnd, PAINT, 0, TRUE); + DfSendMessage(wnd, BORDER, 0, 0); + /* --- show the children of this window --- */ + cwnd = FirstWindow(wnd); + while (cwnd != NULL) + { + if (cwnd->condition != ISCLOSING) + DfSendMessage(cwnd, SHOW_WINDOW, p1, p2); + cwnd = NextWindow(cwnd); + } + } +} + +/* --------- HIDE_WINDOW Message ---------- */ +static void HideWindowMsg(DFWINDOW wnd) +{ + if (isVisible(wnd)) + { + ClearVisible(wnd); + /* --- paint what this window covered --- */ + if (TestAttribute(wnd, SAVESELF)) + PutVideoBuffer(wnd); +#ifdef INCLUDE_MULTI_WINDOWS + else + PaintOverLappers(wnd); +#endif + } +} + +/* --------- KEYBOARD Message ---------- */ +static BOOL KeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + if (WindowMoving || WindowSizing) { + /* -- move or size a window with keyboard -- */ + int x, y; + x=WindowMoving?GetLeft(&dwnd):GetRight(&dwnd); + y=WindowMoving?GetTop(&dwnd):GetBottom(&dwnd); + switch ((int)p1) { + case ESC: + TerminateMoveSize(); + return TRUE; + case UP: + if (y) + --y; + break; + case DN: + if (y < SCREENHEIGHT-1) + y++; + break; + case FWD: + if (x < SCREENWIDTH-1) + x++; + break; + case 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 F1: + DfSendMessage(wnd, DFM_COMMAND, ID_HELP, 0); + return TRUE; + + case ' ': + if ((int)p2 & ALTKEY) + if (TestAttribute(wnd, HASTITLEBAR)) + if (TestAttribute(wnd, CONTROLBOX)) + BuildSystemMenu(wnd); + return TRUE; + + case CTRL_F4: + if (TestAttribute(wnd, CONTROLBOX)) + { + DfSendMessage(wnd, CLOSE_WINDOW, 0, 0); + SkipApplicationControls(); + return TRUE; + } + break; + + default: + break; + } + + return FALSE; +} + +/* --------- COMMAND Message ---------- */ +static void CommandMsg(DFWINDOW wnd, PARAM p1) +{ + switch ((int)p1) { + case ID_HELP: + DisplayHelp(wnd,ClassNames[GetClass(wnd)]); + break; +#ifdef INCLUDE_RESTORE + case ID_SYSRESTORE: + DfSendMessage(wnd, RESTORE, 0, 0); + break; +#endif + case ID_SYSMOVE: + DfSendMessage(wnd, CAPTURE_MOUSE, TRUE, + (PARAM) &dwnd); + DfSendMessage(wnd, CAPTURE_KEYBOARD, TRUE, + (PARAM) &dwnd); + WindowMoving = TRUE; + dragborder(wnd, GetLeft(wnd), GetTop(wnd)); + break; + case ID_SYSSIZE: + DfSendMessage(wnd, CAPTURE_MOUSE, TRUE, + (PARAM) &dwnd); + DfSendMessage(wnd, CAPTURE_KEYBOARD, TRUE, + (PARAM) &dwnd); + WindowSizing = TRUE; + dragborder(wnd, GetLeft(wnd), GetTop(wnd)); + break; +#ifdef INCLUDE_MINIMIZE + case ID_SYSMINIMIZE: + DfSendMessage(wnd, MINIMIZE, 0, 0); + break; +#endif +#ifdef INCLUDE_MAXIMIZE + case ID_SYSMAXIMIZE: + DfSendMessage(wnd, MAXIMIZE, 0, 0); + break; +#endif + case ID_SYSCLOSE: + DfSendMessage(wnd, CLOSE_WINDOW, 0, 0); + SkipApplicationControls(); + break; + default: + break; + } +} + +/* --------- SETFOCUS Message ---------- */ +static void SetFocusMsg(DFWINDOW wnd, PARAM p1) +{ + DFRECT rc = {0,0,0,0}; + + if (p1 && wnd != NULL && inFocus != wnd) + { + DFWINDOW this, thispar; + DFWINDOW that = NULL, thatpar = NULL; + + DFWINDOW cwnd = wnd, fwnd = GetParent(wnd); + /* ---- post focus in ancestors ---- */ + while (fwnd != NULL) + { + fwnd->childfocus = cwnd; + cwnd = fwnd; + fwnd = GetParent(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 = inFocus; + + /* ---- find common ancestor of prev focus and this window --- */ + while (thatpar != NULL) + { + thispar = wnd; + while (thispar != NULL) + { + if (this == CaptureMouse || this == CaptureKeyboard) + { + /* ---- don't repaint if this window has capture ---- */ + that = thatpar = NULL; + break; + } + if (thispar == thatpar) + { + /* ---- don't repaint if SAVESELF window had focus ---- */ + if (this != that && TestAttribute(that, SAVESELF)) + that = thatpar = NULL; + break; + } + this = thispar; + thispar = GetParent(thispar); + } + if (thispar != NULL) + break; + that = thatpar; + thatpar = GetParent(thatpar); + } + if (inFocus != NULL) + DfSendMessage(inFocus, SETFOCUS, FALSE, 0); + inFocus = wnd; + if (that != NULL && isVisible(wnd)) + { + rc = subRectangle(WindowRect(that), WindowRect(this)); + if (!ValidRect(rc)) + { + if (ApplicationWindow != NULL) + { + DFWINDOW fwnd = FirstWindow(ApplicationWindow); + while (fwnd != NULL) + { + if (!isAncestor(wnd, fwnd)) + { + rc = subRectangle(WindowRect(wnd),WindowRect(fwnd)); + if (ValidRect(rc)) + break; + } + fwnd = NextWindow(fwnd); + } + } + } + } + if (that != NULL && !ValidRect(rc) && isVisible(wnd)) + { + DfSendMessage(wnd, BORDER, 0, 0); + this = NULL; + } + ReFocus(wnd); + if (this != NULL) + DfSendMessage(this, SHOW_WINDOW, 0, 0); + } + else if (!p1 && inFocus == wnd) + { + /* clearing focus */ + inFocus = NULL; + DfSendMessage(wnd, BORDER, 0, 0); + } +} + +/* --------- DOUBLE_CLICK Message ---------- */ +static void DoubleClickMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int mx = (int) p1 - GetLeft(wnd); + int my = (int) p2 - GetTop(wnd); + if (!WindowSizing && !WindowMoving) { + if (HitControlBox(wnd, mx, my)) { + DfPostMessage(wnd, CLOSE_WINDOW, 0, 0); + SkipApplicationControls(); + } + } +} + +/* --------- LEFT_BUTTON Message ---------- */ +static void LeftButtonMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int mx = (int) p1 - GetLeft(wnd); + int my = (int) p2 - GetTop(wnd); + if (WindowSizing || WindowMoving) + return; + if (HitControlBox(wnd, mx, my)) { + BuildSystemMenu(wnd); + return; + } + if (my == 0 && mx > -1 && mx < WindowWidth(wnd)) { + /* ---------- hit the top border -------- */ + if (TestAttribute(wnd, MINMAXBOX) && + TestAttribute(wnd, HASTITLEBAR)) { + if (mx == WindowWidth(wnd)-2) { + if (wnd->condition != ISRESTORED) + /* --- hit the restore box --- */ + DfSendMessage(wnd, RESTORE, 0, 0); +#ifdef INCLUDE_MAXIMIZE + else + /* --- hit the maximize box --- */ + DfSendMessage(wnd, MAXIMIZE, 0, 0); +#endif + return; + } +#ifdef INCLUDE_MINIMIZE + if (mx == WindowWidth(wnd)-3) { + /* --- hit the minimize box --- */ + if (wnd->condition != ISMINIMIZED) + DfSendMessage(wnd, MINIMIZE, 0, 0); + return; + } +#endif + } +#ifdef INCLUDE_MAXIMIZE + if (wnd->condition == ISMAXIMIZED) + return; +#endif + if (TestAttribute(wnd, MOVEABLE)) { + WindowMoving = TRUE; + px = mx; + py = my; + diff = (int) mx; + DfSendMessage(wnd, CAPTURE_MOUSE, TRUE, + (PARAM) &dwnd); + dragborder(wnd, GetLeft(wnd), GetTop(wnd)); + } + return; + } + if (mx == WindowWidth(wnd)-1 && + my == WindowHeight(wnd)-1) { + /* ------- hit the resize corner ------- */ +#ifdef INCLUDE_MINIMIZE + if (wnd->condition == ISMINIMIZED) + return; +#endif + if (!TestAttribute(wnd, SIZEABLE)) + return; +#ifdef INCLUDE_MAXIMIZE + if (wnd->condition == ISMAXIMIZED) { + if (GetParent(wnd) == NULL) + return; + if (TestAttribute(GetParent(wnd),HASBORDER)) + return; + /* ----- resizing a maximized window over a + borderless parent ----- */ + wnd = GetParent(wnd); + } +#endif + WindowSizing = TRUE; + DfSendMessage(wnd, CAPTURE_MOUSE, + TRUE, (PARAM) &dwnd); + dragborder(wnd, GetLeft(wnd), GetTop(wnd)); + } +} + +/* --------- MOUSE_MOVED Message ---------- */ +static BOOL MouseMovedMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + if (WindowMoving) { + int leftmost = 0, topmost = 0, + bottommost = SCREENHEIGHT-2, + rightmost = SCREENWIDTH-2; + int x = (int) p1 - diff; + int y = (int) p2; + if (GetParent(wnd) != NULL && + !TestAttribute(wnd, NOCLIP)) { + DFWINDOW wnd1 = GetParent(wnd); + topmost = GetClientTop(wnd1); + leftmost = GetClientLeft(wnd1); + bottommost = GetClientBottom(wnd1); + rightmost = GetClientRight(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 (WindowSizing) { + sizeborder(wnd, (int) p1, (int) p2); + return TRUE; + } + return FALSE; +} + +#ifdef INCLUDE_MAXIMIZE +/* --------- MAXIMIZE Message ---------- */ +static void MaximizeMsg(DFWINDOW wnd) +{ + DFRECT rc = {0, 0, 0, 0}; + DFRECT holdrc; + holdrc = wnd->RestoredRC; + rc.rt = SCREENWIDTH-1; + rc.bt = SCREENHEIGHT-1; + if (GetParent(wnd)) + rc = ClientRect(GetParent(wnd)); + wnd->oldcondition = wnd->condition; + wnd->condition = ISMAXIMIZED; + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + DfSendMessage(wnd, MOVE, + RectLeft(rc), RectTop(rc)); + DfSendMessage(wnd, DFM_SIZE, + RectRight(rc), RectBottom(rc)); + if (wnd->restored_attrib == 0) + wnd->restored_attrib = wnd->attrib; + ClearAttribute(wnd, SHADOW); + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); + wnd->RestoredRC = holdrc; +} +#endif + +#ifdef INCLUDE_MINIMIZE +/* --------- MINIMIZE Message ---------- */ +static void MinimizeMsg(DFWINDOW wnd) +{ + DFRECT rc; + DFRECT holdrc; + + holdrc = wnd->RestoredRC; + rc = PositionIcon(wnd); + wnd->oldcondition = wnd->condition; + wnd->condition = ISMINIMIZED; + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + DfSendMessage(wnd, MOVE, + RectLeft(rc), RectTop(rc)); + DfSendMessage(wnd, DFM_SIZE, + RectRight(rc), RectBottom(rc)); + if (wnd == inFocus) + SetNextFocus(); + if (wnd->restored_attrib == 0) + wnd->restored_attrib = wnd->attrib; + ClearAttribute(wnd, + SHADOW | SIZEABLE | HASMENUBAR | + VSCROLLBAR | HSCROLLBAR); + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); + wnd->RestoredRC = holdrc; +} +#endif + +#ifdef INCLUDE_RESTORE +/* --------- RESTORE Message ---------- */ +static void RestoreMsg(DFWINDOW wnd) +{ + DFRECT holdrc; + holdrc = wnd->RestoredRC; + wnd->oldcondition = wnd->condition; + wnd->condition = ISRESTORED; + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + wnd->attrib = wnd->restored_attrib; + wnd->restored_attrib = 0; + DfSendMessage(wnd, MOVE, wnd->RestoredRC.lf, + wnd->RestoredRC.tp); + wnd->RestoredRC = holdrc; + DfSendMessage(wnd, DFM_SIZE, wnd->RestoredRC.rt, + wnd->RestoredRC.bt); + if (wnd != inFocus) + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + else + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); +} +#endif + +/* --------- MOVE Message ---------- */ +static void MoveMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + DFWINDOW cwnd; + BOOL wasVisible = isVisible(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 = GetLeft(wnd)+WindowWidth(wnd)-1; + wnd->rc.bt = GetTop(wnd)+WindowHeight(wnd)-1; + if (wnd->condition == ISRESTORED) + wnd->RestoredRC = wnd->rc; + + cwnd = FirstWindow(wnd); + while (cwnd != NULL) { + DfSendMessage(cwnd, MOVE, cwnd->rc.lf+xdif, cwnd->rc.tp+ydif); + cwnd = NextWindow(cwnd); + } + if (wasVisible) + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); +} + +/* --------- SIZE Message ---------- */ +static void SizeMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + BOOL wasVisible = isVisible(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 = GetBottom(wnd)-GetTop(wnd)+1; + wnd->wd = GetRight(wnd)-GetLeft(wnd)+1; + + if (wnd->condition == ISRESTORED) + wnd->RestoredRC = WindowRect(wnd); + +#ifdef INCLUDE_MAXIMIZE + rc = ClientRect(wnd); + + cwnd = FirstWindow(wnd); + while (cwnd != NULL) { + if (cwnd->condition == ISMAXIMIZED) + DfSendMessage(cwnd, DFM_SIZE, RectRight(rc), RectBottom(rc)); + cwnd = NextWindow(cwnd); + } + +#endif + if (wasVisible) + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); +} + +/* --------- CLOSE_WINDOW Message ---------- */ +static void CloseWindowMsg(DFWINDOW wnd) +{ + DFWINDOW cwnd; + wnd->condition = ISCLOSING; + if (wnd->PrevMouse != NULL) + DfSendMessage(wnd, RELEASE_MOUSE, 0, 0); + if (wnd->PrevKeyboard != NULL) + DfSendMessage(wnd, RELEASE_KEYBOARD, 0, 0); + /* ----------- hide this window ------------ */ + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + /* --- close the children of this window --- */ + + cwnd = LastWindow(wnd); + while (cwnd != NULL) { + if (inFocus == cwnd) + inFocus = wnd; + DfSendMessage(cwnd,CLOSE_WINDOW,0,0); + cwnd = LastWindow(wnd); + } + + /* --- change focus if this window had it -- */ + if (wnd == inFocus) + SetPrevFocus(); + /* -- 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 -- */ + RemoveWindow(wnd); + if (wnd == inFocus) + inFocus = NULL; + free(wnd); +} + +/* ---- Window-processing module for NORMAL window class ---- */ +int NormalProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + CreateWindowMsg(wnd); + break; + case SHOW_WINDOW: + ShowWindowMsg(wnd, p1, p2); + break; + case DFM_HIDE_WINDOW: + HideWindowMsg(wnd); + break; + case DISPLAY_HELP: + DisplayHelp(wnd, (char *)p1); + break; + case INSIDE_WINDOW: + return InsideWindow(wnd, (int) p1, (int) p2); + case KEYBOARD: + if (KeyboardMsg(wnd, p1, p2)) + return TRUE; + /* ------- fall through ------- */ + case ADDSTATUS: + case SHIFT_CHANGED: + if (GetParent(wnd) != NULL) + DfPostMessage(GetParent(wnd), msg, p1, p2); + break; + case PAINT: + if (isVisible(wnd)) + ClearWindow(wnd, (DFRECT *)p1, ' '); + break; + case BORDER: + if (isVisible(wnd)) + { + if (TestAttribute(wnd, HASBORDER)) + RepaintBorder(wnd, (DFRECT *)p1); + else if (TestAttribute(wnd, HASTITLEBAR)) + DisplayTitle(wnd, (DFRECT *)p1); + } + break; + case DFM_COMMAND: + CommandMsg(wnd, p1); + break; + case SETFOCUS: + SetFocusMsg(wnd, p1); + break; + case DFM_DOUBLE_CLICK: + DoubleClickMsg(wnd, p1, p2); + break; + case LEFT_BUTTON: + LeftButtonMsg(wnd, p1, p2); + break; + case MOUSE_MOVED: + if (MouseMovedMsg(wnd, p1, p2)) + return TRUE; + break; + case DFM_BUTTON_RELEASED: + if (WindowMoving || WindowSizing) + { + if (WindowMoving) + DfPostMessage(wnd,MOVE,dwnd.rc.lf,dwnd.rc.tp); + else + DfPostMessage(wnd, DFM_SIZE,dwnd.rc.rt,dwnd.rc.bt); + TerminateMoveSize(); + } + break; +#ifdef INCLUDE_MAXIMIZE + case MAXIMIZE: + if (wnd->condition != ISMAXIMIZED) + MaximizeMsg(wnd); + break; +#endif +#ifdef INCLUDE_MINIMIZE + case MINIMIZE: + if (wnd->condition != ISMINIMIZED) + MinimizeMsg(wnd); + break; +#endif +#ifdef INCLUDE_RESTORE + case RESTORE: + if (wnd->condition != ISRESTORED) { +#ifdef INCLUDE_MAXIMIZE + if (wnd->oldcondition == ISMAXIMIZED) + DfSendMessage(wnd, MAXIMIZE, 0, 0); + else +#endif + RestoreMsg(wnd); + } + break; +#endif + case MOVE: + MoveMsg(wnd, p1, p2); + break; + case DFM_SIZE: { + SizeMsg(wnd, p1, p2); + break; + } + case 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; + RectLeft(rc) = RectRight(prc) - ICONWIDTH; + RectTop(rc) = RectBottom(prc) - ICONHEIGHT; + RectRight(rc) = RectLeft(rc)+ICONWIDTH-1; + RectBottom(rc) = RectTop(rc)+ICONHEIGHT-1; + return rc; +} +/* ----- compute a position for a minimized window icon ---- */ +static DFRECT PositionIcon(DFWINDOW wnd) +{ + DFWINDOW pwnd = GetParent(wnd); + DFRECT rc; + RectLeft(rc) = SCREENWIDTH-ICONWIDTH; + RectTop(rc) = SCREENHEIGHT-ICONHEIGHT; + RectRight(rc) = SCREENWIDTH-1; + RectBottom(rc) = SCREENHEIGHT-1; + if (pwnd != NULL) { + DFRECT prc = WindowRect(pwnd); + DFWINDOW cwnd = FirstWindow(pwnd); + rc = LowerRight(prc); + /* - search for icon available location - */ + while (cwnd != NULL) { + if (cwnd->condition == ISMINIMIZED) { + DFRECT rc1; + rc1 = WindowRect(cwnd); + if (RectLeft(rc1) == RectLeft(rc) && + RectTop(rc1) == RectTop(rc)) { + RectLeft(rc) -= ICONWIDTH; + RectRight(rc) -= ICONWIDTH; + if (RectLeft(rc) < RectLeft(prc)+1) { + RectLeft(rc) = + RectRight(prc)-ICONWIDTH; + RectRight(rc) = + RectLeft(rc)+ICONWIDTH-1; + RectTop(rc) -= ICONHEIGHT; + RectBottom(rc) -= ICONHEIGHT; + if (RectTop(rc) < RectTop(prc)+1) + return LowerRight(prc); + } + break; + } + } + cwnd = NextWindow(cwnd); + } + } + return rc; +} +#endif +/* ----- terminate the move or size operation ----- */ +static void TerminateMoveSize(void) +{ + px = py = -1; + diff = 0; + DfSendMessage(&dwnd, RELEASE_MOUSE, TRUE, 0); + DfSendMessage(&dwnd, RELEASE_KEYBOARD, TRUE, 0); + RestoreBorder(dwnd.rc); + WindowMoving = WindowSizing = 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+WindowWidth(wnd)-1; + dwnd.rc.bt = dwnd.rc.tp+WindowHeight(wnd)-1; + dwnd.ht = WindowHeight(wnd); + dwnd.wd = WindowWidth(wnd); + dwnd.parent = GetParent(wnd); + dwnd.attrib = VISIBLE | HASBORDER | NOCLIP; + InitWindowColors(&dwnd); + SaveBorder(dwnd.rc); + RepaintBorder(&dwnd, NULL); +} +/* ---- write the dummy window border for sizing ---- */ +static void sizeborder(DFWINDOW wnd, int rt, int bt) +{ + int leftmost = GetLeft(wnd)+10; + int topmost = GetTop(wnd)+3; + int bottommost = SCREENHEIGHT-1; + int rightmost = SCREENWIDTH-1; + if (GetParent(wnd)) { + bottommost = min(bottommost, + GetClientBottom(GetParent(wnd))); + rightmost = min(rightmost, + GetClientRight(GetParent(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); + RepaintBorder(&dwnd, NULL); + } +} +#ifdef INCLUDE_MULTI_WINDOWS +/* ----- adjust a rectangle to include the shadow ----- */ +static DFRECT adjShadow(DFWINDOW wnd) +{ + DFRECT rc; + rc = wnd->rc; + if (TestAttribute(wnd, SHADOW)) { + if (RectRight(rc) < SCREENWIDTH-1) + RectRight(rc)++; + if (RectBottom(rc) < SCREENHEIGHT-1) + RectBottom(rc)++; + } + return rc; +} +/* --- repaint a rectangular subsection of a window --- */ +static void PaintOverLap(DFWINDOW wnd, DFRECT rc) +{ + if (isVisible(wnd)) { + int isBorder, isTitle, isData; + isBorder = isTitle = FALSE; + isData = TRUE; + if (TestAttribute(wnd, HASBORDER)) { + isBorder = RectLeft(rc) == 0 && + RectTop(rc) < WindowHeight(wnd); + isBorder |= RectLeft(rc) < WindowWidth(wnd) && + RectRight(rc) >= WindowWidth(wnd)-1 && + RectTop(rc) < WindowHeight(wnd); + isBorder |= RectTop(rc) == 0 && + RectLeft(rc) < WindowWidth(wnd); + isBorder |= RectTop(rc) < WindowHeight(wnd) && + RectBottom(rc) >= WindowHeight(wnd)-1 && + RectLeft(rc) < WindowWidth(wnd); + } + else if (TestAttribute(wnd, HASTITLEBAR)) + isTitle = RectTop(rc) == 0 && + RectRight(rc) > 0 && + RectLeft(rc)= WindowWidth(wnd)-BorderAdj(wnd)) + isData = FALSE; + if (RectTop(rc) >= WindowHeight(wnd)-BottomBorderAdj(wnd)) + isData = FALSE; + if (TestAttribute(wnd, HASBORDER)) { + if (RectRight(rc) == 0) + isData = FALSE; + if (RectBottom(rc) == 0) + isData = FALSE; + } + if (TestAttribute(wnd, SHADOW)) + isBorder |= RectRight(rc) == WindowWidth(wnd) || + RectBottom(rc) == WindowHeight(wnd); + if (isData) + DfSendMessage(wnd, PAINT, (PARAM) &rc, TRUE); + if (isBorder) + DfSendMessage(wnd, BORDER, (PARAM) &rc, 0); + else if (isTitle) + DisplayTitle(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 = subRectangle(rc, wrc); + if (ValidRect(rc)) + PaintOverLap(wnd, RelativeWindowRect(wnd, rc)); +} +/* --- paint the overlapped parts of all children --- */ +static void PaintOverChildren(DFWINDOW pwnd) +{ + DFWINDOW cwnd = FirstWindow(pwnd); + while (cwnd != NULL) { + if (cwnd != HiddenWindow) { + PaintOver(cwnd); + PaintOverChildren(cwnd); + } + cwnd = NextWindow(cwnd); + } +} +/* -- recursive overlapping paint of parents -- */ +static void PaintOverParents(DFWINDOW wnd) +{ + DFWINDOW pwnd = GetParent(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 = NextWindow(wnd); + while (hwnd != NULL) { + /* ------- test only at document window level ------ */ + DFWINDOW pwnd = GetParent(hwnd); +/* if (pwnd == NULL || GetClass(pwnd) == APPLICATION) */ { + /* ---- don't bother testing self ----- */ + if (isVisible(hwnd) && hwnd != wnd) { + /* --- see if other window is descendent --- */ + while (pwnd != NULL) { + if (pwnd == wnd) + break; + pwnd = GetParent(pwnd); + } + /* ----- don't test descendent overlaps ----- */ + if (pwnd == NULL) { + /* -- see if other window is ancestor --- */ + pwnd = GetParent(wnd); + while (pwnd != NULL) { + if (pwnd == hwnd) + break; + pwnd = GetParent(pwnd); + } + /* --- don't test ancestor overlaps --- */ + if (pwnd == NULL) { + HiddenWindow = GetAncestor(hwnd); + ClearVisible(HiddenWindow); + PaintOver(wnd); + SetVisible(HiddenWindow); + } + } + } + } + hwnd = NextWindow(hwnd); + } + /* --------- repaint all children of this window + the same way ----------- */ + hwnd = FirstWindow(wnd); + while (hwnd != NULL) { + PaintUnderLappers(hwnd); + hwnd = NextWindow(hwnd); + } +} +#endif /* #ifdef INCLUDE_MULTI_WINDOWS */ + +/* --- save video area to be used by dummy window border --- */ +static void SaveBorder(DFRECT rc) +{ + Bht = RectBottom(rc) - RectTop(rc) + 1; + Bwd = RectRight(rc) - RectLeft(rc) + 1; + Bsave = DFrealloc(Bsave, Bht * Bwd * sizeof(CHAR_INFO)); + + GetVideo(rc,Bsave); +} +/* ---- restore video area used by dummy window border ---- */ +static void RestoreBorder(DFRECT rc) +{ + if (Bsave != NULL) + { + StoreVideo(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 = WindowRect(wnd); + if (!TestAttribute(wnd, NOCLIP)) + { + DFWINDOW pwnd = GetParent(wnd); + while (pwnd != NULL) + { + rc = subRectangle(rc, ClientRect(pwnd)); + pwnd = GetParent(pwnd); + } + } + return InsideRect(x, y, rc); +} + +BOOL isDerivedFrom(DFWINDOW wnd, DFCLASS class) +{ + DFCLASS tclass = GetClass(wnd); + while (tclass != -1) { + if (tclass == class) + return TRUE; + tclass = (classdefs[tclass].base); + } + return FALSE; +} + +/* -- find the oldest document window ancestor of a window -- */ +DFWINDOW GetAncestor(DFWINDOW wnd) +{ + if (wnd != NULL) { + while (GetParent(wnd) != NULL) { + if (GetClass(GetParent(wnd)) == APPLICATION) + break; + wnd = GetParent(wnd); + } + } + return wnd; +} + +BOOL isVisible(DFWINDOW wnd) +{ + while (wnd != NULL) { + if (isHidden(wnd)) + return FALSE; + wnd = GetParent(wnd); + } + return TRUE; +} + +/* -- adjust a window's rectangle to clip it to its parent - */ +static DFRECT ClipRect(DFWINDOW wnd) +{ + DFRECT rc; + rc = WindowRect(wnd); + if (TestAttribute(wnd, SHADOW)) { + RectBottom(rc)++; + RectRight(rc)++; + } + return ClipRectangle(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 = RectBottom(rc) - RectTop(rc) + 1; + wd = RectRight(rc) - RectLeft(rc) + 1; + wnd->videosave = DFrealloc(wnd->videosave, (ht * wd * sizeof(CHAR_INFO))); + GetVideo(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); + StoreVideo(rc, wnd->videosave); + free(wnd->videosave); + wnd->videosave = NULL; + } +} + +/* ------- return TRUE if awnd is an ancestor of wnd ------- */ +BOOL isAncestor(DFWINDOW wnd, DFWINDOW awnd) +{ + while (wnd != NULL) { + if (wnd == awnd) + return TRUE; + wnd = GetParent(wnd); + } + return FALSE; +} + +/* EOF */ diff --git a/rosapps/dflat32/pictbox.c b/rosapps/dflat32/pictbox.c new file mode 100644 index 00000000000..fc17e9e8ade --- /dev/null +++ b/rosapps/dflat32/pictbox.c @@ -0,0 +1,284 @@ +/* -------------- pictbox.c -------------- */ + +#include "dflat.h" + +typedef struct { + enum VectTypes vt; + DFRECT rc; +} VECT; + +unsigned char CharInWnd[] = "ijڿÙÀÅôÁÂ"; + +unsigned char VectCvt[3][11][2][4] = { + { /* --- first character in collision vector --- */ + /* ( drawing Ä ) ( drawing ³ ) */ + {{"ÄÄÄ"}, {"ÚÃÀ"}}, + {{"Ú¿"}, {"³³³"}}, + {{"ÚÂÂ"}, {"ÚÃÃ"}}, + {{"¿¿¿"}, {"¿¿¿"}}, + {{"ÙÙÙ"}, {"ÙÙÙ"}}, + {{"ÀÁÁ"}, {"ÃÃÀ"}}, + {{"ÅÅÅ"}, {"ÅÅÅ"}}, + {{"ÃÅÅ"}, {"ÃÃÃ"}}, + {{"´´´"}, {"´´´"}}, + {{"ÁÁÁ"}, {"ÁÁÁ"}}, + {{"ÂÂÂ"}, {"ÂÅÅ"}} }, + { /* --- middle character in collision vector --- */ + /* ( drawing Ä ) ( drawing ³ ) */ + {{"ÄÄÄ"}, {"ÂÅÁ"}}, + {{"ÃÅ´"}, {"³³³"}}, + {{"ÚÚÚ"}, {"ÚÚÚ"}}, + {{"¿¿¿"}, {"¿¿¿"}}, + {{"ÙÙÙ"}, {"ÙÙÙ"}}, + {{"ÀÀÀ"}, {"ÀÀÀ"}}, + {{"ÅÅÅ"}, {"ÅÅÅ"}}, + {{"ÃÃÃ"}, {"ÃÃÃ"}}, + {{"ÅÅ´"}, {"´´´"}}, + {{"ÁÁÁ"}, {"ÅÅÁ"}}, + {{"ÂÂÂ"}, {"ÂÂÂ"}} }, + { /* --- last character in collision vector --- */ + /* ( drawing Ä ) ( drawing ³ ) */ + {{"ÄÄÄ"}, {"¿´Ù"}}, + {{"ÀÁÙ"}, {"³³³"}}, + {{"ÚÚÚ"}, {"ÚÚÚ"}}, + {{"¿"}, {"¿´´"}}, + {{"ÁÁÙ"}, {"´´Ù"}}, + {{"ÀÀÀ"}, {"ÀÀÀ"}}, + {{"ÅÅÅ"}, {"ÅÅÅ"}}, + {{"ÃÃÃ"}, {"ÃÃÃ"}}, + {{"ÅÅ´"}, {"´´´"}}, + {{"ÁÁÁ"}, {"ÅÅÁ"}}, + {{"ÂÂÂ"}, {"ÂÂÂ"}} } +}; + +/* -- compute whether character is first, middle, or last -- */ +static int FindVector(DFWINDOW wnd, DFRECT rc, int x, int y) +{ + DFRECT rcc; + VECT *vc = wnd->VectorList; + int i, coll = -1; + for (i = 0; i < wnd->VectorCount; i++) { + if ((vc+i)->vt == VECTOR) { + rcc = (vc+i)->rc; + /* --- skip the colliding vector --- */ + if (rcc.lf == rc.lf && rcc.rt == rc.rt && + rcc.tp == rc.tp && rc.bt == rcc.bt) + continue; + if (rcc.tp == rcc.bt) { + /* ---- horizontal vector, + see if character is in it --- */ + if (rc.lf+x >= rcc.lf && rc.lf+x <= rcc.rt && + rc.tp+y == rcc.tp) { + /* --- it is --- */ + if (rc.lf+x == rcc.lf) + coll = 0; + else if (rc.lf+x == rcc.rt) + coll = 2; + else + coll = 1; + } + } + else { + /* ---- vertical vector, + see if character is in it --- */ + if (rc.tp+y >= rcc.tp && rc.tp+y <= rcc.bt && + rc.lf+x == rcc.lf) { + /* --- it is --- */ + if (rc.tp+y == rcc.tp) + coll = 0; + else if (rc.tp+y == rcc.bt) + coll = 2; + else + coll = 1; + } + } + } + } + return coll; +} + +static void PaintVector(DFWINDOW wnd, DFRECT rc) +{ + int i, xi, yi, len; + unsigned int ch, nc; + unsigned int newch; + static int cw, fml, vertvect, coll; + + if (rc.rt == rc.lf) { + /* ------ vertical vector ------- */ + nc = '³'; + vertvect = 1; + len = rc.bt-rc.tp+1; + } + else { + /* ------ horizontal vector ------- */ + nc = 'Ä'; + vertvect = 0; + len = rc.rt-rc.lf+1; + } + + for (i = 0; i < len; i++) { + newch = nc; + xi = yi = 0; + if (vertvect) + yi = i; + else + xi = i; + ch = videochar(GetClientLeft(wnd)+rc.lf+xi, + GetClientTop(wnd)+rc.tp+yi); + for (cw = 0; cw < sizeof(CharInWnd); cw++) { + if (ch == CharInWnd[cw]) { + /* ---- hit another vector character ---- */ + if ((coll=FindVector(wnd, rc, xi, yi)) != -1) { + /* compute first/middle/last subscript */ + if (i == len-1) + fml = 2; + else if (i == 0) + fml = 0; + else + fml = 1; + newch = VectCvt[coll][cw][vertvect][fml]; + } + } + } + PutWindowChar(wnd, newch, rc.lf+xi, rc.tp+yi); + } +} + +static void PaintBar(DFWINDOW wnd, DFRECT rc, enum VectTypes vt) +{ + int i, vertbar, len; + unsigned int tys[] = {219, 178, 177, 176}; +/* unsigned int tys[] = {'Û', '²', '±', '°'}; +*/ + unsigned int nc = tys[vt-1]; + + if (rc.rt == rc.lf) { + /* ------ vertical bar ------- */ + vertbar = 1; + len = rc.bt-rc.tp+1; + } + else { + /* ------ horizontal bar ------- */ + vertbar = 0; + len = rc.rt-rc.lf+1; + } + + for (i = 0; i < len; i++) { + int xi = 0, yi = 0; + if (vertbar) + yi = i; + else + xi = i; + PutWindowChar(wnd, nc, rc.lf+xi, rc.tp+yi); + } +} + +static void PaintMsg(DFWINDOW wnd) +{ + int i; + VECT *vc = wnd->VectorList; + for (i = 0; i < wnd->VectorCount; i++) { + if (vc->vt == VECTOR) + PaintVector(wnd, vc->rc); + else + PaintBar(wnd, vc->rc, vc->vt); + vc++; + } +} + +static void DrawVectorMsg(DFWINDOW wnd,PARAM p1,enum VectTypes vt) +{ + if (p1) { + VECT vc; + wnd->VectorList = DFrealloc(wnd->VectorList, + sizeof(VECT) * (wnd->VectorCount + 1)); + vc.vt = vt; + vc.rc = *(DFRECT *)p1; + *(((VECT *)(wnd->VectorList))+wnd->VectorCount)=vc; + wnd->VectorCount++; + } +} + +static void DrawBoxMsg(DFWINDOW wnd, PARAM p1) +{ + if (p1) { + DFRECT rc = *(DFRECT *)p1; + rc.bt = rc.tp; + DfSendMessage(wnd, DRAWVECTOR, (PARAM) &rc, TRUE); + rc = *(DFRECT *)p1; + rc.lf = rc.rt; + DfSendMessage(wnd, DRAWVECTOR, (PARAM) &rc, FALSE); + rc = *(DFRECT *)p1; + rc.tp = rc.bt; + DfSendMessage(wnd, DRAWVECTOR, (PARAM) &rc, TRUE); + rc = *(DFRECT *)p1; + rc.rt = rc.lf; + DfSendMessage(wnd, DRAWVECTOR, (PARAM) &rc, FALSE); + } +} + +int PictureProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case PAINT: + BaseWndProc(PICTUREBOX, wnd, msg, p1, p2); + PaintMsg(wnd); + return TRUE; + case DRAWVECTOR: + DrawVectorMsg(wnd, p1, VECTOR); + return TRUE; + case DRAWBOX: + DrawBoxMsg(wnd, p1); + return TRUE; + case DRAWBAR: + DrawVectorMsg(wnd, p1, (enum VectTypes)p2); + return TRUE; + case CLOSE_WINDOW: + if (wnd->VectorList != NULL) + free(wnd->VectorList); + break; + default: + break; + } + return BaseWndProc(PICTUREBOX, wnd, msg, p1, p2); +} + +static DFRECT PictureRect(int x, int y, int len, int hv) +{ + DFRECT rc; + rc.lf = rc.rt = x; + rc.tp = rc.bt = y; + if (hv) + /* ---- horizontal vector ---- */ + rc.rt += len-1; + else + /* ---- vertical vector ---- */ + rc.bt += len-1; + return rc; +} + +void DrawVector(DFWINDOW wnd, int x, int y, int len, int hv) +{ + DFRECT rc = PictureRect(x,y,len,hv); + DfSendMessage(wnd, DRAWVECTOR, (PARAM) &rc, 0); +} + +void DrawBox(DFWINDOW wnd, int x, int y, int ht, int wd) +{ + DFRECT rc; + rc.lf = x; + rc.tp = y; + rc.rt = x+wd-1; + rc.bt = y+ht-1; + DfSendMessage(wnd, DRAWBOX, (PARAM) &rc, 0); +} + +void DrawBar(DFWINDOW wnd,enum VectTypes vt, + int x,int y,int len,int hv) +{ + DFRECT rc = PictureRect(x,y,len,hv); + DfSendMessage(wnd, DRAWBAR, (PARAM) &rc, (PARAM) vt); +} + +/* EOF */ diff --git a/rosapps/dflat32/popdown.c b/rosapps/dflat32/popdown.c new file mode 100644 index 00000000000..4362369d1b2 --- /dev/null +++ b/rosapps/dflat32/popdown.c @@ -0,0 +1,389 @@ +/* ------------- popdown.c ----------- */ + +#include "dflat.h" + +static int SelectionWidth(struct PopDown *); +static int py = -1; + +/* ------------ CREATE_WINDOW Message ------------- */ +static int CreateWindowMsg(DFWINDOW wnd) +{ + int rtn, adj; + ClearAttribute(wnd, HASTITLEBAR | + VSCROLLBAR | + MOVEABLE | + SIZEABLE | + HSCROLLBAR); + /* ------ adjust to keep popdown on screen ----- */ + adj = SCREENHEIGHT-1-wnd->rc.bt; + if (adj < 0) { + wnd->rc.tp += adj; + wnd->rc.bt += adj; + } + adj = SCREENWIDTH-1-wnd->rc.rt; + if (adj < 0) { + wnd->rc.lf += adj; + wnd->rc.rt += adj; + } + rtn = BaseWndProc(POPDOWNMENU, wnd, CREATE_WINDOW, 0, 0); + DfSendMessage(wnd, CAPTURE_MOUSE, 0, 0); + DfSendMessage(wnd, CAPTURE_KEYBOARD, 0, 0); + DfSendMessage(NULL, SAVE_CURSOR, 0, 0); + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + wnd->oldFocus = inFocus; + inFocus = wnd; + return rtn; +} + +/* --------- LEFT_BUTTON Message --------- */ +static void LeftButtonMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int my = (int) p2 - GetTop(wnd); + if (InsideRect(p1, p2, ClientRect(wnd))) { + if (my != py) { + DfSendMessage(wnd, LB_SELECTION, + (PARAM) wnd->wtop+my-1, TRUE); + py = my; + } + } + else if ((int)p2 == GetTop(GetParent(wnd))) + if (GetClass(GetParent(wnd)) == MENUBAR) + DfPostMessage(GetParent(wnd), LEFT_BUTTON, p1, p2); +} + +/* -------- BUTTON_RELEASED Message -------- */ +static BOOL ButtonReleasedMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + py = -1; + if (InsideRect((int)p1, (int)p2, ClientRect(wnd))) { + int sel = (int)p2 - GetClientTop(wnd); + if (*TextLine(wnd, sel) != LINE) + DfSendMessage(wnd, LB_CHOOSE, wnd->selection, 0); + } + else { + DFWINDOW pwnd = GetParent(wnd); + if (GetClass(pwnd) == MENUBAR && (int)p2==GetTop(pwnd)) + return FALSE; + if ((int)p1 == GetLeft(pwnd)+2) + return FALSE; + DfSendMessage(wnd, CLOSE_WINDOW, 0, 0); + return TRUE; + } + return FALSE; +} + +/* --------- PAINT Message -------- */ +static void PaintMsg(DFWINDOW wnd) +{ + int wd; + unsigned char sep[80], *cp = sep; + unsigned char sel[80]; + struct PopDown *ActivePopDown; + struct PopDown *pd1; + + ActivePopDown = pd1 = wnd->mnu->Selections; + wd = MenuWidth(ActivePopDown)-2; + while (wd--) + *cp++ = LINE; + *cp = '\0'; + DfSendMessage(wnd, CLEARTEXT, 0, 0); + wnd->selection = wnd->mnu->Selection; + while (pd1->SelectionTitle != NULL) { + if (*pd1->SelectionTitle == LINE) + DfSendMessage(wnd, ADDTEXT, (PARAM) sep, 0); + else { + int len; + memset(sel, '\0', sizeof sel); + if (pd1->Attrib & INACTIVE) + /* ------ inactive menu selection ----- */ + sprintf(sel, "%c%c%c", + CHANGECOLOR, + wnd->WindowColors [HILITE_COLOR] [FG]|0x80, + wnd->WindowColors [STD_COLOR] [BG]|0x80); + strcat(sel, " "); + if (pd1->Attrib & CHECKED) + /* ---- paint the toggle checkmark ---- */ + sel[strlen(sel)-1] = CHECKMARK; + len=CopyCommand(sel+strlen(sel),pd1->SelectionTitle, + pd1->Attrib & INACTIVE, + wnd->WindowColors [STD_COLOR] [BG]); + if (pd1->Accelerator) { + /* ---- paint accelerator key ---- */ + int i; + int wd1 = 2+SelectionWidth(ActivePopDown) - + strlen(pd1->SelectionTitle); + for (i = 0; keys[i].keylabel; i++) { + if (keys[i].keycode == pd1->Accelerator) { + while (wd1--) + strcat(sel, " "); + sprintf(sel+strlen(sel), "[%s]", + keys[i].keylabel); + break; + } + } + } + if (pd1->Attrib & CASCADED) { + /* ---- paint cascaded menu token ---- */ + if (!pd1->Accelerator) { + wd = MenuWidth(ActivePopDown)-len+1; + while (wd--) + strcat(sel, " "); + } + sel[strlen(sel)-1] = CASCADEPOINTER; + } + else + strcat(sel, " "); + strcat(sel, " "); + sel[strlen(sel)-1] = RESETCOLOR; + DfSendMessage(wnd, ADDTEXT, (PARAM) sel, 0); + } + pd1++; + } +} + +/* ---------- BORDER Message ----------- */ +static int BorderMsg(DFWINDOW wnd) +{ + int i, rtn = TRUE; + DFWINDOW currFocus; + if (wnd->mnu != NULL) { + currFocus = inFocus; + inFocus = NULL; + rtn = BaseWndProc(POPDOWNMENU, wnd, BORDER, 0, 0); + inFocus = currFocus; + for (i = 0; i < ClientHeight(wnd); i++) { + if (*TextLine(wnd, i) == LINE) { + wputch(wnd, LEDGE, 0, i+1); + wputch(wnd, REDGE, WindowWidth(wnd)-1, i+1); + } + } + } + return rtn; +} + +/* -------------- LB_CHOOSE Message -------------- */ +static void LBChooseMsg(DFWINDOW wnd, PARAM p1) +{ + struct PopDown *ActivePopDown = wnd->mnu->Selections; + if (ActivePopDown != NULL) { + int *attr = &(ActivePopDown+(int)p1)->Attrib; + wnd->mnu->Selection = (int)p1; + if (!(*attr & INACTIVE)) { + if (*attr & TOGGLE) + *attr ^= CHECKED; + DfPostMessage(GetParent(wnd), DFM_COMMAND, + (ActivePopDown+(int)p1)->ActionId, p1); + } + else + beep(); + } +} + +/* ---------- KEYBOARD Message --------- */ +static BOOL KeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + struct PopDown *ActivePopDown = wnd->mnu->Selections; + + if (wnd->mnu != NULL) + { + if (ActivePopDown != NULL) + { + int c = (int)p1; + int sel = 0; + int a; + struct PopDown *pd = ActivePopDown; + + if ((c & OFFSET) == 0) + c = tolower(c); + a = AltConvert(c); + + while (pd->SelectionTitle != NULL) + { + char *cp = strchr(pd->SelectionTitle, SHORTCUTCHAR); + +/* FIXME: AltConvert bug !! */ + if ((cp && tolower(*(cp+1)) == c) || +// (a && tolower(*(cp+1)) == a) || + pd->Accelerator == c) + { + DfPostMessage(wnd, LB_SELECTION, sel, 0); + DfPostMessage(wnd, LB_CHOOSE, sel, TRUE); + return TRUE; + } + pd++; + sel++; + } + } + } + + switch ((int)p1) + { + case F1: + if (ActivePopDown == NULL) + DfSendMessage(GetParent(wnd), KEYBOARD, p1, p2); + else + DisplayHelp(wnd, + (ActivePopDown+wnd->selection)->help); + return TRUE; + case ESC: + DfSendMessage(wnd, CLOSE_WINDOW, 0, 0); + return TRUE; + case FWD: + case BS: + if (GetClass(GetParent(wnd)) == MENUBAR) + DfPostMessage(GetParent(wnd), KEYBOARD, p1, p2); + return TRUE; + case UP: + if (wnd->selection == 0) { + if (wnd->wlines == ClientHeight(wnd)) { + DfPostMessage(wnd, LB_SELECTION, + wnd->wlines-1, FALSE); + return TRUE; + } + } + break; + case DN: + if (wnd->selection == wnd->wlines-1) { + if (wnd->wlines == ClientHeight(wnd)) { + DfPostMessage(wnd, LB_SELECTION, 0, FALSE); + return TRUE; + } + } + break; + case HOME: + case END: + case '\r': + break; + default: + return TRUE; + } + return FALSE; +} + +/* ----------- CLOSE_WINDOW Message ---------- */ +static int CloseWindowMsg(DFWINDOW wnd) +{ + int rtn; + DFWINDOW pwnd = GetParent(wnd); + DfSendMessage(wnd, RELEASE_MOUSE, 0, 0); + DfSendMessage(wnd, RELEASE_KEYBOARD, 0, 0); + DfSendMessage(NULL, RESTORE_CURSOR, 0, 0); + inFocus = wnd->oldFocus; + rtn = BaseWndProc(POPDOWNMENU, wnd, CLOSE_WINDOW, 0, 0); + DfSendMessage(pwnd, CLOSE_POPDOWN, 0, 0); + return rtn; +} + +/* - Window processing module for POPDOWNMENU window class - */ +int PopDownProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + return CreateWindowMsg(wnd); + case LEFT_BUTTON: + LeftButtonMsg(wnd, p1, p2); + return FALSE; + case DOUBLE_CLICK: + return TRUE; + case LB_SELECTION: + if (*TextLine(wnd, (int)p1) == LINE) + return TRUE; + wnd->mnu->Selection = (int)p1; + break; + case DFM_BUTTON_RELEASED: + if (ButtonReleasedMsg(wnd, p1, p2)) + return TRUE; + break; + case BUILD_SELECTIONS: + wnd->mnu = (void *) p1; + wnd->selection = wnd->mnu->Selection; + break; + case PAINT: + if (wnd->mnu == NULL) + return TRUE; + PaintMsg(wnd); + break; + case BORDER: + return BorderMsg(wnd); + case LB_CHOOSE: + LBChooseMsg(wnd, p1); + return TRUE; + case KEYBOARD: + if (KeyboardMsg(wnd, p1, p2)) + return TRUE; + break; + case CLOSE_WINDOW: + return CloseWindowMsg(wnd); + default: + break; + } + return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2); +} + +/* --------- compute menu height -------- */ +int MenuHeight(struct PopDown *pd) +{ + int ht = 0; + while (pd[ht].SelectionTitle != NULL) + ht++; + return ht+2; +} + +/* --------- compute menu width -------- */ +int MenuWidth(struct PopDown *pd) +{ + int wd = 0, i; + int len = 0; + + wd = SelectionWidth(pd); + while (pd->SelectionTitle != NULL) { + if (pd->Accelerator) { + for (i = 0; keys[i].keylabel; i++) + if (keys[i].keycode == pd->Accelerator) { + len = max(len, (int)(2+strlen(keys[i].keylabel))); + break; + } + } + if (pd->Attrib & CASCADED) + len = max(len, 2); + pd++; + } + return wd+5+len; +} + +/* ---- compute the maximum selection width in a menu ---- */ +static int SelectionWidth(struct PopDown *pd) +{ + int wd = 0; + while (pd->SelectionTitle != NULL) { + int len = strlen(pd->SelectionTitle)-1; + wd = max(wd, len); + pd++; + } + return wd; +} + +/* ----- copy a menu command to a display buffer ---- */ +int CopyCommand(unsigned char *dest, unsigned char *src, + int skipcolor, int bg) +{ + unsigned char *d = dest; + while (*src && *src != '\n') { + if (*src == SHORTCUTCHAR) { + src++; + if (!skipcolor) { + *dest++ = CHANGECOLOR; + *dest++ = cfg.clr[POPDOWNMENU] + [HILITE_COLOR] [BG] | 0x80; + *dest++ = bg | 0x80; + *dest++ = *src++; + *dest++ = RESETCOLOR; + } + } + else + *dest++ = *src++; + } + return (int) (dest - d); +} + +/* EOF */ diff --git a/rosapps/dflat32/radio.c b/rosapps/dflat32/radio.c new file mode 100644 index 00000000000..07ad2b861e3 --- /dev/null +++ b/rosapps/dflat32/radio.c @@ -0,0 +1,116 @@ +/* -------- radio.c -------- */ + +#include "dflat.h" + +static CTLWINDOW *rct[MAXRADIOS]; + +int RadioButtonProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + DBOX *db = GetParent(wnd)->extension; + CTLWINDOW *ct = GetControl(wnd); + if (ct != NULL) { + switch (msg) { + case SETFOCUS: + if (!(int)p1) + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + case MOVE: + rtn = BaseWndProc(RADIOBUTTON,wnd,msg,p1,p2); + SetFocusCursor(wnd); + return rtn; + case PAINT: { + char rb[] = "( )"; + if (ct->setting) + rb[1] = 7; + DfSendMessage(wnd, CLEARTEXT, 0, 0); + DfSendMessage(wnd, ADDTEXT, (PARAM) rb, 0); + SetFocusCursor(wnd); + break; + } + case KEYBOARD: + if ((int)p1 != ' ') + break; + case LEFT_BUTTON: + SetRadioButton(db, ct); + break; + default: + break; + } + } + return BaseWndProc(RADIOBUTTON, wnd, msg, p1, p2); +} + +static BOOL Setting = TRUE; + +void SetRadioButton(DBOX *db, CTLWINDOW *ct) +{ + Setting = FALSE; + PushRadioButton(db, ct->command); + Setting = TRUE; +} + +void PushRadioButton(DBOX *db, enum commands cmd) +{ + CTLWINDOW *ctt = db->ctl; + CTLWINDOW *ct = FindCommand(db, cmd, RADIOBUTTON); + int i; + + if (ct == NULL) + return; + + /* --- clear all the radio buttons + in this group on the dialog box --- */ + + /* -------- build a table of all radio buttons at the + same x vector ---------- */ + for (i = 0; i < MAXRADIOS; i++) + rct[i] = NULL; + while (ctt->class) { + if (ctt->class == RADIOBUTTON) + if (ct->dwnd.x == ctt->dwnd.x) + rct[ctt->dwnd.y] = ctt; + ctt++; + } + + /* ----- find the start of the radiobutton group ---- */ + i = ct->dwnd.y; + while (i >= 0 && rct[i] != NULL) + --i; + /* ---- ignore everthing before the group ------ */ + while (i >= 0) + rct[i--] = NULL; + + /* ----- find the end of the radiobutton group ---- */ + i = ct->dwnd.y; + while (i < MAXRADIOS && rct[i] != NULL) + i++; + /* ---- ignore everthing past the group ------ */ + while (i < MAXRADIOS) + rct[i++] = NULL; + + for (i = 0; i < MAXRADIOS; i++) { + if (rct[i] != NULL) { + int wason = rct[i]->setting; + rct[i]->setting = OFF; + if (Setting) + rct[i]->isetting = OFF; + if (wason) + DfSendMessage(rct[i]->wnd, PAINT, 0, 0); + } + } + /* ----- set the specified radio button on ----- */ + ct->setting = ON; + if (Setting) + ct->isetting = ON; + DfSendMessage(ct->wnd, PAINT, 0, 0); +} + +BOOL RadioButtonSetting(DBOX *db, enum commands cmd) +{ + CTLWINDOW *ct = FindCommand(db, cmd, RADIOBUTTON); + if (ct != NULL) + return (ct->setting == ON); + return FALSE; +} + +/* EOF */ diff --git a/rosapps/dflat32/readme.doc b/rosapps/dflat32/readme.doc new file mode 100644 index 00000000000..18e9a6cdadf --- /dev/null +++ b/rosapps/dflat32/readme.doc @@ -0,0 +1,104 @@ +February, 1995 + +D-Flat Version 20 + +The source files in the DFLAT archive constitute the D-Flat windowing +system. This is public domain code. You may use it in your +applications without restriction. You may freely distribute source +code. It would be nice if you would give credit to Dr. Dobb's Journal +as the original publisher of the source code. + +The software build procedure makes a program named memopad.exe. It is +a multiple-document notepad program. Observe the #define VERSION +statement in dflat.h. The version number should correspond with the +nn in the DFLTnn.ZIP filename that you downloaded. Check the uploads +periodically to see if there is a more recent version available. + +For other examples download the Quincy and IMail applications. The +IMail application uses the DFWRAP C++ class wrapper. + +My CompuServe ID is 71101,1262. I monitor the DDJFORUM every day and +prefer that you discuss D-Flat there so that every one can benefit +from your comments. + +========== Borland C++ 3.1 or 4.0 ============ + +To build with the Borland C++ 3.1 or 4.x make utility: + +Set the DRIVE macro in the makefile to the drive and directory +where your compiler is installed. + +Type this command: + + C>make /fmakefile.bcc + +======================================================= + +D-Flat uses Compressed help files. It uses an adaptation of the +Huffman compression programs from the Dr. Dobb's Journal C +Programming Column of early 1991. + +The makefile compresses the help file with these commands: + + C>huffc memopad.txt memopad.hlp + C>fixhelp memopad.hlp + +Both of the programs must be run in order for the help system to work +properly. Note that .hlp files from previous versions are not +compatible with versions 18 and higher. The .txt files are, however, +so you can use the huffc and fixhelp programs to rebuild the .hlp +file. + +=============================================== + +This is version 20. It incorporates these changes: + +1. Dialog boxes displayed twice upon open. + +2. The intended #define of FA_DIREC in direct.c was inadvertently + released with #include as the preprocessing directive. + +3. Changed status bar to display time after screen takeover. + +4. Statbar incorrectly captured clock with every MOVE message. Caused + hangups when compiled with BCC 3.1 and user moved application window. + +5. Modeless dialog boxes did not redisplay properly when there was +more than one window open. + +6. Added ButtonEnabled and CheckBoxEnabled functions. + +7. Changed LB_SETSELECTION message to accept -1 to turn off +selections in the listbox. + +8. Moved processing of ID_SEARCH, ID_SEARCHNEXT, ID_REPLACE, ID_CUT, +ID_COPY, ID_PASTE, ID_DELETETEXT, ID_UNDO, and ID_CLEAR to editbox.c, +relieving applications of these common processes. + +9. Now allow marking blocks, cut, copy, paste, etc. on single line +editboxes. + +10. Added SetProtect function. + +11. The Window menu listed doc windows that were not visible. + +12. Changed class identifiers to Class. + +13. ClearWindow did not work properly for a window with a status bar +and menu bar and no title bar. + +14. Added the void *wrapper field to the window structure to support +a C++ class wrapper around the D-Flat C function library. + +15. Sizeable windows with borders now display a small token in the +lower right corner to indicate that they are sizeable. + +=============================================== + +Buy the DDJ CD-ROM from Miller-Freeman to get the complete D-Flat +narrative from May '91 to October '92. These columns describe the +development of D-Flat and serve as a tutorial on its use. The D-Flat +reference manual is DFLAT.DOC. + + + diff --git a/rosapps/dflat32/readme.txt b/rosapps/dflat32/readme.txt new file mode 100644 index 00000000000..42773f8bcbf --- /dev/null +++ b/rosapps/dflat32/readme.txt @@ -0,0 +1,33 @@ + +How do I build D-Flat/32? + +At present D-Flat/32 does not exist as a separate dll. But you can build an +example progam. + +To build the example program (actually this is the FreeDOS Editor) you only +have to run 'make dflat32' from the rosapps base directory. The example +program is 'dflat32\edit.exe'. + + +What must be changed in D-Flat/32? + +Things that have to be fixed (incomplete list): + - key handling (replace dos keycodes by win32 console keycodes) + - message queue should become a double linked list (it's an array now) + - establish consitent naming conventions ('Df'/'DF' prefix) to avoid + collisions (e.g. CreateWindow() --> DfCreateWindow()) + - fix short dos filename buffers + - add code to register external window classes + - implement recognition of current console screen size + - fix remaining bugs + - update documentation + +Does it run on ReactOS? +The debugging version doesn't run on ReactOS yet. I haven't tried a version +without debugging code but I doubt it will run. I know that three console +functions are not implemented in ReactOS yet. They will be implemented soon. + +If you have a question, drop me a note. + + +Eric Kohl ekohl@rz-online.de diff --git a/rosapps/dflat32/rect.c b/rosapps/dflat32/rect.c new file mode 100644 index 00000000000..d58d4ba7fe4 --- /dev/null +++ b/rosapps/dflat32/rect.c @@ -0,0 +1,106 @@ +/* ------------- rect.c --------------- */ + +#include "dflat.h" + + /* --- Produce the vector end points produced by the overlap + of two other vectors --- */ +static void subVector(int *v1, int *v2, + int t1, int t2, int o1, int o2) +{ + *v1 = *v2 = -1; + if (within(o1, t1, t2)) { + *v1 = o1; + if (within(o2, t1, t2)) + *v2 = o2; + else + *v2 = t2; + } + else if (within(o2, t1, t2)) { + *v2 = o2; + if (within(o1, t1, t2)) + *v1 = o1; + else + *v1 = t1; + } + else if (within(t1, o1, o2)) { + *v1 = t1; + if (within(t2, o1, o2)) + *v2 = t2; + else + *v2 = o2; + } + else if (within(t2, o1, o2)) { + *v2 = t2; + if (within(t1, o1, o2)) + *v1 = t1; + else + *v1 = o1; + } +} + + /* --- Return the rectangle produced by the overlap + of two other rectangles ---- */ +DFRECT subRectangle(DFRECT r1, DFRECT r2) +{ + DFRECT r = {0,0,0,0}; + subVector((int *) &RectLeft(r), (int *) &RectRight(r), + RectLeft(r1), RectRight(r1), + RectLeft(r2), RectRight(r2)); + subVector((int *) &RectTop(r), (int *) &RectBottom(r), + RectTop(r1), RectBottom(r1), + RectTop(r2), RectBottom(r2)); + if (RectRight(r) == -1 || RectTop(r) == -1) + RectRight(r) = + RectLeft(r) = + RectTop(r) = + RectBottom(r) = 0; + return r; +} + +/* ------- return the client rectangle of a window ------ */ +DFRECT ClientRect(void *wnd) +{ + DFRECT rc; + + if (wnd == NULL) + { + RectLeft(rc) = 1; // GetClientLeft((DFWINDOW)wnd); + RectTop(rc) = 2; // GetClientTop((DFWINDOW)wnd); + RectRight(rc) = SCREENWIDTH - 2; // GetClientRight((DFWINDOW)wnd); + RectBottom(rc) = SCREENHEIGHT - 2; // GetClientBottom((DFWINDOW)wnd); + return rc; + } + + RectLeft(rc) = GetClientLeft((DFWINDOW)wnd); + RectTop(rc) = GetClientTop((DFWINDOW)wnd); + RectRight(rc) = GetClientRight((DFWINDOW)wnd); + RectBottom(rc) = GetClientBottom((DFWINDOW)wnd); + + return rc; +} + +/* ----- return the rectangle relative to + its window's screen position -------- */ +DFRECT RelativeWindowRect(void *wnd, DFRECT rc) +{ + RectLeft(rc) -= GetLeft((DFWINDOW)wnd); + RectRight(rc) -= GetLeft((DFWINDOW)wnd); + RectTop(rc) -= GetTop((DFWINDOW)wnd); + RectBottom(rc) -= GetTop((DFWINDOW)wnd); + return rc; +} + +/* ----- clip a rectangle to the parents of the window ----- */ +DFRECT ClipRectangle(void *wnd, DFRECT rc) +{ + DFRECT sr; + RectLeft(sr) = RectTop(sr) = 0; + RectRight(sr) = SCREENWIDTH-1; + RectBottom(sr) = SCREENHEIGHT-1; + if (!TestAttribute((DFWINDOW)wnd, NOCLIP)) + while ((wnd = GetParent((DFWINDOW)wnd)) != NULL) + rc = subRectangle(rc, ClientRect(wnd)); + return subRectangle(rc, sr); +} + +/* EOF */ diff --git a/rosapps/dflat32/rect.h b/rosapps/dflat32/rect.h new file mode 100644 index 00000000000..c4497e13e99 --- /dev/null +++ b/rosapps/dflat32/rect.h @@ -0,0 +1,24 @@ +/* ----------- rect.h ------------ */ +#ifndef RECT_H +#define RECT_H + +typedef struct { + int lf,tp,rt,bt; +} DFRECT; +#define within(p,v1,v2) ((p)>=(v1)&&(p)<=(v2)) +#define RectTop(r) (r.tp) +#define RectBottom(r) (r.bt) +#define RectLeft(r) (r.lf) +#define RectRight(r) (r.rt) +#define InsideRect(x,y,r) (within((x),RectLeft(r),RectRight(r))\ + && \ + within((y),RectTop(r),RectBottom(r))) +#define ValidRect(r) (RectRight(r) || RectLeft(r) || \ + RectTop(r) || RectBottom(r)) +#define RectWidth(r) (RectRight(r)-RectLeft(r)+1) +#define RectHeight(r) (RectBottom(r)-RectTop(r)+1) +DFRECT subRectangle(DFRECT, DFRECT); +DFRECT ClientRect(void *); +DFRECT RelativeWindowRect(void *, DFRECT); +DFRECT ClipRectangle(void *, DFRECT); +#endif diff --git a/rosapps/dflat32/search.c b/rosapps/dflat32/search.c new file mode 100644 index 00000000000..52a2a4a1d2a --- /dev/null +++ b/rosapps/dflat32/search.c @@ -0,0 +1,163 @@ +/* ---------------- search.c ------------- */ +#include "dflat.h" + +extern DBOX SearchTextDB; +extern DBOX ReplaceTextDB; +static int CheckCase = TRUE; +static int Replacing = FALSE; + +/* - case-insensitive, white-space-normalized char compare - */ +static BOOL SearchCmp(int a, int b) +{ + if (b == '\n') + b = ' '; + if (CheckCase) + return a != b; + return tolower(a) != tolower(b); +} + +/* ----- replace a matching block of text ----- */ +static void replacetext(DFWINDOW wnd, char *cp1, DBOX *db) +{ + char *cr = GetEditBoxText(db, ID_REPLACEWITH); + char *cp = GetEditBoxText(db, ID_SEARCHFOR); + int oldlen = strlen(cp); /* length of text being replaced */ + int newlen = strlen(cr); /* length of replacing text */ + int dif; + if (oldlen < newlen) { + /* ---- new text expands text size ---- */ + dif = newlen-oldlen; + if (wnd->textlen < strlen(wnd->text)+dif) { + /* ---- need to reallocate the text buffer ---- */ + int offset = (int)((int)cp1-(int)wnd->text); + wnd->textlen += dif; + wnd->text = DFrealloc(wnd->text, wnd->textlen+2); + cp1 = wnd->text + offset; + } + memmove(cp1+dif, cp1, strlen(cp1)+1); + } + else if (oldlen > newlen) { + /* ---- new text collapses text size ---- */ + dif = oldlen-newlen; + memmove(cp1, cp1+dif, strlen(cp1)+1); + } + strncpy(cp1, cr, newlen); +} + +/* ------- search for the occurrance of a string ------- */ +static void SearchTextBox(DFWINDOW wnd, int incr) +{ + char *s1 = NULL, *s2, *cp1; + DBOX *db = Replacing ? &ReplaceTextDB : &SearchTextDB; + char *cp = GetEditBoxText(db, ID_SEARCHFOR); + BOOL rpl = TRUE, FoundOne = FALSE; + + while (rpl == TRUE && cp != NULL && *cp) { + rpl = Replacing ? + CheckBoxSetting(&ReplaceTextDB, ID_REPLACEALL) : + FALSE; + if (TextBlockMarked(wnd)) { + ClearTextBlock(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + } + /* search for a match starting at cursor position */ + cp1 = CurrChar; + if (incr) + cp1++; /* start past the last hit */ + /* --- compare at each character position --- */ + while (*cp1) { + s1 = cp; + s2 = cp1; + while (*s1 && *s1 != '\n') { + if (SearchCmp(*s1, *s2)) + break; + s1++, s2++; + } + if (*s1 == '\0' || *s1 == '\n') + break; + cp1++; + } + if (s1 != NULL && (*s1 == 0 || *s1 == '\n')) { + /* ----- match at *cp1 ------- */ + FoundOne = TRUE; + + /* mark a block at beginning of matching text */ + wnd->BlkEndLine = TextLineNumber(wnd, s2); + wnd->BlkBegLine = TextLineNumber(wnd, cp1); + if (wnd->BlkEndLine < wnd->BlkBegLine) + wnd->BlkEndLine = wnd->BlkBegLine; + wnd->BlkEndCol = + (int)((int)s2 - (int)TextLine(wnd, wnd->BlkEndLine)); + wnd->BlkBegCol = + (int)((int)cp1 - (int)TextLine(wnd, wnd->BlkBegLine)); + + /* position the cursor at the matching text */ + wnd->CurrCol = wnd->BlkBegCol; + wnd->CurrLine = wnd->BlkBegLine; + wnd->WndRow = wnd->CurrLine - wnd->wtop; + + /* align the window scroll to matching text */ + if (WndCol > ClientWidth(wnd)-1) + wnd->wleft = wnd->CurrCol; + if (wnd->WndRow > ClientHeight(wnd)-1) { + wnd->wtop = wnd->CurrLine; + wnd->WndRow = 0; + } + + DfSendMessage(wnd, PAINT, 0, 0); + DfSendMessage(wnd, KEYBOARD_CURSOR, + WndCol, wnd->WndRow); + + if (Replacing) { + if (rpl || DfYesNoBox("Replace the text?")) { + replacetext(wnd, cp1, db); + wnd->TextChanged = TRUE; + BuildTextPointers(wnd); + } + if (rpl) { + incr = TRUE; + continue; + } + ClearTextBlock(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + } + return; + } + break; + } + if (!FoundOne) + DfMessageBox("Search/Replace Text", "No match found"); +} + +/* ------- search for the occurrance of a string, + replace it with a specified string ------- */ +void DfReplaceText(DFWINDOW wnd) +{ + Replacing = TRUE; + if (CheckCase) + SetCheckBox(&ReplaceTextDB, ID_MATCHCASE); + if (DfDialogBox(NULL, &ReplaceTextDB, TRUE, NULL)) { + CheckCase=CheckBoxSetting(&ReplaceTextDB,ID_MATCHCASE); + SearchTextBox(wnd, FALSE); + } +} + +/* ------- search for the first occurrance of a string ------ */ +void DfSearchText(DFWINDOW wnd) +{ + Replacing = FALSE; + if (CheckCase) + SetCheckBox(&SearchTextDB, ID_MATCHCASE); + if (DfDialogBox(NULL, &SearchTextDB, TRUE, NULL)) { + CheckCase=CheckBoxSetting(&SearchTextDB,ID_MATCHCASE); + SearchTextBox(wnd, FALSE); + } +} + +/* ------- search for the next occurrance of a string ------- */ +void DfSearchNext(DFWINDOW wnd) +{ + SearchTextBox(wnd, TRUE); +} + +/* EOF */ diff --git a/rosapps/dflat32/slidebox.c b/rosapps/dflat32/slidebox.c new file mode 100644 index 00000000000..d98719473b5 --- /dev/null +++ b/rosapps/dflat32/slidebox.c @@ -0,0 +1,114 @@ +/* ------------- slidebox.c ------------ */ + +#include "dflat.h" + +static int (*GenericProc) + (DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2); +static BOOL KeepRunning; +static int SliderLen; +static int Percent; +extern DBOX SliderBoxDB; + +static void InsertPercent(char *s) +{ + int offset; + char pcc[5]; + + sprintf(s, "%c%c%c", + CHANGECOLOR, + color[DIALOG][SELECT_COLOR][FG]+0x80, + color[DIALOG][SELECT_COLOR][BG]+0x80); + s += 3; + memset(s, ' ', SliderLen); + *(s+SliderLen) = '\0'; + sprintf(pcc, "%d%%", Percent); + strncpy(s+SliderLen/2-1, pcc, strlen(pcc)); + offset = (SliderLen * Percent) / 100; + memmove(s+offset+4, s+offset, strlen(s+offset)+1); + sprintf(pcc, "%c%c%c%c", + RESETCOLOR, + CHANGECOLOR, + color[DIALOG][SELECT_COLOR][BG]+0x80, + color[DIALOG][SELECT_COLOR][FG]+0x80); + strncpy(s+offset, pcc, 4); + *(s + strlen(s) - 1) = RESETCOLOR; +} + +static int +SliderTextProc (DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2) +{ + switch (msg) + { + case PAINT: + Percent = (int)p2; + InsertPercent(GetText(wnd) ? + GetText(wnd) : SliderBoxDB.ctl[1].itext); + GenericProc(wnd, PAINT, 0, 0); + if (Percent >= 100) + DfSendMessage(GetParent(wnd),DFM_COMMAND,ID_CANCEL,0); + if (!DfDispatchMessage ()) + DfPostMessage(GetParent(wnd), ENDDIALOG, 0, 0); + return KeepRunning; + default: + break; + } + return GenericProc(wnd, msg, p1, p2); +} + +static int +SliderBoxProc (DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + DFWINDOW twnd; + switch (msg) { + case CREATE_WINDOW: + AddAttribute(wnd, SAVESELF); + rtn = DefaultWndProc(wnd, msg, p1, p2); + twnd = SliderBoxDB.ctl[1].wnd; + GenericProc = twnd->wndproc; + twnd->wndproc = SliderTextProc; + KeepRunning = TRUE; + DfSendMessage(wnd, CAPTURE_MOUSE, 0, 0); + DfSendMessage(wnd, CAPTURE_KEYBOARD, 0, 0); + return rtn; + case DFM_COMMAND: + if ((int)p2 == 0 && (int)p1 == ID_CANCEL) { + if (Percent >= 100 || + DfYesNoBox("Terminate process?")) + KeepRunning = FALSE; + else + return TRUE; + } + break; + case CLOSE_WINDOW: + DfSendMessage(wnd, RELEASE_MOUSE, 0, 0); + DfSendMessage(wnd, RELEASE_KEYBOARD, 0, 0); + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +DFWINDOW SliderBox(int len, char *ttl, char *msg) +{ + SliderLen = len; + SliderBoxDB.dwnd.title = ttl; + SliderBoxDB.dwnd.w = + max((int)strlen(ttl),max(len, (int)strlen(msg)))+4; + SliderBoxDB.ctl[0].itext = msg; + SliderBoxDB.ctl[0].dwnd.w = strlen(msg); + SliderBoxDB.ctl[0].dwnd.x = + (SliderBoxDB.dwnd.w - strlen(msg)-1) / 2; + SliderBoxDB.ctl[1].itext = + DFrealloc(SliderBoxDB.ctl[1].itext, len+10); + Percent = 0; + InsertPercent(SliderBoxDB.ctl[1].itext); + SliderBoxDB.ctl[1].dwnd.w = len; + SliderBoxDB.ctl[1].dwnd.x = (SliderBoxDB.dwnd.w-len-1)/2; + SliderBoxDB.ctl[2].dwnd.x = (SliderBoxDB.dwnd.w-10)/2; + DfDialogBox(NULL, &SliderBoxDB, FALSE, SliderBoxProc); + return SliderBoxDB.ctl[1].wnd; +} + +/* EOF */ diff --git a/rosapps/dflat32/spinbutt.c b/rosapps/dflat32/spinbutt.c new file mode 100644 index 00000000000..262797d61ea --- /dev/null +++ b/rosapps/dflat32/spinbutt.c @@ -0,0 +1,48 @@ +/* ------------ spinbutt.c ------------- */ + +#include "dflat.h" + +int SpinButtonProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + CTLWINDOW *ct = GetControl(wnd); + if (ct != NULL) { + switch (msg) { + case CREATE_WINDOW: + wnd->wd -= 2; + wnd->rc.rt -= 2; + break; + case SETFOCUS: + rtn = BaseWndProc(SPINBUTTON, wnd, msg, p1, p2); + if (!(int)p1) + DfSendMessage(NULL, HIDE_CURSOR, 0, 0); + SetFocusCursor(wnd); + return rtn; + case PAINT: + foreground = WndBackground(wnd); + background = WndForeground(wnd); + wputch(wnd,UPSCROLLBOX,WindowWidth(wnd), 0); + wputch(wnd,DOWNSCROLLBOX,WindowWidth(wnd)+1,0); + SetFocusCursor(wnd); + break; + case LEFT_BUTTON: + if (p1 == GetRight(wnd) + 1) + DfSendMessage(wnd, KEYBOARD, UP, 0); + else if (p1 == GetRight(wnd) + 2) + DfSendMessage(wnd, KEYBOARD, DN, 0); + if (wnd != inFocus) + DfSendMessage(wnd, SETFOCUS, TRUE, 0); + return TRUE; + case LB_SETSELECTION: + rtn = BaseWndProc(SPINBUTTON, wnd, msg, p1, p2); + wnd->wtop = (int) p1; + DfSendMessage(wnd, PAINT, 0, 0); + return rtn; + default: + break; + } + } + return BaseWndProc(SPINBUTTON, wnd, msg, p1, p2); +} + +/* EOF */ diff --git a/rosapps/dflat32/statbar.c b/rosapps/dflat32/statbar.c new file mode 100644 index 00000000000..7a459e072dd --- /dev/null +++ b/rosapps/dflat32/statbar.c @@ -0,0 +1,53 @@ +/* ---------------- statbar.c -------------- */ + +#include "dflat.h" + +int StatusBarProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + char *statusbar; + switch (msg) { + case CREATE_WINDOW: + case MOVE: + DfSendMessage(wnd, CAPTURE_CLOCK, 0, 0); + break; + case KEYBOARD: + if ((int)p1 == CTRL_F4) + return TRUE; + break; + case PAINT: + if (!isVisible(wnd)) + break; + statusbar = DFcalloc(1, WindowWidth(wnd)+1); + memset(statusbar, ' ', WindowWidth(wnd)); + *(statusbar+WindowWidth(wnd)) = '\0'; + strncpy(statusbar+1, "F1=Help Ý FreeDos Edit", 22); + if (wnd->text) { + int len = min((int)strlen(wnd->text), (int)(WindowWidth(wnd)-17)); + if (len > 0) { + int off=(WindowWidth(wnd)-len)/2; + strncpy(statusbar+off, wnd->text, len); + } + } + if (wnd->TimePosted) + *(statusbar+WindowWidth(wnd)-8) = '\0'; + SetStandardColor(wnd); + PutWindowLine(wnd, statusbar, 0, 0); + free(statusbar); + return TRUE; + case BORDER: + return TRUE; + case CLOCKTICK: + SetStandardColor(wnd); + PutWindowLine(wnd, (char *)p1, WindowWidth(wnd)-8, 0); + wnd->TimePosted = TRUE; + return TRUE; + case CLOSE_WINDOW: + DfSendMessage(NULL, RELEASE_CLOCK, 0, 0); + break; + default: + break; + } + return BaseWndProc(STATUSBAR, wnd, msg, p1, p2); +} + +/* EOF */ diff --git a/rosapps/dflat32/sysmenu.c b/rosapps/dflat32/sysmenu.c new file mode 100644 index 00000000000..a3e897b15dd --- /dev/null +++ b/rosapps/dflat32/sysmenu.c @@ -0,0 +1,108 @@ +/* ------------- sysmenu.c ------------ */ + +#include "dflat.h" + +int SystemMenuProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int mx, my; + DFWINDOW wnd1; + switch (msg) { + case CREATE_WINDOW: + wnd->holdmenu = ActiveMenuBar; + ActiveMenuBar = &SystemMenu; + SystemMenu.PullDown[0].Selection = 0; + break; + case LEFT_BUTTON: + wnd1 = GetParent(wnd); + mx = (int) p1 - GetLeft(wnd1); + my = (int) p2 - GetTop(wnd1); + if (HitControlBox(wnd1, mx, my)) + return TRUE; + break; + case LB_CHOOSE: + DfPostMessage(wnd, CLOSE_WINDOW, 0, 0); + break; + case DOUBLE_CLICK: + if (p2 == GetTop(GetParent(wnd))) { + DfPostMessage(GetParent(wnd), msg, p1, p2); + DfSendMessage(wnd, CLOSE_WINDOW, TRUE, 0); + } + return TRUE; + case SHIFT_CHANGED: + return TRUE; + case CLOSE_WINDOW: + ActiveMenuBar = wnd->holdmenu; + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +/* ------- Build a system menu -------- */ +void BuildSystemMenu(DFWINDOW wnd) +{ + int lf, tp, ht, wd; + DFWINDOW SystemMenuWnd; + + SystemMenu.PullDown[0].Selections[6].Accelerator = + (GetClass(wnd) == APPLICATION) ? ALT_F4 : CTRL_F4; + + lf = GetLeft(wnd)+1; + tp = GetTop(wnd)+1; + ht = MenuHeight(SystemMenu.PullDown[0].Selections); + wd = MenuWidth(SystemMenu.PullDown[0].Selections); + + if (lf+wd > SCREENWIDTH-1) + lf = (SCREENWIDTH-1) - wd; + if (tp+ht > SCREENHEIGHT-2) + tp = (SCREENHEIGHT-2) - ht; + + SystemMenuWnd = DfCreateWindow(POPDOWNMENU, NULL, + lf,tp,ht,wd,NULL,wnd,SystemMenuProc, 0); + +#ifdef INCLUDE_RESTORE + if (wnd->condition == ISRESTORED) + DeactivateCommand(&SystemMenu, ID_SYSRESTORE); + else + ActivateCommand(&SystemMenu, ID_SYSRESTORE); +#endif + + if (TestAttribute(wnd, MOVEABLE) +#ifdef INCLUDE_MAXIMIZE + && wnd->condition != ISMAXIMIZED +#endif + ) + ActivateCommand(&SystemMenu, ID_SYSMOVE); + else + DeactivateCommand(&SystemMenu, ID_SYSMOVE); + + if (wnd->condition != ISRESTORED || + TestAttribute(wnd, SIZEABLE) == FALSE) + DeactivateCommand(&SystemMenu, ID_SYSSIZE); + else + ActivateCommand(&SystemMenu, ID_SYSSIZE); + +#ifdef INCLUDE_MINIMIZE + if (wnd->condition == ISMINIMIZED || + TestAttribute(wnd, MINMAXBOX) == FALSE) + DeactivateCommand(&SystemMenu, ID_SYSMINIMIZE); + else + ActivateCommand(&SystemMenu, ID_SYSMINIMIZE); +#endif + +#ifdef INCLUDE_MAXIMIZE + if (wnd->condition != ISRESTORED || + TestAttribute(wnd, MINMAXBOX) == FALSE) + DeactivateCommand(&SystemMenu, ID_SYSMAXIMIZE); + else + ActivateCommand(&SystemMenu, ID_SYSMAXIMIZE); +#endif + + DfSendMessage(SystemMenuWnd, BUILD_SELECTIONS, + (PARAM) &SystemMenu.PullDown[0], 0); + DfSendMessage(SystemMenuWnd, SETFOCUS, TRUE, 0); + DfSendMessage(SystemMenuWnd, SHOW_WINDOW, 0, 0); +} + +/* EOF */ diff --git a/rosapps/dflat32/system.h b/rosapps/dflat32/system.h new file mode 100644 index 00000000000..944dc7c3a19 --- /dev/null +++ b/rosapps/dflat32/system.h @@ -0,0 +1,92 @@ +/* --------------- system.h -------------- */ +#ifndef SYSTEM_H +#define SYSTEM_H + +//#if MSC | WATCOM +#include +//#else +//#include +//#endif + +#define swap(a,b){int x=a;a=b;b=x;} +/* ------- platform-dependent values ------ */ +#define KEYBOARDPORT 0x60 +#define FREQUENCY 100 +#define COUNT (1193280L / FREQUENCY) +#define ZEROFLAG 0x40 +#define MAXSAVES 50 + +#define SCREENWIDTH (80) +#define SCREENHEIGHT (25) + +/* ---------- keyboard prototypes -------- */ +int AltConvert(int); +void GetKey(PINPUT_RECORD); +int getshift(void); +BOOL keyhit(void); +void beep(void); + +/* ---------- cursor prototypes -------- */ +void curr_cursor(int *x, int *y); +void cursor(int x, int y); +void hidecursor(void); +void unhidecursor(void); +void savecursor(void); +void restorecursor(void); +void normalcursor(void); +void set_cursor_type(unsigned t); +void videomode(void); +void SwapCursorStack(void); + +/* ------------ timer macros -------------- */ +#define timed_out(timer) (timer==0) +#define set_timer(timer, secs) timer=(secs)*182/10+1 +#define disable_timer(timer) timer = -1 +#define timer_running(timer) (timer > 0) +#define countdown(timer) --timer +#define timer_disabled(timer) (timer == -1) + + +#ifndef TURBOC +#ifndef BCPP +/* ============= Color Macros ============ */ +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define CYAN 3 +#define RED 4 +#define MAGENTA 5 +#define BROWN 6 +#define LIGHTGRAY 7 +#define DARKGRAY 8 +#define LIGHTBLUE 9 +#define LIGHTGREEN 10 +#define LIGHTCYAN 11 +#define LIGHTRED 12 +#define LIGHTMAGENTA 13 +#define YELLOW 14 +#define WHITE 15 +#define keyhit kbhit +#endif +#endif + +typedef enum messages { +#ifdef WATCOM + WATCOMFIX1 = -1, +#endif + #undef DFlatMsg + #define DFlatMsg(m) m, + #include "dflatmsg.h" + MESSAGECOUNT +} DFMESSAGE; + +typedef enum window_class { +#ifdef WATCOM + WATCOMFIX2 = -1, +#endif + #define ClassDef(c,b,p,a) c, + #include "classes.h" + CLASSCOUNT +} DFCLASS; + +#endif diff --git a/rosapps/dflat32/text.c b/rosapps/dflat32/text.c new file mode 100644 index 00000000000..c9635e63dc8 --- /dev/null +++ b/rosapps/dflat32/text.c @@ -0,0 +1,65 @@ +/* -------------- text.c -------------- */ + +#include "dflat.h" + +int TextProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int i, len; + CTLWINDOW *ct = GetControl(wnd); + char *cp, *cp2 = ct->itext; + char *ptr; + + switch (msg) + { + case SETFOCUS: + return TRUE; + + case LEFT_BUTTON: + return TRUE; + + case PAINT: + if (ct == NULL || + ct->itext == NULL || + GetText(wnd) != NULL) + break; + len = min(ct->dwnd.h, MsgHeight(cp2)); + + ptr = DFmalloc (strlen (cp2) + 1); + strcpy (ptr, cp2); + cp = ptr; + for (i = 0; i < len; i++) + { + int mlen; + char *txt = cp; + char *cp1 = cp; + char *np = strchr(cp, '\n'); + if (np != NULL) + *np = '\0'; + mlen = strlen(cp); + while ((cp1=strchr(cp1,SHORTCUTCHAR)) != NULL) + { + mlen += 3; + cp1++; + } + + if (np != NULL) + *np = '\n'; + txt = DFmalloc(mlen+1); + CopyCommand(txt, cp, FALSE, WndBackground(wnd)); + txt[mlen] = '\0'; + DfSendMessage(wnd, ADDTEXT, (PARAM)txt, 0); + if ((cp = strchr(cp, '\n')) != NULL) + cp++; + free(txt); + } + free (ptr); + break; + + default: + break; + } + + return BaseWndProc(TEXT, wnd, msg, p1, p2); +} + +/* EOF */ diff --git a/rosapps/dflat32/textbox.c b/rosapps/dflat32/textbox.c new file mode 100644 index 00000000000..cc5fb7d553e --- /dev/null +++ b/rosapps/dflat32/textbox.c @@ -0,0 +1,874 @@ +/* ------------- textbox.c ------------ */ + +#include "dflat.h" + +static void ComputeWindowTop(DFWINDOW); +static void ComputeWindowLeft(DFWINDOW); +static int ComputeVScrollBox(DFWINDOW); +static int ComputeHScrollBox(DFWINDOW); +static void MoveScrollBox(DFWINDOW, int); +static char *GetTextLine(DFWINDOW, int); + +BOOL VSliding; +BOOL HSliding; + +/* ------------ ADDTEXT Message -------------- */ +static BOOL AddTextMsg(DFWINDOW wnd, char *txt) +{ + /* --- append text to the textbox's buffer --- */ + unsigned adln = strlen(txt); + if (adln > (unsigned)0xfff0) + return FALSE; + if (wnd->text != NULL) { + /* ---- appending to existing text ---- */ + unsigned txln = strlen(wnd->text); + if ((long)txln+adln > (unsigned) 0xfff0) + return FALSE; + if (txln+adln > wnd->textlen) { + wnd->text = DFrealloc(wnd->text, txln+adln+3); + wnd->textlen = txln+adln+1; + } + } + else { + /* ------ 1st text appended ------ */ + wnd->text = DFcalloc(1, adln+3); + wnd->textlen = adln+1; + } + if (wnd->text != NULL) { + /* ---- append the text ---- */ + strcat(wnd->text, txt); + strcat(wnd->text, "\n"); + BuildTextPointers(wnd); + return TRUE; + } + return FALSE; +} + +/* ------------ DELETETEXT Message -------------- */ +static void DeleteTextMsg(DFWINDOW wnd, int lno) +{ + char *cp1 = TextLine(wnd, lno); + --wnd->wlines; + if (lno == wnd->wlines) + *cp1 = '\0'; + else { + char *cp2 = TextLine(wnd, lno+1); + memmove(cp1, cp2, strlen(cp2)+1); + } + BuildTextPointers(wnd); +} + +/* ------------ INSERTTEXT Message -------------- */ +static void InsertTextMsg(DFWINDOW wnd, char *txt, int lno) +{ + if (AddTextMsg(wnd, txt)) { + int len = strlen(txt); + char *cp2 = TextLine(wnd, lno); + char *cp1 = cp2+len+1; + memmove(cp1, cp2, strlen(cp2)-len); + strcpy(cp2, txt); + *(cp2+len) = '\n'; + BuildTextPointers(wnd); + } +} + +/* ------------ SETTEXT Message -------------- */ +static void SetTextMsg(DFWINDOW wnd, char *txt) +{ + /* -- assign new text value to textbox buffer -- */ + unsigned int len = strlen(txt)+1; + DfSendMessage(wnd, CLEARTEXT, 0, 0); + wnd->textlen = len; + wnd->text=DFrealloc(wnd->text, len+1); + wnd->text[len] = '\0'; + strcpy(wnd->text, txt); + BuildTextPointers(wnd); +} + +/* ------------ CLEARTEXT Message -------------- */ +static void ClearTextMsg(DFWINDOW wnd) +{ + /* ----- clear text from textbox ----- */ + if (wnd->text != NULL) + free(wnd->text); + wnd->text = NULL; + wnd->textlen = 0; + wnd->wlines = 0; + wnd->textwidth = 0; + wnd->wtop = wnd->wleft = 0; + ClearTextBlock(wnd); + ClearTextPointers(wnd); +} + +/* ------------ KEYBOARD Message -------------- */ +static int KeyboardMsg(DFWINDOW wnd, PARAM p1) +{ + switch ((int) p1) { + case UP: + return DfSendMessage(wnd,SCROLL,FALSE,0); + case DN: + return DfSendMessage(wnd,SCROLL,TRUE,0); + case FWD: + return DfSendMessage(wnd,HORIZSCROLL,TRUE,0); + case BS: + return DfSendMessage(wnd,HORIZSCROLL,FALSE,0); + case PGUP: + return DfSendMessage(wnd,SCROLLPAGE,FALSE,0); + case PGDN: + return DfSendMessage(wnd,SCROLLPAGE,TRUE,0); + case CTRL_PGUP: + return DfSendMessage(wnd,HORIZPAGE,FALSE,0); + case CTRL_PGDN: + return DfSendMessage(wnd,HORIZPAGE,TRUE,0); + case HOME: + return DfSendMessage(wnd,SCROLLDOC,TRUE,0); + case END: + return DfSendMessage(wnd,SCROLLDOC,FALSE,0); + default: + break; + } + return FALSE; +} + +/* ------------ LEFT_BUTTON Message -------------- */ +static int LeftButtonMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int mx = (int) p1 - GetLeft(wnd); + int my = (int) p2 - GetTop(wnd); + if (TestAttribute(wnd, VSCROLLBAR) && + mx == WindowWidth(wnd)-1) { + /* -------- in the right border ------- */ + if (my == 0 || my == ClientHeight(wnd)+1) + /* --- above or below the scroll bar --- */ + return FALSE; + if (my == 1) + /* -------- top scroll button --------- */ + return DfSendMessage(wnd, SCROLL, FALSE, 0); + if (my == ClientHeight(wnd)) + /* -------- bottom scroll button --------- */ + return DfSendMessage(wnd, SCROLL, TRUE, 0); + /* ---------- in the scroll bar ----------- */ + if (!VSliding && my-1 == wnd->VScrollBox) { + DFRECT rc; + VSliding = TRUE; + rc.lf = rc.rt = GetRight(wnd); + rc.tp = GetTop(wnd)+2; + rc.bt = GetBottom(wnd)-2; + return DfSendMessage(NULL, MOUSE_TRAVEL, + (PARAM) &rc, 0); + } + if (my-1 < wnd->VScrollBox) + return DfSendMessage(wnd,SCROLLPAGE,FALSE,0); + if (my-1 > wnd->VScrollBox) + return DfSendMessage(wnd,SCROLLPAGE,TRUE,0); + } + if (TestAttribute(wnd, HSCROLLBAR) && + my == WindowHeight(wnd)-1) { + /* -------- in the bottom border ------- */ + if (mx == 0 || my == ClientWidth(wnd)+1) + /* ------ outside the scroll bar ---- */ + return FALSE; + if (mx == 1) + return DfSendMessage(wnd, HORIZSCROLL,FALSE,0); + if (mx == WindowWidth(wnd)-2) + return DfSendMessage(wnd, HORIZSCROLL,TRUE,0); + if (!HSliding && mx-1 == wnd->HScrollBox) { + /* --- hit the scroll box --- */ + DFRECT rc; + rc.lf = GetLeft(wnd)+2; + rc.rt = GetRight(wnd)-2; + rc.tp = rc.bt = GetBottom(wnd); + /* - keep the mouse in the scroll bar - */ + DfSendMessage(NULL,MOUSE_TRAVEL,(PARAM)&rc,0); + HSliding = TRUE; + return TRUE; + } + if (mx-1 < wnd->HScrollBox) + return DfSendMessage(wnd,HORIZPAGE,FALSE,0); + if (mx-1 > wnd->HScrollBox) + return DfSendMessage(wnd,HORIZPAGE,TRUE,0); + } + return FALSE; +} + +/* ------------ MOUSE_MOVED Message -------------- */ +static BOOL MouseMovedMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + int mx = (int) p1 - GetLeft(wnd); + int my = (int) p2 - GetTop(wnd); + if (VSliding) { + /* ---- dragging the vertical scroll box --- */ + if (my-1 != wnd->VScrollBox) { + foreground = FrameForeground(wnd); + background = FrameBackground(wnd); + wputch(wnd, SCROLLBARCHAR, WindowWidth(wnd)-1, + wnd->VScrollBox+1); + wnd->VScrollBox = my-1; + wputch(wnd, SCROLLBOXCHAR, WindowWidth(wnd)-1, + my); + } + return TRUE; + } + if (HSliding) { + /* --- dragging the horizontal scroll box --- */ + if (mx-1 != wnd->HScrollBox) { + foreground = FrameForeground(wnd); + background = FrameBackground(wnd); + wputch(wnd, SCROLLBARCHAR, wnd->HScrollBox+1, + WindowHeight(wnd)-1); + wnd->HScrollBox = mx-1; + wputch(wnd, SCROLLBOXCHAR, mx, WindowHeight(wnd)-1); + } + return TRUE; + } + return FALSE; +} + +/* ------------ BUTTON_RELEASED Message -------------- */ +static void ButtonReleasedMsg(DFWINDOW wnd) +{ + if (HSliding || VSliding) { + /* release the mouse ouside the scroll bar */ + DfSendMessage(NULL, MOUSE_TRAVEL, 0, 0); + VSliding ? ComputeWindowTop(wnd):ComputeWindowLeft(wnd); + DfSendMessage(wnd, PAINT, 0, 0); + DfSendMessage(wnd, KEYBOARD_CURSOR, 0, 0); + VSliding = HSliding = FALSE; + } +} + +/* ------------ SCROLL Message -------------- */ +static BOOL ScrollMsg(DFWINDOW wnd, PARAM p1) +{ + /* ---- vertical scroll one line ---- */ + if (p1) { + /* ----- scroll one line up ----- */ + if (wnd->wtop+ClientHeight(wnd) >= wnd->wlines) + return FALSE; + wnd->wtop++; + } + else { + /* ----- scroll one line down ----- */ + if (wnd->wtop == 0) + return FALSE; + --wnd->wtop; + } + if (isVisible(wnd)) { + DFRECT rc; + rc = ClipRectangle(wnd, ClientRect(wnd)); + if (ValidRect(rc)) { + /* ---- scroll the window ----- */ + if (wnd != inFocus) + DfSendMessage(wnd, PAINT, 0, 0); + else { + scroll_window(wnd, rc, (int)p1); + if (!(int)p1) + /* -- write top line (down) -- */ + WriteTextLine(wnd,NULL,wnd->wtop,FALSE); + else { + /* -- write bottom line (up) -- */ + int y=RectBottom(rc)-GetClientTop(wnd); + WriteTextLine(wnd, NULL, + wnd->wtop+y, FALSE); + } + } + } + /* ---- reset the scroll box ---- */ + if (TestAttribute(wnd, VSCROLLBAR)) { + int vscrollbox = ComputeVScrollBox(wnd); + if (vscrollbox != wnd->VScrollBox) + MoveScrollBox(wnd, vscrollbox); + } + } + return TRUE; +} + +/* ------------ HORIZSCROLL Message -------------- */ +static BOOL HorizScrollMsg(DFWINDOW wnd, PARAM p1) +{ + /* --- horizontal scroll one column --- */ + if (p1) { + /* --- scroll left --- */ + if (wnd->wleft + ClientWidth(wnd)-1 >= wnd->textwidth) + return FALSE; + wnd->wleft++; + } + else { + /* --- scroll right --- */ + if (wnd->wleft == 0) + return FALSE; + --wnd->wleft; + } + DfSendMessage(wnd, PAINT, 0, 0); + return TRUE; +} + +/* ------------ SCROLLPAGE Message -------------- */ +static void ScrollPageMsg(DFWINDOW wnd, PARAM p1) +{ + /* --- vertical scroll one page --- */ + if ((int) p1 == FALSE) { + /* ---- page up ---- */ + if (wnd->wtop) + wnd->wtop -= ClientHeight(wnd); + } + else { + /* ---- page down ---- */ + if (wnd->wtop+ClientHeight(wnd) < wnd->wlines) { + wnd->wtop += ClientHeight(wnd); + if (wnd->wtop>wnd->wlines-ClientHeight(wnd)) + wnd->wtop=wnd->wlines-ClientHeight(wnd); + } + } + if (wnd->wtop < 0) + wnd->wtop = 0; + DfSendMessage(wnd, PAINT, 0, 0); +} + +/* ------------ HORIZSCROLLPAGE Message -------------- */ +static void HorizScrollPageMsg(DFWINDOW wnd, PARAM p1) +{ + /* --- horizontal scroll one page --- */ + if ((int) p1 == FALSE) + /* ---- page left ----- */ + wnd->wleft -= ClientWidth(wnd); + else { + /* ---- page right ----- */ + wnd->wleft += ClientWidth(wnd); + if (wnd->wleft > wnd->textwidth-ClientWidth(wnd)) + wnd->wleft = wnd->textwidth-ClientWidth(wnd); + } + if (wnd->wleft < 0) + wnd->wleft = 0; + DfSendMessage(wnd, PAINT, 0, 0); +} + +/* ------------ SCROLLDOC Message -------------- */ +static void ScrollDocMsg(DFWINDOW wnd, PARAM p1) +{ + /* --- scroll to beginning or end of document --- */ + if ((int) p1) + wnd->wtop = wnd->wleft = 0; + else if (wnd->wtop+ClientHeight(wnd) < wnd->wlines){ + wnd->wtop = wnd->wlines-ClientHeight(wnd); + wnd->wleft = 0; + } + DfSendMessage(wnd, PAINT, 0, 0); +} + +/* ------------ PAINT Message -------------- */ +static void PaintMsg(DFWINDOW wnd, PARAM p1, PARAM p2) +{ + /* ------ paint the client area ----- */ + DFRECT rc, rcc; + int y; + char blankline[201]; + + /* ----- build the rectangle to paint ----- */ + if ((DFRECT *)p1 == NULL) + rc=RelativeWindowRect(wnd, WindowRect(wnd)); + else + rc= *(DFRECT *)p1; + if (TestAttribute(wnd, HASBORDER) && + RectRight(rc) >= WindowWidth(wnd)-1) { + if (RectLeft(rc) >= WindowWidth(wnd)-1) + return; + RectRight(rc) = WindowWidth(wnd)-2; + } + rcc = AdjustRectangle(wnd, rc); + + if (!p2 && wnd != inFocus) + ClipString++; + + /* ----- blank line for padding ----- */ + memset(blankline, ' ', SCREENWIDTH); + blankline[RectRight(rcc)+1] = '\0'; + + /* ------- each line within rectangle ------ */ + for (y = RectTop(rc); y <= RectBottom(rc); y++){ + int yy; + /* ---- test outside of Client area ---- */ + if (TestAttribute(wnd, + HASBORDER | HASTITLEBAR)) { + if (y < TopBorderAdj(wnd)) + continue; + if (y > WindowHeight(wnd)-2) + continue; + } + yy = y-TopBorderAdj(wnd); + if (yy < wnd->wlines-wnd->wtop) + /* ---- paint a text line ---- */ + WriteTextLine(wnd, &rc, + yy+wnd->wtop, FALSE); + else { + /* ---- paint a blank line ---- */ + SetStandardColor(wnd); + writeline(wnd, blankline+RectLeft(rcc), + RectLeft(rcc)+BorderAdj(wnd), y, FALSE); + } + } + /* ------- position the scroll box ------- */ + if (TestAttribute(wnd, VSCROLLBAR|HSCROLLBAR)) { + int hscrollbox = ComputeHScrollBox(wnd); + int vscrollbox = ComputeVScrollBox(wnd); + if (hscrollbox != wnd->HScrollBox || + vscrollbox != wnd->VScrollBox) { + wnd->HScrollBox = hscrollbox; + wnd->VScrollBox = vscrollbox; + DfSendMessage(wnd, BORDER, p1, 0); + } + } + if (!p2 && wnd != inFocus) + --ClipString; +} + +/* ------------ CLOSE_WINDOW Message -------------- */ +static void CloseWindowMsg(DFWINDOW wnd) +{ + DfSendMessage(wnd, CLEARTEXT, 0, 0); + if (wnd->TextPointers != NULL) { + free(wnd->TextPointers); + wnd->TextPointers = NULL; + } +} + +/* ----------- TEXTBOX Message-processing Module ----------- */ +int TextBoxProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + switch (msg) { + case CREATE_WINDOW: + wnd->HScrollBox = wnd->VScrollBox = 1; + ClearTextPointers(wnd); + break; + case ADDTEXT: + return AddTextMsg(wnd, (char *) p1); + case DELETETEXT: + DeleteTextMsg(wnd, (int) p1); + return TRUE; + case INSERTTEXT: + InsertTextMsg(wnd, (char *) p1, (int) p2); + return TRUE; + case SETTEXT: + SetTextMsg(wnd, (char *) p1); + return TRUE; + case CLEARTEXT: + ClearTextMsg(wnd); + break; + case KEYBOARD: + if (WindowMoving || WindowSizing) + break; + if (KeyboardMsg(wnd, p1)) + return TRUE; + break; + case LEFT_BUTTON: + if (WindowSizing || WindowMoving) + return FALSE; + if (LeftButtonMsg(wnd, p1, p2)) + return TRUE; + break; + case MOUSE_MOVED: + if (MouseMovedMsg(wnd, p1, p2)) + return TRUE; + break; + case DFM_BUTTON_RELEASED: + ButtonReleasedMsg(wnd); + break; + case SCROLL: + return ScrollMsg(wnd, p1); + case HORIZSCROLL: + return HorizScrollMsg(wnd, p1); + case SCROLLPAGE: + ScrollPageMsg(wnd, p1); + return TRUE; + case HORIZPAGE: + HorizScrollPageMsg(wnd, p1); + return TRUE; + case SCROLLDOC: + ScrollDocMsg(wnd, p1); + return TRUE; + case PAINT: + if (isVisible(wnd)) + { + PaintMsg(wnd, p1, p2); + return FALSE; + } + break; + case CLOSE_WINDOW: + CloseWindowMsg(wnd); + break; + default: + break; + } + return BaseWndProc(TEXTBOX, wnd, msg, p1, p2); +} + +/* ------ compute the vertical scroll box position from + the text pointers --------- */ +static int ComputeVScrollBox(DFWINDOW wnd) +{ + int pagelen = wnd->wlines - ClientHeight(wnd); + int barlen = ClientHeight(wnd)-2; + int lines_tick; + int vscrollbox; + + if (pagelen < 1 || barlen < 1) + vscrollbox = 1; + else { + if (pagelen > barlen) + lines_tick = pagelen / barlen; + else + lines_tick = barlen / pagelen; + vscrollbox = 1 + (wnd->wtop / lines_tick); + if (vscrollbox > ClientHeight(wnd)-2 || + wnd->wtop + ClientHeight(wnd) >= wnd->wlines) + vscrollbox = ClientHeight(wnd)-2; + } + return vscrollbox; +} + +/* ---- compute top text line from scroll box position ---- */ +static void ComputeWindowTop(DFWINDOW wnd) +{ + int pagelen = wnd->wlines - ClientHeight(wnd); + if (wnd->VScrollBox == 0) + wnd->wtop = 0; + else if (wnd->VScrollBox == ClientHeight(wnd)-2) + wnd->wtop = pagelen; + else { + int barlen = ClientHeight(wnd)-2; + int lines_tick; + + if (pagelen > barlen) + lines_tick = barlen ? (pagelen / barlen) : 0; + else + lines_tick = pagelen ? (barlen / pagelen) : 0; + wnd->wtop = (wnd->VScrollBox-1) * lines_tick; + if (wnd->wtop + ClientHeight(wnd) > wnd->wlines) + wnd->wtop = pagelen; + } + if (wnd->wtop < 0) + wnd->wtop = 0; +} + +/* ------ compute the horizontal scroll box position from + the text pointers --------- */ +static int ComputeHScrollBox(DFWINDOW wnd) +{ + int pagewidth = wnd->textwidth - ClientWidth(wnd); + int barlen = ClientWidth(wnd)-2; + int chars_tick; + int hscrollbox; + + if (pagewidth < 1 || barlen < 1) + hscrollbox = 1; + else { + if (pagewidth > barlen) + chars_tick = barlen ? (pagewidth / barlen) : 0; + else + chars_tick = pagewidth ? (barlen / pagewidth) : 0; + hscrollbox = 1 + (chars_tick ? (wnd->wleft / chars_tick) : 0); + if (hscrollbox > ClientWidth(wnd)-2 || + wnd->wleft + ClientWidth(wnd) >= wnd->textwidth) + hscrollbox = ClientWidth(wnd)-2; + } + return hscrollbox; +} + +/* ---- compute left column from scroll box position ---- */ +static void ComputeWindowLeft(DFWINDOW wnd) +{ + int pagewidth = wnd->textwidth - ClientWidth(wnd); + + if (wnd->HScrollBox == 0) + wnd->wleft = 0; + else if (wnd->HScrollBox == ClientWidth(wnd)-2) + wnd->wleft = pagewidth; + else { + int barlen = ClientWidth(wnd)-2; + int chars_tick; + + if (pagewidth > barlen) + chars_tick = pagewidth / barlen; + else + chars_tick = barlen / pagewidth; + wnd->wleft = (wnd->HScrollBox-1) * chars_tick; + if (wnd->wleft + ClientWidth(wnd) > wnd->textwidth) + wnd->wleft = pagewidth; + } + if (wnd->wleft < 0) + wnd->wleft = 0; +} + +/* ----- get the text to a specified line ----- */ +static char *GetTextLine(DFWINDOW wnd, int selection) +{ + char *line; + int len = 0; + char *cp, *cp1; + cp = cp1 = TextLine(wnd, selection); + while (*cp && *cp != '\n') { + len++; + cp++; + } + line = DFmalloc(len+7); + memmove(line, cp1, len); + line[len] = '\0'; + return line; +} + +/* ------- write a line of text to a textbox window ------- */ +void WriteTextLine(DFWINDOW wnd, DFRECT *rcc, int y, BOOL reverse) +{ + int len = 0; + int dif = 0; + unsigned char line[200]; + DFRECT rc; + unsigned char *lp, *svlp; + int lnlen; + int i; + BOOL trunc = FALSE; + + /* ------ make sure y is inside the window ----- */ + if (y < wnd->wtop || y >= wnd->wtop+ClientHeight(wnd)) + return; + + /* ---- build the retangle within which can write ---- */ + if (rcc == NULL) { + rc = RelativeWindowRect(wnd, WindowRect(wnd)); + if (TestAttribute(wnd, HASBORDER) && + RectRight(rc) >= WindowWidth(wnd)-1) + RectRight(rc) = WindowWidth(wnd)-2; + } + else + rc = *rcc; + + /* ----- make sure rectangle is within window ------ */ + if (RectLeft(rc) >= WindowWidth(wnd)-1) + return; + if (RectRight(rc) == 0) + return; + rc = AdjustRectangle(wnd, rc); + if (y-wnd->wtopwtop>RectBottom(rc)) + return; + + /* --- get the text and length of the text line --- */ + lp = svlp = GetTextLine(wnd, y); + if (svlp == NULL) + return; + lnlen = LineLength(lp); + + /* -------- insert block color change controls ------- */ + if (TextBlockMarked(wnd)) { + int bbl = wnd->BlkBegLine; + int bel = wnd->BlkEndLine; + int bbc = wnd->BlkBegCol; + int bec = wnd->BlkEndCol; + int by = y; + + /* ----- put lowest marker first ----- */ + if (bbl > bel) { + swap(bbl, bel); + swap(bbc, bec); + } + if (bbl == bel && bbc > bec) + swap(bbc, bec); + + if (by >= bbl && by <= bel) { + /* ------ the block includes this line ----- */ + int blkbeg = 0; + int blkend = lnlen; + if (!(by > bbl && by < bel)) { + /* --- the entire line is not in the block -- */ + if (by == bbl) + /* ---- the block begins on this line --- */ + blkbeg = bbc; + if (by == bel) + /* ---- the block ends on this line ---- */ + blkend = bec; + } + if (blkend == 0 && lnlen == 0) { + strcpy(lp, " "); + blkend++; + } + /* ----- insert the reset color token ----- */ + memmove(lp+blkend+1,lp+blkend,strlen(lp+blkend)+1); + lp[blkend] = RESETCOLOR; + /* ----- insert the change color token ----- */ + memmove(lp+blkbeg+3,lp+blkbeg,strlen(lp+blkbeg)+1); + lp[blkbeg] = CHANGECOLOR; + /* ----- insert the color tokens ----- */ + SetReverseColor(wnd); + lp[blkbeg+1] = foreground | 0x80; + lp[blkbeg+2] = background | 0x80; + lnlen += 4; + } + } + /* - make sure left margin doesn't overlap color change - */ + for (i = 0; i < wnd->wleft+3; i++) { + if (*(lp+i) == '\0') + break; + if (*(unsigned char *)(lp + i) == RESETCOLOR) + break; + } + if (*(lp+i) && i < wnd->wleft+3) { + if (wnd->wleft+4 > lnlen) + trunc = TRUE; + else + lp += 4; + } + else { + /* --- it does, shift the color change over --- */ + for (i = 0; i < wnd->wleft; i++) { + if (*(lp+i) == '\0') + break; + if (*(unsigned char *)(lp + i) == CHANGECOLOR) { + *(lp+wnd->wleft+2) = *(lp+i+2); + *(lp+wnd->wleft+1) = *(lp+i+1); + *(lp+wnd->wleft) = *(lp+i); + break; + } + } + } + /* ------ build the line to display -------- */ + if (!trunc) { + if (lnlen < wnd->wleft) + lnlen = 0; + else + lp += wnd->wleft; + if (lnlen > RectLeft(rc)) { + /* ---- the line exceeds the rectangle ---- */ + int ct = RectLeft(rc); + char *initlp = lp; + /* --- point to end of clipped line --- */ + while (ct) { + if (*(unsigned char *)lp == CHANGECOLOR) + lp += 3; + else if (*(unsigned char *)lp == RESETCOLOR) + lp++; + else + lp++, --ct; + } + if (RectLeft(rc)) { + char *lpp = lp; + while (*lpp) { + if (*(unsigned char*)lpp==CHANGECOLOR) + break; + if (*(unsigned char*)lpp==RESETCOLOR) { + lpp = lp; + while (lpp >= initlp) { + if (*(unsigned char *)lpp == + CHANGECOLOR) { + lp -= 3; + memmove(lp,lpp,3); + break; + } + --lpp; + } + break; + } + lpp++; + } + } + lnlen = LineLength(lp); + len = min(lnlen, RectWidth(rc)); + dif = strlen(lp) - lnlen; + len += dif; + if (len > 0) + strncpy(line, lp, len); + } + } + /* -------- pad the line --------- */ + while (len < RectWidth(rc)+dif) + line[len++] = ' '; + line[len] = '\0'; + dif = 0; + /* ------ establish the line's main color ----- */ + if (reverse) { + char *cp = line; + SetReverseColor(wnd); + while ((cp = strchr(cp, CHANGECOLOR)) != NULL) { + cp += 2; + *cp++ = background | 0x80; + } + if (*(unsigned char *)line == CHANGECOLOR) + dif = 3; + } + else + SetStandardColor(wnd); + /* ------- display the line -------- */ + writeline(wnd, line+dif, + RectLeft(rc)+BorderAdj(wnd), + y-wnd->wtop+TopBorderAdj(wnd), FALSE); + free(svlp); +} + +void MarkTextBlock(DFWINDOW wnd, int BegLine, int BegCol, + int EndLine, int EndCol) +{ + wnd->BlkBegLine = BegLine; + wnd->BlkEndLine = EndLine; + wnd->BlkBegCol = BegCol; + wnd->BlkEndCol = EndCol; +} + +/* ----- clear and initialize text line pointer array ----- */ +void ClearTextPointers(DFWINDOW wnd) +{ + wnd->TextPointers = DFrealloc(wnd->TextPointers, sizeof(int)); + *(wnd->TextPointers) = 0; +} + +#define INITLINES 100 + +/* ---- build array of pointers to text lines ---- */ +void BuildTextPointers(DFWINDOW wnd) +{ + char *cp = wnd->text, *cp1; + int incrs = INITLINES; + unsigned int off; + wnd->textwidth = wnd->wlines = 0; + while (*cp) { + if (incrs == INITLINES) { + incrs = 0; + wnd->TextPointers = DFrealloc(wnd->TextPointers, + (wnd->wlines + INITLINES) * sizeof(int)); + } + off = (unsigned int) ((unsigned int)cp - (unsigned int)wnd->text); + *((wnd->TextPointers) + wnd->wlines) = off; + wnd->wlines++; + incrs++; + cp1 = cp; + while (*cp && *cp != '\n') + cp++; + wnd->textwidth = max(wnd->textwidth, (int)(cp - cp1)); + if (*cp) + cp++; + } +} + +static void MoveScrollBox(DFWINDOW wnd, int vscrollbox) +{ + foreground = FrameForeground(wnd); + background = FrameBackground(wnd); + wputch(wnd, SCROLLBARCHAR, WindowWidth(wnd)-1, + wnd->VScrollBox+1); + wputch(wnd, SCROLLBOXCHAR, WindowWidth(wnd)-1, + vscrollbox+1); + wnd->VScrollBox = vscrollbox; +} + +int TextLineNumber(DFWINDOW wnd, char *lp) +{ + int lineno; + char *cp; + for (lineno = 0; lineno < wnd->wlines; lineno++) { + cp = wnd->text + *((wnd->TextPointers) + lineno); + if (cp == lp) + return lineno; + if (cp > lp) + break; + } + return lineno-1; +} + +/* EOF */ diff --git a/rosapps/dflat32/video.c b/rosapps/dflat32/video.c new file mode 100644 index 00000000000..74385c986e1 --- /dev/null +++ b/rosapps/dflat32/video.c @@ -0,0 +1,323 @@ +/* --------------------- video.c -------------------- */ + +#include "dflat.h" + +#define clr(fg,bg) ((fg)|((bg)<<4)) + +BOOL ClipString; + +/* -- read a rectangle of video memory into a save buffer -- */ +void GetVideo(DFRECT rc, PCHAR_INFO bf) +{ + COORD Size; + COORD Pos; + SMALL_RECT Rect; + + Size.X = RectRight(rc) - RectLeft(rc) + 1; + Size.Y = RectBottom(rc) - RectTop(rc) + 1; + + Pos.X = 0; + Pos.Y = 0; + + Rect.Left = RectLeft(rc); + Rect.Top = RectTop(rc); + Rect.Right = RectRight(rc); + Rect.Bottom = RectBottom(rc); + + ReadConsoleOutput (GetStdHandle (STD_OUTPUT_HANDLE), + bf, + Size, + Pos, + &Rect); +} + +/* -- write a rectangle of video memory from a save buffer -- */ +void StoreVideo(DFRECT rc, PCHAR_INFO bf) +{ + COORD Size; + COORD Pos; + SMALL_RECT Rect; + + Size.X = RectRight(rc) - RectLeft(rc) + 1; + Size.Y = RectBottom(rc) - RectTop(rc) + 1; + + Pos.X = 0; + Pos.Y = 0; + + Rect.Left = RectLeft(rc); + Rect.Top = RectTop(rc); + Rect.Right = RectRight(rc); + Rect.Bottom = RectBottom(rc); + + WriteConsoleOutput (GetStdHandle (STD_OUTPUT_HANDLE), + bf, + Size, + Pos, + &Rect); +} + +/* -------- read a character of video memory ------- */ +char GetVideoChar(int x, int y) +{ + COORD pos; + DWORD dwRead; + char ch; + + pos.X = x; + pos.Y = y; + + ReadConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE), + &ch, + 1, + pos, + &dwRead); + + return ch; +} + +/* -------- write a character of video memory ------- */ +void PutVideoChar(int x, int y, int ch) +{ + COORD pos; + DWORD dwWritten; + + if (x < SCREENWIDTH && y < SCREENHEIGHT) + { + pos.X = x; + pos.Y = y; + + WriteConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE), + (char *)&ch, + 1, + pos, + &dwWritten); + } +} + +BOOL CharInView(DFWINDOW wnd, int x, int y) +{ + DFWINDOW nwnd = NextWindow(wnd); + DFWINDOW pwnd; + DFRECT rc; + int x1 = GetLeft(wnd)+x; + int y1 = GetTop(wnd)+y; + + if (!TestAttribute(wnd, VISIBLE)) + return FALSE; + if (!TestAttribute(wnd, NOCLIP)) + { + DFWINDOW wnd1 = GetParent(wnd); + while (wnd1 != NULL) + { + /* clip character to parent's borders */ + if (!TestAttribute(wnd1, VISIBLE)) + return FALSE; + if (!InsideRect(x1, y1, ClientRect(wnd1))) + return FALSE; + wnd1 = GetParent(wnd1); + } + } + while (nwnd != NULL) + { + if (!isHidden(nwnd) && !isAncestor(wnd, nwnd)) + { + rc = WindowRect(nwnd); + if (TestAttribute(nwnd, SHADOW)) + { + RectBottom(rc)++; + RectRight(rc)++; + } + if (!TestAttribute(nwnd, NOCLIP)) + { + pwnd = nwnd; + while (GetParent(pwnd)) + { + pwnd = GetParent(pwnd); + rc = subRectangle(rc, ClientRect(pwnd)); + } + } + if (InsideRect(x1,y1,rc)) + return FALSE; + } + nwnd = NextWindow(nwnd); + } + return (x1 < SCREENWIDTH && y1 < SCREENHEIGHT); +} + +/* -------- write a character to a window ------- */ +void wputch(DFWINDOW wnd, int c, int x, int y) +{ + if (CharInView(wnd, x, y)) + { + DWORD dwWritten; + COORD pos; + WORD Attr; + + pos.X = GetLeft(wnd)+x; + pos.Y = GetTop(wnd)+y; + + Attr = clr(foreground, background); + + WriteConsoleOutputAttribute (GetStdHandle(STD_OUTPUT_HANDLE), + &Attr, + 1, + pos, + &dwWritten); + + WriteConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE), + (char *)&c, + 1, + pos, + &dwWritten); + } +} + +/* ------- write a string to a window ---------- */ +void wputs(DFWINDOW wnd, void *s, int x, int y) +{ + + int x1 = GetLeft(wnd)+x; + int x2 = x1; + int y1 = GetTop(wnd)+y; + + if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT && isVisible(wnd)) + { + char ln[200]; + WORD attr[200]; + char *cp = ln; + WORD *ap = attr; + unsigned char *str = s; + int fg = foreground; + int bg = background; + int len; + int off = 0; + while (*str) + { + if (*str == CHANGECOLOR) + { + str++; + foreground = (*str++) & 0x7f; + background = (*str++) & 0x7f; + continue; + } + + if (*str == RESETCOLOR) + { + foreground = fg & 0x7f; + background = bg & 0x7f; + str++; + continue; + } + *cp = (*str & 255); + *ap = (WORD)clr(foreground, background); +// *cp1 = (*str & 255) | (clr(foreground, background) << 8); +// if (ClipString) +// if (!CharInView(wnd, x, y)) +// *cp1 = peek(video_address, vad(x2,y1)); + cp++; + ap++; + str++; + x++; + x2++; + } + foreground = fg; + background = bg; + len = (int)(cp-ln); + if (x1+len > SCREENWIDTH) + len = SCREENWIDTH-x1; + + if (!ClipString && !TestAttribute(wnd, NOCLIP)) + { + /* -- clip the line to within ancestor windows -- */ + DFRECT rc = WindowRect(wnd); + DFWINDOW nwnd = GetParent(wnd); + while (len > 0 && nwnd != NULL) + { + if (!isVisible(nwnd)) + { + len = 0; + break; + } + rc = subRectangle(rc, ClientRect(nwnd)); + nwnd = GetParent(nwnd); + } + while (len > 0 && !InsideRect(x1+off,y1,rc)) + { + off++; + --len; + } + if (len > 0) + { + x2 = x1+len-1; + while (len && !InsideRect(x2,y1,rc)) + { + --x2; + --len; + } + } + } + if (len > 0) + { + COORD pos; + DWORD dwWritten; + + pos.X = x1; + pos.Y = y1; + + WriteConsoleOutputAttribute (GetStdHandle(STD_OUTPUT_HANDLE), + attr, + len, + pos, + &dwWritten); + + WriteConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE), + ln, + len, + pos, + &dwWritten); + } + } +} + +/* --------- scroll the window. d: 1 = up, 0 = dn ---------- */ +void scroll_window(DFWINDOW wnd, DFRECT rc, int d) +{ + if (RectTop(rc) != RectBottom(rc)) + { + CHAR_INFO ciFill; + SMALL_RECT rcScroll; + SMALL_RECT rcClip; + COORD pos; + + ciFill.Attributes = clr(WndForeground(wnd),WndBackground(wnd)); + ciFill.Char.AsciiChar = ' '; + + rcScroll.Left = RectLeft(rc); + rcScroll.Right = RectRight(rc); + rcScroll.Top = RectTop(rc); + rcScroll.Bottom = RectBottom(rc); + + rcClip = rcScroll; + + pos.X = RectLeft(rc); + + if (d == 0) + { + /* scroll 1 line down */ + pos.Y = RectTop(rc)+1; + } + else + { + /* scroll 1 line up */ + pos.Y = RectTop(rc)-1; + } + + ScrollConsoleScreenBuffer (GetStdHandle(STD_OUTPUT_HANDLE), + &rcScroll, + &rcClip, + pos, + &ciFill); + } +} + +/* EOF */ diff --git a/rosapps/dflat32/video.h b/rosapps/dflat32/video.h new file mode 100644 index 00000000000..cc8996c970f --- /dev/null +++ b/rosapps/dflat32/video.h @@ -0,0 +1,18 @@ +/* ---------------- video.h ----------------- */ + +#ifndef VIDEO_H +#define VIDEO_H + +#include "rect.h" + +void GetVideo(DFRECT, PCHAR_INFO); +void StoreVideo(DFRECT, PCHAR_INFO); +void wputch(DFWINDOW, int, int, int); +char GetVideoChar(int, int); +void PutVideoChar(int, int, int); +void wputs(DFWINDOW, void *, int, int); +void scroll_window(DFWINDOW, DFRECT, int); + +#define videochar(x,y) (GetVideoChar(x,y) & 0xFF) + +#endif diff --git a/rosapps/dflat32/watch.c b/rosapps/dflat32/watch.c new file mode 100644 index 00000000000..c7871129f66 --- /dev/null +++ b/rosapps/dflat32/watch.c @@ -0,0 +1,58 @@ +/* ----------- watch.c ----------- */ + +#include "dflat.h" + +int WatchIconProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2) +{ + int rtn; + switch (msg) { + case CREATE_WINDOW: + rtn = DefaultWndProc(wnd, msg, p1, p2); + DfSendMessage(wnd, CAPTURE_MOUSE, 0, 0); + DfSendMessage(wnd, CAPTURE_KEYBOARD, 0, 0); + return rtn; + case PAINT: + SetStandardColor(wnd); + writeline(wnd, " R ", 1, 1, FALSE); + return TRUE; + case BORDER: + rtn = DefaultWndProc(wnd, msg, p1, p2); + writeline(wnd, "Í", 2, 0, FALSE); + return rtn; + case MOUSE_MOVED: + DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0); + DfSendMessage(wnd, MOVE, p1, p2); + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); + return TRUE; + case CLOSE_WINDOW: + DfSendMessage(wnd, RELEASE_MOUSE, 0, 0); + DfSendMessage(wnd, RELEASE_KEYBOARD, 0, 0); + break; + default: + break; + } + return DefaultWndProc(wnd, msg, p1, p2); +} + +DFWINDOW WatchIcon(void) +{ + int mx, my; + DFWINDOW wnd; + +/* this won't work !! */ +// DfSendMessage(NULL, DFM_CURRENT_MOUSE_CURSOR, +// (PARAM) &mx, (PARAM) &my); + + mx = 0;//SCREENWIDTH / 2; + mx = 0;//SCREENHEIGHT / 2; + wnd = DfCreateWindow( + BOX, + NULL, + mx, my, 3, 5, + NULL,NULL, + WatchIconProc, + VISIBLE | HASBORDER | SHADOW | SAVESELF); + return wnd; +} + +/* EOF */ diff --git a/rosapps/dflat32/window.c b/rosapps/dflat32/window.c new file mode 100644 index 00000000000..63d4bc0c70d --- /dev/null +++ b/rosapps/dflat32/window.c @@ -0,0 +1,519 @@ +/* ---------- window.c ------------- */ + +#include "dflat.h" + +DFWINDOW inFocus = NULL; + +int foreground, background; /* current video colors */ + +static void TopLine(DFWINDOW, int, DFRECT); + +/* --------- create a window ------------ */ +DFWINDOW DfCreateWindow( + DFCLASS class, /* class of this window */ + char *ttl, /* title or NULL */ + int left, int top, /* upper left coordinates */ + int height, int width, /* dimensions */ + void *extension, /* pointer to additional data */ + DFWINDOW parent, /* parent of this window */ + int (*wndproc)(struct window *,enum messages,PARAM,PARAM), + int attrib) /* window attribute */ +{ + DFWINDOW wnd = DFcalloc(1, sizeof(struct window)); + if (wnd != NULL) { + int base; + /* ----- height, width = -1: fill the screen ------- */ + if (height == -1) + height = SCREENHEIGHT; + if (width == -1) + width = SCREENWIDTH; + /* ----- coordinates -1, -1 = center the window ---- */ + if (left == -1) + wnd->rc.lf = (SCREENWIDTH-width)/2; + else + wnd->rc.lf = left; + if (top == -1) + wnd->rc.tp = (SCREENHEIGHT-height)/2; + else + wnd->rc.tp = top; + wnd->attrib = attrib; + if (ttl != NULL) + AddAttribute(wnd, HASTITLEBAR); + if (wndproc == NULL) + wnd->wndproc = classdefs[class].wndproc; + else + wnd->wndproc = wndproc; + /* ---- derive attributes of base classes ---- */ + base = class; + while (base != -1) { + AddAttribute(wnd, classdefs[base].attrib); + base = classdefs[base].base; + } + if (parent) + { + if (!TestAttribute(wnd, NOCLIP)) + { + /* -- keep upper left within borders of parent - */ + wnd->rc.lf = max(wnd->rc.lf,GetClientLeft(parent)); + wnd->rc.tp = max(wnd->rc.tp,GetClientTop(parent)); + } + } + else + parent = ApplicationWindow; + + wnd->class = class; + wnd->extension = extension; + wnd->rc.rt = GetLeft(wnd)+width-1; + wnd->rc.bt = GetTop(wnd)+height-1; + wnd->ht = height; + wnd->wd = width; + if (ttl != NULL) + InsertTitle(wnd, ttl); + wnd->parent = parent; + wnd->oldcondition = wnd->condition = ISRESTORED; + wnd->RestoredRC = wnd->rc; + InitWindowColors(wnd); + DfSendMessage(wnd, CREATE_WINDOW, 0, 0); + if (isVisible(wnd)) + DfSendMessage(wnd, SHOW_WINDOW, 0, 0); + } + return wnd; +} + +/* -------- add a title to a window --------- */ +void AddTitle(DFWINDOW wnd, char *ttl) +{ + InsertTitle(wnd, ttl); + DfSendMessage(wnd, BORDER, 0, 0); +} + +/* ----- insert a title into a window ---------- */ +void InsertTitle(DFWINDOW wnd, char *ttl) +{ + wnd->title=DFrealloc(wnd->title,strlen(ttl)+1); + strcpy(wnd->title, ttl); +} + +static unsigned char line[300]; + +/* ------ write a line to video window client area ------ */ +void writeline(DFWINDOW wnd, char *str, int x, int y, BOOL pad) +{ + char *cp; + int len; + int dif; + char wline[200]; + + memset(wline, 0, 200); + len = LineLength(str); + dif = strlen(str) - len; + strncpy(wline, str, ClientWidth(wnd) + dif); + if (pad) { + cp = wline+strlen(wline); + while (len++ < ClientWidth(wnd)-x) + *cp++ = ' '; + } + wputs(wnd, wline, x, y); +} + +DFRECT AdjustRectangle(DFWINDOW wnd, DFRECT rc) +{ + /* -------- adjust the rectangle ------- */ + if (TestAttribute(wnd, HASBORDER)) { + if (RectLeft(rc) == 0) + --rc.rt; + else if (RectLeft(rc) < RectRight(rc) && + RectLeft(rc) < WindowWidth(wnd)+1) + --rc.lf; + } + if (TestAttribute(wnd, HASBORDER | HASTITLEBAR)) { + if (RectTop(rc) == 0) + --rc.bt; + else if (RectTop(rc) < RectBottom(rc) && + RectTop(rc) < WindowHeight(wnd)+1) + --rc.tp; + } + RectRight(rc) = max(RectLeft(rc), + min(RectRight(rc),WindowWidth(wnd))); + RectBottom(rc) = max(RectTop(rc), + min(RectBottom(rc),WindowHeight(wnd))); + return rc; +} + +/* -------- display a window's title --------- */ +void DisplayTitle(DFWINDOW wnd, DFRECT *rcc) +{ + if (GetTitle(wnd) != NULL) + { + int tlen = min((int)strlen(GetTitle(wnd)), (int)WindowWidth(wnd)-2); + int tend = WindowWidth(wnd)-3-BorderAdj(wnd); + DFRECT rc; + + if (rcc == NULL) + rc = RelativeWindowRect(wnd, WindowRect(wnd)); + else + rc = *rcc; + rc = AdjustRectangle(wnd, rc); + + if (DfSendMessage(wnd, TITLE, (PARAM) rcc, 0)) + { + if (wnd == inFocus) + { + foreground = cfg.clr[TITLEBAR] [HILITE_COLOR] [FG]; + background = cfg.clr[TITLEBAR] [HILITE_COLOR] [BG]; + } + else + { + foreground = cfg.clr[TITLEBAR] [STD_COLOR] [FG]; + background = cfg.clr[TITLEBAR] [STD_COLOR] [BG]; + } + memset(line,' ',WindowWidth(wnd)); +#ifdef INCLUDE_MINIMIZE + if (wnd->condition != ISMINIMIZED) +#endif + strncpy (line + ((WindowWidth(wnd)-2 - tlen) / 2), + wnd->title, tlen); + if (TestAttribute(wnd, CONTROLBOX)) + line[2-BorderAdj(wnd)] = CONTROLBOXCHAR; + if (TestAttribute(wnd, MINMAXBOX)) + { + switch (wnd->condition) + { + case ISRESTORED: +#ifdef INCLUDE_MAXIMIZE + line[tend+1] = MAXPOINTER; +#endif +#ifdef INCLUDE_MINIMIZE + line[tend] = MINPOINTER; +#endif + break; +#ifdef INCLUDE_MINIMIZE + case ISMINIMIZED: + line[tend+1] = MAXPOINTER; + break; +#endif +#ifdef INCLUDE_MAXIMIZE + case ISMAXIMIZED: +#ifdef INCLUDE_MINIMIZE + line[tend] = MINPOINTER; +#endif +#ifdef INCLUDE_RESTORE + line[tend+1] = RESTOREPOINTER; +#endif + break; +#endif + default: + break; + } + } + line[RectRight(rc)+1] = line[tend+3] = '\0'; + if (wnd != inFocus) + ClipString++; + writeline(wnd, line+RectLeft(rc), + RectLeft(rc)+BorderAdj(wnd), + 0, + FALSE); + ClipString = 0; + } + } +} + +/* --- display right border shadow character of a window --- */ +static void shadow_char(DFWINDOW wnd, int y) +{ + int fg = foreground; + int bg = background; + int x = WindowWidth(wnd); + char c = videochar(GetLeft(wnd)+x, GetTop(wnd)+y); + + if (TestAttribute(wnd, SHADOW) == 0) + return; + foreground = DARKGRAY; + background = BLACK; + wputch(wnd, c, x, y); + foreground = fg; + background = bg; +} + +/* --- display the bottom border shadow line for a window -- */ +static void shadowline(DFWINDOW wnd, DFRECT rc) +{ + int i; + int y = GetBottom(wnd)+1; + int fg = foreground; + int bg = background; + + if ((TestAttribute(wnd, SHADOW)) == 0) + return; + for (i = 0; i < WindowWidth(wnd)+1; i++) + line[i] = videochar(GetLeft(wnd)+i, y); + line[i] = '\0'; + foreground = DARKGRAY; + background = BLACK; + line[RectRight(rc)+1] = '\0'; + if (RectLeft(rc) == 0) + rc.lf++; + ClipString++; + wputs(wnd, line+RectLeft(rc), RectLeft(rc), + WindowHeight(wnd)); + --ClipString; + foreground = fg; + background = bg; +} + +static DFRECT ParamRect(DFWINDOW wnd, DFRECT *rcc) +{ + DFRECT rc; + if (rcc == NULL) { + rc = RelativeWindowRect(wnd, WindowRect(wnd)); + if (TestAttribute(wnd, SHADOW)) { + rc.rt++; + rc.bt++; + } + } + else + rc = *rcc; + return rc; +} + +void PaintShadow(DFWINDOW wnd) +{ + int y; + DFRECT rc = ParamRect(wnd, NULL); + for (y = 1; y < WindowHeight(wnd); y++) + shadow_char(wnd, y); + shadowline(wnd, rc); +} + +/* ------- display a window's border ----- */ +void RepaintBorder(DFWINDOW wnd, DFRECT *rcc) +{ + int y; + char lin, side, ne, nw, se, sw; + DFRECT rc, clrc; + + if (!TestAttribute(wnd, HASBORDER)) + return; + rc = ParamRect(wnd, rcc); + clrc = AdjustRectangle(wnd, rc); + + if (wnd == inFocus) { + lin = FOCUS_LINE; + side = FOCUS_SIDE; + ne = FOCUS_NE; + nw = FOCUS_NW; + se = FOCUS_SE; + sw = FOCUS_SW; + } + else { + lin = LINE; + side = SIDE; + ne = NE; + nw = NW; + se = SE; + sw = SW; + } + line[WindowWidth(wnd)] = '\0'; + /* ---------- window title ------------ */ + if (TestAttribute(wnd, HASTITLEBAR)) + if (RectTop(rc) == 0) + if (RectLeft(rc) < WindowWidth(wnd)-BorderAdj(wnd)) + DisplayTitle(wnd, &rc); + foreground = FrameForeground(wnd); + background = FrameBackground(wnd); + /* -------- top frame corners --------- */ + if (RectTop(rc) == 0) { + if (RectLeft(rc) == 0) + wputch(wnd, nw, 0, 0); + if (RectLeft(rc) < WindowWidth(wnd)) { + if (RectRight(rc) >= WindowWidth(wnd)-1) + wputch(wnd, ne, WindowWidth(wnd)-1, 0); + TopLine(wnd, lin, clrc); + } + } + + /* ----------- window body ------------ */ + for (y = RectTop(rc); y <= RectBottom(rc); y++) { + char ch; + if (y == 0 || y >= WindowHeight(wnd)-1) + continue; + if (RectLeft(rc) == 0) + wputch(wnd, side, 0, y); + if (RectLeft(rc) < WindowWidth(wnd) && + RectRight(rc) >= WindowWidth(wnd)-1) { + if (TestAttribute(wnd, VSCROLLBAR)) + ch = ( y == 1 ? UPSCROLLBOX : + y == WindowHeight(wnd)-2 ? + DOWNSCROLLBOX : + y-1 == wnd->VScrollBox ? + SCROLLBOXCHAR : + SCROLLBARCHAR ); + else + ch = side; + wputch(wnd, ch, WindowWidth(wnd)-1, y); + } + if (RectRight(rc) == WindowWidth(wnd)) + shadow_char(wnd, y); + } + + if (RectTop(rc) <= WindowHeight(wnd)-1 && + RectBottom(rc) >= WindowHeight(wnd)-1) { + /* -------- bottom frame corners ---------- */ + if (RectLeft(rc) == 0) + wputch(wnd, sw, 0, WindowHeight(wnd)-1); + if (RectLeft(rc) < WindowWidth(wnd) && + RectRight(rc) >= WindowWidth(wnd)-1) + wputch(wnd, se, WindowWidth(wnd)-1, + WindowHeight(wnd)-1); + + + if (wnd->StatusBar == NULL) { + /* ----------- bottom line ------------- */ + memset(line,lin,WindowWidth(wnd)-1); + if (TestAttribute(wnd, HSCROLLBAR)) { + line[0] = LEFTSCROLLBOX; + line[WindowWidth(wnd)-3] = RIGHTSCROLLBOX; + memset(line+1, SCROLLBARCHAR, WindowWidth(wnd)-4); + line[wnd->HScrollBox] = SCROLLBOXCHAR; + } + line[WindowWidth(wnd)-2] = line[RectRight(rc)] = '\0'; + if (RectLeft(rc) != RectRight(rc) || + (RectLeft(rc) && RectLeft(rc) < WindowWidth(wnd)-1)) + { + if (wnd != inFocus) + ClipString++; + writeline(wnd, + line+(RectLeft(clrc)), + RectLeft(clrc)+1, + WindowHeight(wnd)-1, + FALSE); + ClipString = 0; + } + } + if (RectRight(rc) == WindowWidth(wnd)) + shadow_char(wnd, WindowHeight(wnd)-1); + } + if (RectBottom(rc) == WindowHeight(wnd)) + /* ---------- bottom shadow ------------- */ + shadowline(wnd, rc); +} + +static void TopLine(DFWINDOW wnd, int lin, DFRECT rc) +{ + if (TestAttribute(wnd, HASMENUBAR)) + return; + if (TestAttribute(wnd, HASTITLEBAR) && GetTitle(wnd)) + return; + if (RectLeft(rc) == 0) { + RectLeft(rc) += BorderAdj(wnd); + RectRight(rc) += BorderAdj(wnd); + } + if (RectRight(rc) < WindowWidth(wnd)-1) + RectRight(rc)++; + + if (RectLeft(rc) < RectRight(rc)) { + /* ----------- top line ------------- */ + memset(line,lin,WindowWidth(wnd)-1); + if (TestAttribute(wnd, CONTROLBOX)) { + strncpy(line+1, " ", 3); + *(line+2) = CONTROLBOXCHAR; + } + line[RectRight(rc)] = '\0'; + writeline(wnd, line+RectLeft(rc), + RectLeft(rc), 0, FALSE); + } +} + +/* ------ clear the data space of a window -------- */ +void ClearWindow(DFWINDOW wnd, DFRECT *rcc, int clrchar) +{ + if (isVisible(wnd)) { + int y; + DFRECT rc; + + if (rcc == NULL) + rc = RelativeWindowRect(wnd, WindowRect(wnd)); + else + rc = *rcc; + + if (RectLeft(rc) == 0) + RectLeft(rc) = BorderAdj(wnd); + if (RectRight(rc) > WindowWidth(wnd)-1) + RectRight(rc) = WindowWidth(wnd)-1; + SetStandardColor(wnd); + memset(line, clrchar, sizeof line); + line[RectRight(rc)+1] = '\0'; + for (y = RectTop(rc); y <= RectBottom(rc); y++) + { + if (y < TopBorderAdj(wnd) || + y > ClientHeight(wnd)+ + (TestAttribute(wnd, HASMENUBAR) ? 1 : 0)) + continue; + writeline(wnd, + line+(RectLeft(rc)), + RectLeft(rc), + y, + FALSE); + } + } +} + +/* ------ compute the logical line length of a window ------ */ +int LineLength(char *ln) +{ + int len = strlen(ln); + char *cp = ln; + while ((cp = strchr(cp, CHANGECOLOR)) != NULL) + { + cp++; + len -= 3; + } + cp = ln; + while ((cp = strchr(cp, RESETCOLOR)) != NULL) + { + cp++; + --len; + } + return len; +} + +void InitWindowColors(DFWINDOW wnd) +{ + int fbg,col; + int cls = GetClass(wnd); + /* window classes without assigned colors inherit parent's colors */ + if (cfg.clr[cls][0][0] == 0xff && GetParent(wnd) != NULL) + cls = GetClass(GetParent(wnd)); + /* ---------- set the colors ---------- */ + for (fbg = 0; fbg < 2; fbg++) + for (col = 0; col < 4; col++) + wnd->WindowColors[col][fbg] = cfg.clr[cls][col][fbg]; +} + +void PutWindowChar(DFWINDOW wnd, char c, int x, int y) +{ + if (x < ClientWidth(wnd) && y < ClientHeight(wnd)) + wputch(wnd, c, x+BorderAdj(wnd), y+TopBorderAdj(wnd)); +} + +void PutWindowLine(DFWINDOW wnd, void *s, int x, int y) +{ + int saved = FALSE, sv; + if (x < ClientWidth(wnd) && y < ClientHeight(wnd)) + { + char *en = (char *)s+ClientWidth(wnd)-x; + if ((int)(strlen(s)+x) > (int)ClientWidth(wnd)) + { + sv = *en; + *en = '\0'; + saved = TRUE; + } + ClipString++; + wputs(wnd, s, x+BorderAdj(wnd), y+TopBorderAdj(wnd)); + --ClipString; + if (saved) + *en = sv; + } +} + +/* EOF */