├── applicat.c ├── barchart.c ├── bin ├── memopad.exe ├── memopad.hlp ├── memopad.map └── readme.txt ├── box.c ├── button.c ├── calendar.c ├── changes.txt ├── checkbox.c ├── classdef.h ├── classes.h ├── clipbord.c ├── combobox.c ├── commands.h ├── compilin.txt ├── config.c ├── config.h ├── console.c ├── decomp.c ├── dfalloc.c ├── dflat.bld ├── dflat.doc ├── dflat.h ├── dflat.lbc ├── dflatmsg.h ├── dialbox.c ├── dialbox.h ├── dialogs.c ├── direct.c ├── editbox.c ├── editor.c ├── fileopen.c ├── fixhelp.c ├── helpbox.c ├── helpbox.h ├── htree.c ├── htree.h ├── huffc.c ├── keys.c ├── keys.h ├── license.txt ├── listbox.c ├── lists.c ├── log.c ├── makefile.bcc ├── makefile.tcc ├── makefile.wat ├── memopad.c ├── memopad.lnk ├── memopad.txt ├── menu.c ├── menu.h ├── menubar.c ├── menus.c ├── message.c ├── mfixhelp.txt ├── mhuffc.txt ├── mldflat.txt ├── mmemopad.txt ├── mouse.c ├── msgbox.c ├── normal.c ├── pictbox.c ├── popdown.c ├── radio.c ├── readme.doc ├── rect.c ├── rect.h ├── scdos.c ├── scdos.h ├── scrnshot └── memopad.png ├── search.c ├── slidebox.c ├── spinbutt.c ├── statbar.c ├── sysmenu.c ├── system.h ├── text.c ├── textbox.c ├── video.c ├── video.h ├── watch.c └── window.c /barchart.c: -------------------------------------------------------------------------------- 1 | /* ------------ barchart.c ----------- */ 2 | #include "dflat.h" 3 | 4 | #define BCHEIGHT 12 5 | #define BCWIDTH 44 6 | #define COLWIDTH 4 7 | 8 | static WINDOW Bwnd; 9 | 10 | /* ------- project schedule array ------- */ 11 | static struct ProjChart { 12 | char *prj; 13 | int start, stop; 14 | } projs[] = { 15 | {"Center St", 0,3}, 16 | {"City Hall", 0,5}, 17 | {"Rt 395 ", 1,4}, 18 | {"Sky Condo", 2,3}, 19 | {"Out Hs ", 0,4}, 20 | {"Bk Palace", 1,5} 21 | }; 22 | 23 | static char *Title = " PROJECT SCHEDULE"; 24 | static char *Months = " Jan Feb Mar Apr May Jun"; 25 | 26 | static int BarChartProc(WINDOW wnd, MESSAGE msg, 27 | PARAM p1, PARAM p2) 28 | { 29 | switch (msg) { 30 | case COMMAND: 31 | if ((int)p1 == ID_HELP) { 32 | DisplayHelp(wnd, "BarChart"); 33 | return TRUE; 34 | } 35 | break; 36 | case CLOSE_WINDOW: 37 | Bwnd = NULL; 38 | break; 39 | default: 40 | break; 41 | } 42 | return DefaultWndProc(wnd, msg, p1, p2); 43 | } 44 | 45 | void BarChart(WINDOW pwnd) 46 | { 47 | int pct = sizeof projs / sizeof(struct ProjChart); 48 | int i; 49 | 50 | if (Bwnd == NULL) { 51 | Bwnd = CreateWindow(PICTUREBOX, 52 | "BarChart", 53 | -1, -1, BCHEIGHT, BCWIDTH, 54 | NULL, pwnd, BarChartProc, 55 | SHADOW | 56 | CONTROLBOX | 57 | MOVEABLE | 58 | HASBORDER 59 | ); 60 | SendMessage(Bwnd, ADDTEXT, (PARAM) Title, 0); 61 | SendMessage(Bwnd, ADDTEXT, (PARAM) "", 0); 62 | for (i = 0; i < pct; i++) { 63 | SendMessage(Bwnd,ADDTEXT,(PARAM)projs[i].prj,0); 64 | DrawBar(Bwnd, SOLIDBAR+(i%4), 65 | 11+projs[i].start*COLWIDTH, 2+i, 66 | (1 + projs[i].stop-projs[i].start) * COLWIDTH, 67 | TRUE); 68 | } 69 | SendMessage(Bwnd, ADDTEXT, (PARAM) "", 0); 70 | SendMessage(Bwnd, ADDTEXT, (PARAM) Months, 0); 71 | DrawBox(Bwnd, 10, 1, pct+2, 25); 72 | } 73 | SendMessage(Bwnd, SETFOCUS, TRUE, 0); 74 | } 75 | -------------------------------------------------------------------------------- /bin/memopad.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/bin/memopad.exe -------------------------------------------------------------------------------- /bin/memopad.hlp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/bin/memopad.hlp -------------------------------------------------------------------------------- /bin/readme.txt: -------------------------------------------------------------------------------- 1 | Precompiled memopad.exe and memopad.hlp. 2 | -------------------------------------------------------------------------------- /box.c: -------------------------------------------------------------------------------- 1 | /* ----------- box.c ------------ */ 2 | 3 | #include "dflat.h" 4 | 5 | int BoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 6 | { 7 | int rtn; 8 | CTLWINDOW *ct = GetControl(wnd); 9 | if (ct != NULL) { 10 | switch (msg) { 11 | case SETFOCUS: 12 | case PAINT: 13 | return FALSE; 14 | case LEFT_BUTTON: 15 | case BUTTON_RELEASED: 16 | return SendMessage(GetParent(wnd), msg, p1, p2); 17 | case BORDER: 18 | rtn = BaseWndProc(BOX, wnd, msg, p1, p2); 19 | if (ct != NULL && ct->itext != NULL) 20 | writeline(wnd, ct->itext, 1, 0, FALSE); 21 | return rtn; 22 | default: 23 | break; 24 | } 25 | } 26 | return BaseWndProc(BOX, wnd, msg, p1, p2); 27 | } 28 | -------------------------------------------------------------------------------- /button.c: -------------------------------------------------------------------------------- 1 | /* -------------- button.c -------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | void PaintMsg(WINDOW wnd, CTLWINDOW *ct, RECT *rc) 6 | { 7 | if (isVisible(wnd)) { 8 | if (TestAttribute(wnd, SHADOW) && cfg.mono == 0) { 9 | /* -------- draw the button's shadow ------- */ 10 | int x; 11 | background = WndBackground(GetParent(wnd)); 12 | foreground = BLACK; 13 | for (x = 1; x <= WindowWidth(wnd); x++) 14 | wputch(wnd, 223, x, 1); 15 | wputch(wnd, 220, WindowWidth(wnd), 0); 16 | } 17 | if (ct->itext != NULL) { 18 | unsigned char *txt; 19 | txt = DFcalloc(1, strlen(ct->itext)+10); 20 | if (ct->setting == OFF) { 21 | txt[0] = CHANGECOLOR; 22 | txt[1] = wnd->WindowColors 23 | [HILITE_COLOR] [FG] | 0x80; 24 | txt[2] = wnd->WindowColors 25 | [STD_COLOR] [BG] | 0x80; 26 | } 27 | CopyCommand(txt+strlen(txt),ct->itext,!ct->setting, 28 | WndBackground(wnd)); 29 | SendMessage(wnd, CLEARTEXT, 0, 0); 30 | SendMessage(wnd, ADDTEXT, (PARAM) txt, 0); 31 | free(txt); 32 | } 33 | /* --------- write the button's text ------- */ 34 | WriteTextLine(wnd, rc, 0, wnd == inFocus); 35 | } 36 | } 37 | 38 | void LeftButtonMsg(WINDOW wnd, MESSAGE msg, CTLWINDOW *ct) 39 | { 40 | if (cfg.mono == 0) { 41 | /* --------- draw a pushed button -------- */ 42 | int x; 43 | background = WndBackground(GetParent(wnd)); 44 | foreground = WndBackground(wnd); 45 | wputch(wnd, ' ', 0, 0); 46 | for (x = 0; x < WindowWidth(wnd); x++) { 47 | wputch(wnd, 220, x+1, 0); 48 | wputch(wnd, 223, x+1, 1); 49 | } 50 | } 51 | if (msg == LEFT_BUTTON) 52 | SendMessage(NULL, WAITMOUSE, 0, 0); 53 | else 54 | SendMessage(NULL, WAITKEYBOARD, 0, 0); 55 | SendMessage(wnd, PAINT, 0, 0); 56 | if (ct->setting == ON) 57 | PostMessage(GetParent(wnd), COMMAND, ct->command, 0); 58 | else 59 | beep(); 60 | } 61 | 62 | int ButtonProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 63 | { 64 | CTLWINDOW *ct = GetControl(wnd); 65 | if (ct != NULL) { 66 | switch (msg) { 67 | case SETFOCUS: 68 | BaseWndProc(BUTTON, wnd, msg, p1, p2); 69 | p1 = 0; 70 | /* ------- fall through ------- */ 71 | case PAINT: 72 | PaintMsg(wnd, ct, (RECT*)p1); 73 | return TRUE; 74 | case KEYBOARD: 75 | if (p1 != '\r') 76 | break; 77 | /* ---- fall through ---- */ 78 | case LEFT_BUTTON: 79 | LeftButtonMsg(wnd, msg, ct); 80 | return TRUE; 81 | case HORIZSCROLL: 82 | return TRUE; 83 | default: 84 | break; 85 | } 86 | } 87 | return BaseWndProc(BUTTON, wnd, msg, p1, p2); 88 | } 89 | -------------------------------------------------------------------------------- /calendar.c: -------------------------------------------------------------------------------- 1 | /* ------------- calendar.c ------------- */ 2 | #include "dflat.h" 3 | 4 | #ifndef TURBOC 5 | 6 | #define CALHEIGHT 17 7 | #define CALWIDTH 33 8 | 9 | static int DyMo[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 10 | static struct tm ttm; 11 | static int dys[42]; 12 | static WINDOW Cwnd; 13 | 14 | static void FixDate(void) 15 | { 16 | /* ---- adjust Feb for leap year ---- */ 17 | DyMo[1] = (ttm.tm_year % 4) ? 28 : 29; 18 | ttm.tm_mday = min(ttm.tm_mday, DyMo[ttm.tm_mon]); 19 | } 20 | 21 | /* ---- build calendar dates array ---- */ 22 | static void BuildDateArray(void) 23 | { 24 | int offset, dy = 0; 25 | memset(dys, 0, sizeof dys); 26 | FixDate(); 27 | /* ----- compute the weekday for the 1st ----- */ 28 | offset = ((ttm.tm_mday-1) - ttm.tm_wday) % 7; 29 | if (offset < 0) 30 | offset += 7; 31 | if (offset) 32 | offset = (offset - 7) * -1; 33 | /* ----- build the dates into the array ---- */ 34 | for (dy = 1; dy <= DyMo[ttm.tm_mon]; dy++) 35 | dys[offset++] = dy; 36 | } 37 | 38 | static void CreateWindowMsg(WINDOW wnd) 39 | { 40 | int x, y; 41 | DrawBox(wnd, 1, 2, CALHEIGHT-4, CALWIDTH-4); 42 | for (x = 5; x < CALWIDTH-4; x += 4) 43 | DrawVector(wnd, x, 2, CALHEIGHT-4, FALSE); 44 | for (y = 4; y < CALHEIGHT-3; y+=2) 45 | DrawVector(wnd, 1, y, CALWIDTH-4, TRUE); 46 | } 47 | 48 | static void DisplayDates(WINDOW wnd) 49 | { 50 | int week, day; 51 | char dyln[10]; 52 | int offset; 53 | char banner[CALWIDTH-1]; 54 | char banner1[30]; 55 | 56 | SetStandardColor(wnd); 57 | PutWindowLine(wnd, "Sun Mon Tue Wed Thu Fri Sat", 2, 1); 58 | memset(banner, ' ', CALWIDTH-2); 59 | strftime(banner1, 16, "%B, %Y", &ttm); 60 | offset = (CALWIDTH-2 - strlen(banner1)) / 2; 61 | strcpy(banner+offset, banner1); 62 | strcat(banner, " "); 63 | PutWindowLine(wnd, banner, 0, 0); 64 | BuildDateArray(); 65 | for (week = 0; week < 6; week++) { 66 | for (day = 0; day < 7; day++) { 67 | int dy = dys[week*7+day]; 68 | if (dy == 0) 69 | strcpy(dyln, " "); 70 | else { 71 | if (dy == ttm.tm_mday) 72 | sprintf(dyln, "%c%c%c%2d %c", 73 | CHANGECOLOR, 74 | SelectForeground(wnd)+0x80, 75 | SelectBackground(wnd)+0x80, 76 | dy, RESETCOLOR); 77 | else 78 | sprintf(dyln, "%2d ", dy); 79 | } 80 | SetStandardColor(wnd); 81 | PutWindowLine(wnd, dyln, 2 + day * 4, 3 + week*2); 82 | } 83 | } 84 | } 85 | 86 | static int KeyboardMsg(WINDOW wnd, PARAM p1) 87 | { 88 | switch ((int)p1) { 89 | case PGUP: 90 | if (ttm.tm_mon == 0) { 91 | ttm.tm_mon = 12; 92 | ttm.tm_year--; 93 | } 94 | ttm.tm_mon--; 95 | FixDate(); 96 | mktime(&ttm); 97 | DisplayDates(wnd); 98 | return TRUE; 99 | case PGDN: 100 | ttm.tm_mon++; 101 | if (ttm.tm_mon == 12) { 102 | ttm.tm_mon = 0; 103 | ttm.tm_year++; 104 | } 105 | FixDate(); 106 | mktime(&ttm); 107 | DisplayDates(wnd); 108 | return TRUE; 109 | default: 110 | break; 111 | } 112 | return FALSE; 113 | } 114 | 115 | static int CalendarProc(WINDOW wnd,MESSAGE msg, 116 | PARAM p1,PARAM p2) 117 | { 118 | switch (msg) { 119 | case CREATE_WINDOW: 120 | DefaultWndProc(wnd, msg, p1, p2); 121 | CreateWindowMsg(wnd); 122 | return TRUE; 123 | case KEYBOARD: 124 | if (KeyboardMsg(wnd, p1)) 125 | return TRUE; 126 | break; 127 | case PAINT: 128 | DefaultWndProc(wnd, msg, p1, p2); 129 | DisplayDates(wnd); 130 | return TRUE; 131 | case COMMAND: 132 | if ((int)p1 == ID_HELP) { 133 | DisplayHelp(wnd, "Calendar"); 134 | return TRUE; 135 | } 136 | break; 137 | case CLOSE_WINDOW: 138 | Cwnd = NULL; 139 | break; 140 | default: 141 | break; 142 | } 143 | return DefaultWndProc(wnd, msg, p1, p2); 144 | } 145 | 146 | void Calendar(WINDOW pwnd) 147 | { 148 | if (Cwnd == NULL) { 149 | time_t tim = time(NULL); 150 | ttm = *localtime(&tim); 151 | Cwnd = CreateWindow(PICTUREBOX, 152 | "Calendar", 153 | -1, -1, CALHEIGHT, CALWIDTH, 154 | NULL, pwnd, CalendarProc, 155 | SHADOW | 156 | MINMAXBOX | 157 | CONTROLBOX | 158 | MOVEABLE | 159 | HASBORDER 160 | ); 161 | } 162 | SendMessage(Cwnd, SETFOCUS, TRUE, 0); 163 | } 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /changes.txt: -------------------------------------------------------------------------------- 1 | Changes made to D-Flat version 20 2 | while adapting it for compilation with Smaller C. 3 | 4 | - Changed calls to unlink() to calls to remove(). Just to make 5 | the code a bit more generic. No functional change. 6 | - Made flags, counters, etc modified by ISRs explicitly volatile 7 | simply to show the intent. No functional change. If anything, 8 | the code is a bit more correct with these volatiles. 9 | - Changed the backslash to the forward slash in include 10 | directives, e.g. 11 | #include -> #include 12 | #include -> #include 13 | This works with Borland/Turbo C/C++ in DOS just fine. Ditto 14 | with Smaller C in DOS and Windows. 15 | - Inserted a space in a macro definition: 16 | #define ALT_7 (0xfe+OFFSET) -> 17 | #define ALT_7 (0xfe +OFFSET) 18 | Many old compilers incorrectly (according to the C standard) 19 | parse 0xfe+OFFSET as three tokens, whereas it should be parsed 20 | as one token ("preprocessing number" token) and compilation 21 | should fail because it doesn't represent a valid numeric 22 | constant. This change is required for compilation with 23 | Smaller C, which employs a better preprocessor (ucpp). 24 | - Changed a call to stat() to calls to fopen() and fclose(). 25 | stat() was originally used to see if a file exists. This makes 26 | the code a bit more generic and lets us get away without 27 | stat() in Smaller C's standard C library. Minimal functional 28 | change. 29 | - Changed the location of the interrupt keyword in declarations. 30 | This is required for compilation with Smaller C, which is not 31 | as flexible as Borland/Turbo C/C++ w.r.t. the keyword 32 | placement. 33 | - Changed calls to segread() and int86x() to calls to just 34 | int86(). Segments aren't involved so there should be no 35 | functional change but this allows for a simpler int86() than 36 | int86x(). 37 | - Changed several instances of int to short primarily in the 38 | code that copies characters to and from the screen. This is 39 | required for compilation with Smaller C, which defines int as 40 | 32-bit in the huge and unreal mode(l)s. No functional change. 41 | - Changed one C++ style comment (// comment) to ANSI C style 42 | (/* comment */) since all other comments in D-Flat are ANSI C 43 | style. 44 | - Checked the value returned by strchr() in KeyboardMsg(). Just 45 | in case. Was found in code review, not because of some 46 | observed malfunction. No functional change. 47 | - Checked the nm parameter for NULL in FindHelp() in fixhelp.c. 48 | This avoids a NULL pointer dereference (and a crash) in the 49 | fixhelp tool compiled for Windows and Linux. 50 | -------------------------------------------------------------------------------- /checkbox.c: -------------------------------------------------------------------------------- 1 | /* -------------- checkbox.c ------------ */ 2 | 3 | #include "dflat.h" 4 | 5 | int CheckBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 6 | { 7 | int rtn; 8 | CTLWINDOW *ct = GetControl(wnd); 9 | if (ct != NULL) { 10 | switch (msg) { 11 | case SETFOCUS: 12 | if (!(int)p1) 13 | SendMessage(NULL, HIDE_CURSOR, 0, 0); 14 | case MOVE: 15 | rtn = BaseWndProc(CHECKBOX, wnd, msg, p1, p2); 16 | SetFocusCursor(wnd); 17 | return rtn; 18 | case PAINT: { 19 | char cb[] = "[ ]"; 20 | if (ct->setting) 21 | cb[1] = 'X'; 22 | SendMessage(wnd, CLEARTEXT, 0, 0); 23 | SendMessage(wnd, ADDTEXT, (PARAM) cb, 0); 24 | SetFocusCursor(wnd); 25 | break; 26 | } 27 | case KEYBOARD: 28 | if ((int)p1 != ' ') 29 | break; 30 | case LEFT_BUTTON: 31 | ct->setting ^= ON; 32 | SendMessage(wnd, PAINT, 0, 0); 33 | return TRUE; 34 | default: 35 | break; 36 | } 37 | } 38 | return BaseWndProc(CHECKBOX, wnd, msg, p1, p2); 39 | } 40 | 41 | BOOL CheckBoxSetting(DBOX *db, enum commands cmd) 42 | { 43 | CTLWINDOW *ct = FindCommand(db, cmd, CHECKBOX); 44 | return ct ? (ct->wnd ? (ct->setting==ON) : (ct->isetting==ON)) : FALSE; 45 | } 46 | -------------------------------------------------------------------------------- /classdef.h: -------------------------------------------------------------------------------- 1 | /* ---------------- classdef.h --------------- */ 2 | 3 | #ifndef CLASSDEF_H 4 | #define CLASSDEF_H 5 | 6 | typedef struct classdefs { 7 | CLASS base; /* base window class */ 8 | int (*wndproc)(struct window *,enum messages,PARAM,PARAM); 9 | int attrib; 10 | } CLASSDEFS; 11 | 12 | extern CLASSDEFS classdefs[]; 13 | 14 | #define SHADOW 0x0001 15 | #define MOVEABLE 0x0002 16 | #define SIZEABLE 0x0004 17 | #define HASMENUBAR 0x0008 18 | #define VSCROLLBAR 0x0010 19 | #define HSCROLLBAR 0x0020 20 | #define VISIBLE 0x0040 21 | #define SAVESELF 0x0080 22 | #define HASTITLEBAR 0x0100 23 | #define CONTROLBOX 0x0200 24 | #define MINMAXBOX 0x0400 25 | #define NOCLIP 0x0800 26 | #define READONLY 0x1000 27 | #define MULTILINE 0x2000 28 | #define HASBORDER 0x4000 29 | #define HASSTATUSBAR 0x8000 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /classes.h: -------------------------------------------------------------------------------- 1 | /* ----------- classes.h ------------ */ 2 | /* 3 | * Class definition source file 4 | * Make class changes to this source file 5 | * Other source files will adapt 6 | * 7 | * You must add entries to the color tables in 8 | * CONFIG.C for new classes. 9 | * 10 | * Class Name Base Class Processor Attribute 11 | * ------------ --------- --------------- ----------- 12 | */ 13 | ClassDef( NORMAL, -1, NormalProc, 0 ) 14 | ClassDef( APPLICATION, NORMAL, ApplicationProc, VISIBLE | 15 | SAVESELF | 16 | CONTROLBOX ) 17 | ClassDef( TEXTBOX, NORMAL, TextBoxProc, 0 ) 18 | ClassDef( LISTBOX, TEXTBOX, ListBoxProc, 0 ) 19 | ClassDef( EDITBOX, TEXTBOX, EditBoxProc, 0 ) 20 | ClassDef( MENUBAR, NORMAL, MenuBarProc, NOCLIP ) 21 | ClassDef( POPDOWNMENU, LISTBOX, PopDownProc, SAVESELF | 22 | NOCLIP | 23 | HASBORDER ) 24 | #ifdef INCLUDE_PICTUREBOX 25 | ClassDef( PICTUREBOX, TEXTBOX, PictureProc, 0 ) 26 | #endif 27 | ClassDef( DIALOG, NORMAL, DialogProc, SHADOW | 28 | MOVEABLE | 29 | CONTROLBOX| 30 | HASBORDER | 31 | NOCLIP ) 32 | ClassDef( BOX, NORMAL, BoxProc, HASBORDER ) 33 | ClassDef( BUTTON, TEXTBOX, ButtonProc, SHADOW ) 34 | ClassDef( COMBOBOX, EDITBOX, ComboProc, 0 ) 35 | ClassDef( TEXT, TEXTBOX, TextProc, 0 ) 36 | ClassDef( RADIOBUTTON, TEXTBOX, RadioButtonProc, 0 ) 37 | ClassDef( CHECKBOX, TEXTBOX, CheckBoxProc, 0 ) 38 | ClassDef( SPINBUTTON, LISTBOX, SpinButtonProc, 0 ) 39 | ClassDef( ERRORBOX, DIALOG, NULL, SHADOW | 40 | HASBORDER ) 41 | ClassDef( MESSAGEBOX, DIALOG, NULL, SHADOW | 42 | HASBORDER ) 43 | ClassDef( HELPBOX, DIALOG, HelpBoxProc, MOVEABLE | 44 | SAVESELF | 45 | HASBORDER | 46 | NOCLIP | 47 | CONTROLBOX ) 48 | ClassDef( STATUSBAR, TEXTBOX, StatusBarProc, NOCLIP ) 49 | 50 | ClassDef( EDITOR, EDITBOX, EditorProc, 0 ) 51 | 52 | /* 53 | * ========> Add new classes here <======== 54 | */ 55 | 56 | /* ---------- pseudo classes to create enums, etc. ---------- */ 57 | ClassDef( TITLEBAR, -1, NULL, 0 ) 58 | ClassDef( DUMMY, -1, NULL, HASBORDER ) 59 | -------------------------------------------------------------------------------- /clipbord.c: -------------------------------------------------------------------------------- 1 | /* ----------- clipbord.c ------------ */ 2 | #include "dflat.h" 3 | 4 | char *Clipboard; 5 | unsigned ClipboardLength; 6 | 7 | void CopyTextToClipboard(char *text) 8 | { 9 | ClipboardLength = strlen(text); 10 | Clipboard = DFrealloc(Clipboard, ClipboardLength); 11 | memmove(Clipboard, text, ClipboardLength); 12 | } 13 | 14 | void CopyToClipboard(WINDOW wnd) 15 | { 16 | if (TextBlockMarked(wnd)) { 17 | char *bbl=TextLine(wnd,wnd->BlkBegLine)+wnd->BlkBegCol; 18 | char *bel=TextLine(wnd,wnd->BlkEndLine)+wnd->BlkEndCol; 19 | ClipboardLength = (int) (bel - bbl); 20 | Clipboard = DFrealloc(Clipboard, ClipboardLength); 21 | memmove(Clipboard, bbl, ClipboardLength); 22 | } 23 | } 24 | 25 | void ClearClipboard(void) 26 | { 27 | if (Clipboard != NULL) { 28 | free(Clipboard); 29 | Clipboard = NULL; 30 | } 31 | } 32 | 33 | 34 | BOOL PasteText(WINDOW wnd, char *SaveTo, unsigned len) 35 | { 36 | if (SaveTo != NULL && len > 0) { 37 | unsigned plen = strlen(wnd->text) + len; 38 | 39 | if (plen <= wnd->MaxTextLength) { 40 | if (plen+1 > wnd->textlen) { 41 | wnd->text = DFrealloc(wnd->text, plen+3); 42 | wnd->textlen = plen+1; 43 | } 44 | memmove(CurrChar+len, CurrChar, strlen(CurrChar)+1); 45 | memmove(CurrChar, SaveTo, len); 46 | BuildTextPointers(wnd); 47 | wnd->TextChanged = TRUE; 48 | return TRUE; 49 | } 50 | } 51 | return FALSE; 52 | } 53 | -------------------------------------------------------------------------------- /combobox.c: -------------------------------------------------------------------------------- 1 | /* -------------- combobox.c -------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | int ListProc(WINDOW, MESSAGE, PARAM, PARAM); 6 | 7 | int ComboProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 8 | { 9 | switch (msg) { 10 | case CREATE_WINDOW: 11 | wnd->extension = CreateWindow( 12 | LISTBOX, 13 | NULL, 14 | wnd->rc.lf,wnd->rc.tp+1, 15 | wnd->ht-1, wnd->wd+1, 16 | NULL, 17 | wnd, 18 | ListProc, 19 | HASBORDER | NOCLIP | SAVESELF); 20 | ((WINDOW)(wnd->extension))->ct->command = 21 | wnd->ct->command; 22 | wnd->ht = 1; 23 | wnd->rc.bt = wnd->rc.tp; 24 | break; 25 | case PAINT: 26 | foreground = WndBackground(wnd); 27 | background = WndForeground(wnd); 28 | wputch(wnd, DOWNSCROLLBOX, WindowWidth(wnd), 0); 29 | break; 30 | case KEYBOARD: 31 | if ((int)p1 == DN) { 32 | SendMessage(wnd->extension, SETFOCUS, TRUE, 0); 33 | return TRUE; 34 | } 35 | break; 36 | case LEFT_BUTTON: 37 | if ((int)p1 == GetRight(wnd) + 1) 38 | SendMessage(wnd->extension, SETFOCUS, TRUE, 0); 39 | break; 40 | case CLOSE_WINDOW: 41 | SendMessage(wnd->extension, CLOSE_WINDOW, 0, 0); 42 | break; 43 | default: 44 | break; 45 | } 46 | return BaseWndProc(COMBOBOX, wnd, msg, p1, p2); 47 | } 48 | 49 | int ListProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 50 | { 51 | WINDOW pwnd = GetParent(GetParent(wnd)); 52 | DBOX *db = pwnd->extension; 53 | WINDOW cwnd = ControlWindow(db, wnd->ct->command); 54 | char text[130]; 55 | int rtn; 56 | WINDOW currFocus; 57 | switch (msg) { 58 | case CREATE_WINDOW: 59 | wnd->ct = DFmalloc(sizeof(CTLWINDOW)); 60 | wnd->ct->setting = OFF; 61 | wnd->WindowColors[FRAME_COLOR][FG] = 62 | wnd->WindowColors[STD_COLOR][FG]; 63 | wnd->WindowColors[FRAME_COLOR][BG] = 64 | wnd->WindowColors[STD_COLOR][BG]; 65 | rtn = DefaultWndProc(wnd, msg, p1, p2); 66 | return rtn; 67 | case SETFOCUS: 68 | if ((int)p1 == FALSE) { 69 | if (!wnd->isHelping) { 70 | SendMessage(wnd, HIDE_WINDOW, 0, 0); 71 | wnd->ct->setting = OFF; 72 | } 73 | } 74 | else 75 | wnd->ct->setting = ON; 76 | break; 77 | case SHOW_WINDOW: 78 | if (wnd->ct->setting == OFF) 79 | return TRUE; 80 | break; 81 | case BORDER: 82 | currFocus = inFocus; 83 | inFocus = NULL; 84 | rtn = DefaultWndProc(wnd, msg, p1, p2); 85 | inFocus = currFocus; 86 | return rtn; 87 | case LB_SELECTION: 88 | rtn = DefaultWndProc(wnd, msg, p1, p2); 89 | SendMessage(wnd, LB_GETTEXT, 90 | (PARAM) text, wnd->selection); 91 | PutItemText(pwnd, wnd->ct->command, text); 92 | SendMessage(cwnd, PAINT, 0, 0); 93 | cwnd->TextChanged = TRUE; 94 | return rtn; 95 | case KEYBOARD: 96 | switch ((int) p1) { 97 | case ESC: 98 | case FWD: 99 | case BS: 100 | SendMessage(cwnd, SETFOCUS, TRUE, 0); 101 | return TRUE; 102 | default: 103 | break; 104 | } 105 | break; 106 | case LB_CHOOSE: 107 | SendMessage(cwnd, SETFOCUS, TRUE, 0); 108 | return TRUE; 109 | case CLOSE_WINDOW: 110 | if (wnd->ct != NULL) 111 | free(wnd->ct); 112 | wnd->ct = NULL; 113 | break; 114 | default: 115 | break; 116 | } 117 | return DefaultWndProc(wnd, msg, p1, p2); 118 | } 119 | 120 | void PutComboListText(WINDOW wnd, enum commands cmd, char *text) 121 | { 122 | CTLWINDOW *ct = FindCommand(wnd->extension, cmd, COMBOBOX); 123 | if (ct != NULL) { 124 | WINDOW lwnd = ((WINDOW)(ct->wnd))->extension; 125 | SendMessage(lwnd, ADDTEXT, (PARAM) text, 0); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /commands.h: -------------------------------------------------------------------------------- 1 | /* ---------------- commands.h ----------------- */ 2 | 3 | /* 4 | * Command values sent as the first parameter 5 | * in the COMMAND message 6 | * 7 | * Add application-specific commands to this enum 8 | */ 9 | 10 | #ifndef COMMANDS_H 11 | #define COMMANDS_H 12 | 13 | enum commands { 14 | /* --------------- File menu ---------------- */ 15 | ID_OPEN, 16 | ID_NEW, 17 | ID_SAVE, 18 | ID_SAVEAS, 19 | ID_DELETEFILE, 20 | ID_PRINT, 21 | ID_PRINTSETUP, 22 | ID_DOS, 23 | ID_EXIT, 24 | /* --------------- Edit menu ---------------- */ 25 | ID_UNDO, 26 | ID_CUT, 27 | ID_COPY, 28 | ID_PASTE, 29 | ID_PARAGRAPH, 30 | ID_CLEAR, 31 | ID_DELETETEXT, 32 | /* --------------- Search Menu -------------- */ 33 | ID_SEARCH, 34 | ID_REPLACE, 35 | ID_SEARCHNEXT, 36 | /* --------------- Utilities Menu ------------- */ 37 | ID_CALENDAR, 38 | ID_BARCHART, 39 | /* -------------- Options menu -------------- */ 40 | ID_INSERT, 41 | ID_WRAP, 42 | ID_LOG, 43 | ID_TABS, 44 | ID_DISPLAY, 45 | ID_SAVEOPTIONS, 46 | /* --------------- Window menu -------------- */ 47 | ID_CLOSEALL, 48 | ID_WINDOW, 49 | ID_MOREWINDOWS, 50 | /* --------------- Help menu ---------------- */ 51 | ID_HELPHELP, 52 | ID_EXTHELP, 53 | ID_KEYSHELP, 54 | ID_HELPINDEX, 55 | ID_ABOUT, 56 | /* --------------- System menu -------------- */ 57 | #ifdef INCLUDE_RESTORE 58 | ID_SYSRESTORE, 59 | #endif 60 | ID_SYSMOVE, 61 | ID_SYSSIZE, 62 | #ifdef INCLUDE_MINIMIZE 63 | ID_SYSMINIMIZE, 64 | #endif 65 | #ifdef INCLUDE_MAXIMIZE 66 | ID_SYSMAXIMIZE, 67 | #endif 68 | ID_SYSCLOSE, 69 | /* ---- FileOpen and SaveAs dialog boxes ---- */ 70 | ID_FILENAME, 71 | ID_FILES, 72 | ID_DIRECTORY, 73 | ID_DRIVE, 74 | ID_PATH, 75 | /* ----- Search and Replace dialog boxes ---- */ 76 | ID_SEARCHFOR, 77 | ID_REPLACEWITH, 78 | ID_MATCHCASE, 79 | ID_REPLACEALL, 80 | /* ----------- Windows dialog box ----------- */ 81 | ID_WINDOWLIST, 82 | /* --------- generic command buttons -------- */ 83 | ID_OK, 84 | ID_CANCEL, 85 | ID_HELP, 86 | /* -------------- TabStops menu ------------- */ 87 | ID_TAB2, 88 | ID_TAB4, 89 | ID_TAB6, 90 | ID_TAB8, 91 | /* ------------ Display dialog box ---------- */ 92 | ID_BORDER, 93 | ID_TITLE, 94 | ID_STATUSBAR, 95 | ID_TEXTURE, 96 | ID_SNOWY, 97 | ID_COLOR, 98 | ID_MONO, 99 | ID_REVERSE, 100 | ID_25LINES, 101 | ID_43LINES, 102 | ID_50LINES, 103 | /* ------------- Log dialog box ------------- */ 104 | ID_LOGLIST, 105 | ID_LOGGING, 106 | /* ------------ HelpBox dialog box ---------- */ 107 | ID_HELPTEXT, 108 | ID_BACK, 109 | ID_PREV, 110 | ID_NEXT, 111 | /* ---------- Print Select dialog box --------- */ 112 | ID_PRINTERPORT, 113 | ID_LEFTMARGIN, 114 | ID_RIGHTMARGIN, 115 | ID_TOPMARGIN, 116 | ID_BOTTOMMARGIN, 117 | /* ----------- InputBox dialog box ------------ */ 118 | ID_INPUTTEXT 119 | }; 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /compilin.txt: -------------------------------------------------------------------------------- 1 | How to compile D-Flat and MemoPad for DOS with Smaller C. 2 | 3 | -1. Get Smaller C (with sources) and get it to successfully compile a 4 | hello-world app. See https://github.com/alexfru/SmallerC. 5 | 6 | 7 | 0. Recompile Smaller C (core compiler only) to support larger C source files. 8 | Do (beware, a long command line follows) 9 | 10 | > smlrcc smlrc.c -o smlrcbig[.exe] -DMAX_IDENT_TABLE_LEN=16384 -DSYNTAX_STACK_MAX=8192 -DMAX_CASES=257 -DSTACK_SIZE=256 11 | 12 | Then replace your smlrc[.exe] with smlrcbig[.exe]. 13 | 14 | 15 | 1. Compile D-Flat and MemoPad. 16 | Do 17 | 18 | > smlrcc @mldflat.txt 19 | > smlrcc @mmemopad.txt 20 | 21 | This should produce files ldflat.a and memopad.exe. 22 | In principle, you can now run memopad.exe in DOS, but without help file. 23 | 24 | 25 | 2. Compile help file tools (huffc and fixhelp) and generate memopad.hlp. 26 | 27 | 2.1. If you're doing it in DOS 28 | Do 29 | 30 | > smlrcc @mhuffc.txt 31 | > smlrcc @mfixhelp.txt 32 | 33 | This should produce files huffc.exe and fixhelp.exe. 34 | Then do 35 | 36 | > huffc.exe memopad.txt memopad.hlp 37 | > fixhelp.exe memopad 38 | 39 | This should produce memopad.hlp for memopad.exe. 40 | 41 | 2.2. If you're doing it in Windows 42 | Do 43 | 44 | > smlrcc -DBUILD_FULL_DFLAT -o huffc.exe huffc.c htree.c 45 | > smlrcc -DBUILD_FULL_DFLAT -o fixhelp.exe fixhelp.c decomp.c 46 | 47 | This should produce files huffc.exe and fixhelp.exe. 48 | Then do 49 | 50 | > huffc.exe memopad.txt memopad.hlp 51 | > fixhelp.exe memopad 52 | 53 | This should produce memopad.hlp for memopad.exe. 54 | 55 | 2.3. If you're doing it in Linux (I haven't tested this on Linux yet) 56 | Do 57 | 58 | > smlrcc -DBUILD_FULL_DFLAT -o huffc huffc.c htree.c 59 | > smlrcc -DBUILD_FULL_DFLAT -o fixhelp fixhelp.c decomp.c 60 | 61 | This should produce files huffc and fixhelp. 62 | Then do 63 | 64 | > ./huffc memopad.txt memopad.hlp 65 | > ./fixhelp memopad 66 | 67 | This should produce memopad.hlp for memopad.exe. 68 | 69 | 3. Done! You got memopad.exe and memopad.hlp and can run MemoPad in DOS. 70 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* ---------------- config.h -------------- */ 2 | 3 | #ifndef CONFIG_H 4 | #define CONFIG_H 5 | 6 | enum colortypes { 7 | STD_COLOR, 8 | SELECT_COLOR, 9 | FRAME_COLOR, 10 | HILITE_COLOR 11 | }; 12 | 13 | enum grounds { FG, BG }; 14 | 15 | /* ----------- configuration parameters ----------- */ 16 | typedef struct config { 17 | char version[sizeof VERSION]; 18 | char mono; /* 0=color, 1=mono, 2=reverse mono */ 19 | BOOL snowy; /* TRUE = snowy CGA display */ 20 | BOOL InsertMode; /* Editor insert mode */ 21 | int Tabs; /* Editor tab stops */ 22 | BOOL WordWrap; /* True to word wrap editor */ 23 | #ifdef INCLUDE_WINDOWOPTIONS 24 | BOOL Border; /* True for application window border */ 25 | BOOL Title; /* True for application window title */ 26 | BOOL StatusBar; /* True for appl'n window status bar */ 27 | #endif 28 | BOOL Texture; /* True for textured appl window */ 29 | int ScreenLines; /* Number of screen lines (25/43/50) */ 30 | char PrinterPort[5]; 31 | int LinesPage; /* Lines per printer page */ 32 | int CharsLine; /* Characters per printer line */ 33 | int LeftMargin; /* Printer margins */ 34 | int RightMargin; 35 | int TopMargin; 36 | int BottomMargin; 37 | unsigned char clr[CLASSCOUNT] [4] [2]; /* Colors */ 38 | } CONFIG; 39 | 40 | extern CONFIG cfg; 41 | extern unsigned char color[CLASSCOUNT] [4] [2]; 42 | extern unsigned char bw[CLASSCOUNT] [4] [2]; 43 | extern unsigned char reverse[CLASSCOUNT] [4] [2]; 44 | 45 | BOOL LoadConfig(void); 46 | void SaveConfig(void); 47 | FILE *OpenConfig(char *); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /console.c: -------------------------------------------------------------------------------- 1 | /* ----------- console.c ---------- */ 2 | 3 | #include "dflat.h" 4 | 5 | /* ----- table of alt keys for finding shortcut keys ----- */ 6 | static int altconvert[] = { 7 | ALT_A,ALT_B,ALT_C,ALT_D,ALT_E,ALT_F,ALT_G,ALT_H, 8 | ALT_I,ALT_J,ALT_K,ALT_L,ALT_M,ALT_N,ALT_O,ALT_P, 9 | ALT_Q,ALT_R,ALT_S,ALT_T,ALT_U,ALT_V,ALT_W,ALT_X, 10 | ALT_Y,ALT_Z,ALT_0,ALT_1,ALT_2,ALT_3,ALT_4,ALT_5, 11 | ALT_6,ALT_7,ALT_8,ALT_9 12 | }; 13 | 14 | unsigned video_mode; 15 | unsigned video_page; 16 | 17 | static int near cursorpos[MAXSAVES]; 18 | static int near cursorshape[MAXSAVES]; 19 | static int cs; 20 | 21 | static union REGS regs; 22 | 23 | /* ------------- clear the screen -------------- */ 24 | void clearscreen(void) 25 | { 26 | int ht = SCREENHEIGHT; 27 | int wd = SCREENWIDTH; 28 | cursor(0, 0); 29 | regs.h.al = ' '; 30 | regs.h.ah = 9; 31 | regs.x.bx = 7; 32 | regs.x.cx = ht * wd; 33 | int86(VIDEO, ®s, ®s); 34 | } 35 | 36 | void SwapCursorStack(void) 37 | { 38 | if (cs > 1) { 39 | swap(cursorpos[cs-2], cursorpos[cs-1]); 40 | swap(cursorshape[cs-2], cursorshape[cs-1]); 41 | } 42 | } 43 | 44 | #ifdef __SMALLER_C__ 45 | #else 46 | #ifndef MSC 47 | #ifndef WATCOM 48 | #define ZEROFLAG 0x40 49 | /* ---- Test for keystroke ---- */ 50 | BOOL keyhit(void) 51 | { 52 | _AH = 1; 53 | geninterrupt(KEYBRD); 54 | return (_FLAGS & ZEROFLAG) == 0; 55 | } 56 | #endif 57 | #endif 58 | #endif 59 | 60 | /* ---- Read a keystroke ---- */ 61 | int getkey(void) 62 | { 63 | int c; 64 | while (keyhit() == FALSE) 65 | ; 66 | if (((c = bioskey(0)) & 0xff) == 0) 67 | c = (c >> 8) | 0x1080; 68 | else 69 | c &= 0xff; 70 | return c & 0x10ff; 71 | } 72 | 73 | /* ---------- read the keyboard shift status --------- */ 74 | int getshift(void) 75 | { 76 | regs.h.ah = 2; 77 | int86(KEYBRD, ®s, ®s); 78 | return regs.h.al; 79 | } 80 | 81 | static volatile int far *clk = MK_FP(0x40,0x6c); 82 | /* ------- macro to wait one clock tick -------- */ 83 | #define wait() \ 84 | { \ 85 | int now = *clk; \ 86 | while (now == *clk) \ 87 | ; \ 88 | } 89 | 90 | /* -------- sound a buzz tone ---------- */ 91 | void beep(void) 92 | { 93 | wait(); 94 | outp(0x43, 0xb6); /* program the frequency */ 95 | outp(0x42, (int) (COUNT % 256)); 96 | outp(0x42, (int) (COUNT / 256)); 97 | outp(0x61, inp(0x61) | 3); /* start the sound */ 98 | wait(); 99 | outp(0x61, inp(0x61) & ~3); /* stop the sound */ 100 | } 101 | 102 | /* -------- get the video mode and page from BIOS -------- */ 103 | void videomode(void) 104 | { 105 | regs.h.ah = 15; 106 | int86(VIDEO, ®s, ®s); 107 | video_mode = regs.h.al; 108 | video_page = regs.x.bx; 109 | video_page &= 0xff00; 110 | video_mode &= 0x7f; 111 | } 112 | 113 | /* ------ position the cursor ------ */ 114 | void cursor(int x, int y) 115 | { 116 | videomode(); 117 | regs.x.dx = ((y << 8) & 0xff00) + x; 118 | regs.h.ah = SETCURSOR; 119 | regs.x.bx = video_page; 120 | int86(VIDEO, ®s, ®s); 121 | } 122 | 123 | /* ------ get cursor shape and position ------ */ 124 | static void near getcursor(void) 125 | { 126 | videomode(); 127 | regs.h.ah = READCURSOR; 128 | regs.x.bx = video_page; 129 | int86(VIDEO, ®s, ®s); 130 | } 131 | 132 | /* ------- get the current cursor position ------- */ 133 | void curr_cursor(int *x, int *y) 134 | { 135 | getcursor(); 136 | *x = regs.h.dl; 137 | *y = regs.h.dh; 138 | } 139 | 140 | /* ------ save the current cursor configuration ------ */ 141 | void savecursor(void) 142 | { 143 | if (cs < MAXSAVES) { 144 | getcursor(); 145 | cursorshape[cs] = regs.x.cx; 146 | cursorpos[cs] = regs.x.dx; 147 | cs++; 148 | } 149 | } 150 | 151 | /* ---- restore the saved cursor configuration ---- */ 152 | void restorecursor(void) 153 | { 154 | if (cs) { 155 | --cs; 156 | videomode(); 157 | regs.x.dx = cursorpos[cs]; 158 | regs.h.ah = SETCURSOR; 159 | regs.x.bx = video_page; 160 | int86(VIDEO, ®s, ®s); 161 | set_cursor_type(cursorshape[cs]); 162 | } 163 | } 164 | 165 | /* ------ make a normal cursor ------ */ 166 | void normalcursor(void) 167 | { 168 | set_cursor_type(0x0607); 169 | } 170 | 171 | /* ------ hide the cursor ------ */ 172 | void hidecursor(void) 173 | { 174 | getcursor(); 175 | regs.h.ch |= HIDECURSOR; 176 | regs.h.ah = SETCURSORTYPE; 177 | int86(VIDEO, ®s, ®s); 178 | } 179 | 180 | /* ------ unhide the cursor ------ */ 181 | void unhidecursor(void) 182 | { 183 | getcursor(); 184 | regs.h.ch &= ~HIDECURSOR; 185 | regs.h.ah = SETCURSORTYPE; 186 | int86(VIDEO, ®s, ®s); 187 | } 188 | 189 | /* ---- use BIOS to set the cursor type ---- */ 190 | void set_cursor_type(unsigned t) 191 | { 192 | videomode(); 193 | regs.h.ah = SETCURSORTYPE; 194 | regs.x.bx = video_page; 195 | regs.x.cx = t; 196 | int86(VIDEO, ®s, ®s); 197 | } 198 | 199 | /* ---- test for EGA -------- */ 200 | BOOL isEGA(void) 201 | { 202 | if (isVGA()) 203 | return FALSE; 204 | regs.h.ah = 0x12; 205 | regs.h.bl = 0x10; 206 | int86(VIDEO, ®s, ®s); 207 | return regs.h.bl != 0x10; 208 | } 209 | 210 | /* ---- test for VGA -------- */ 211 | BOOL isVGA(void) 212 | { 213 | regs.x.ax = 0x1a00; 214 | int86(VIDEO, ®s, ®s); 215 | return regs.h.al == 0x1a && regs.h.bl > 6; 216 | } 217 | 218 | static void Scan350(void) 219 | { 220 | regs.x.ax = 0x1201; 221 | regs.h.bl = 0x30; 222 | int86(VIDEO, ®s, ®s); 223 | regs.h.ah = 0x0f; 224 | int86(VIDEO, ®s, ®s); 225 | regs.h.ah = 0x00; 226 | int86(VIDEO, ®s, ®s); 227 | } 228 | 229 | static void Scan400(void) 230 | { 231 | regs.x.ax = 0x1202; 232 | regs.h.bl = 0x30; 233 | int86(VIDEO, ®s, ®s); 234 | regs.h.ah = 0x0f; 235 | int86(VIDEO, ®s, ®s); 236 | regs.h.ah = 0x00; 237 | int86(VIDEO, ®s, ®s); 238 | } 239 | 240 | /* ---------- set 25 line mode ------- */ 241 | void Set25(void) 242 | { 243 | if (isVGA()) { 244 | Scan400(); 245 | regs.x.ax = 0x1114; 246 | } 247 | else 248 | regs.x.ax = 0x1111; 249 | regs.h.bl = 0; 250 | int86(VIDEO, ®s, ®s); 251 | } 252 | 253 | /* ---------- set 43 line mode ------- */ 254 | void Set43(void) 255 | { 256 | if (isVGA()) 257 | Scan350(); 258 | regs.x.ax = 0x1112; 259 | regs.h.bl = 0; 260 | int86(VIDEO, ®s, ®s); 261 | } 262 | 263 | /* ---------- set 50 line mode ------- */ 264 | void Set50(void) 265 | { 266 | if (isVGA()) 267 | Scan400(); 268 | regs.x.ax = 0x1112; 269 | regs.h.bl = 0; 270 | int86(VIDEO, ®s, ®s); 271 | } 272 | 273 | /* ------ convert an Alt+ key to its letter equivalent ----- */ 274 | int AltConvert(int c) 275 | { 276 | int i, a = 0; 277 | for (i = 0; i < 36; i++) 278 | if (c == altconvert[i]) 279 | break; 280 | if (i < 26) 281 | a = 'a' + i; 282 | else if (i < 36) 283 | a = '0' + i - 26; 284 | return a; 285 | } 286 | 287 | #if MSC | WATCOM 288 | int getdisk(void) 289 | { 290 | unsigned int cd; 291 | _dos_getdrive(&cd); 292 | cd -= 1; 293 | return cd; 294 | } 295 | #endif 296 | -------------------------------------------------------------------------------- /decomp.c: -------------------------------------------------------------------------------- 1 | /* ------------------- decomp.c -------------------- */ 2 | 3 | /* 4 | * Decompress the application.HLP file 5 | * or load the application.TXT file if the .HLP file 6 | * does not exist 7 | */ 8 | 9 | #include 10 | #include "dflat.h" 11 | #include "htree.h" 12 | 13 | static int in8; 14 | static int ct8 = 8; 15 | static FILE *fi; 16 | static BYTECOUNTER bytectr; 17 | struct htr *HelpTree; 18 | static int root; 19 | 20 | /* ------- open the help database file -------- */ 21 | FILE *OpenHelpFile(const char *fn, const char *md) 22 | { 23 | char *cp; 24 | int treect, i; 25 | char helpname[65]; 26 | 27 | /* -------- get the name of the help file ---------- */ 28 | BuildFileName(helpname, fn, ".hlp"); 29 | if ((fi = fopen(helpname, md)) == NULL) 30 | return NULL; 31 | if (HelpTree == NULL) { 32 | /* ----- read the byte count ------ */ 33 | fread(&bytectr, sizeof bytectr, 1, fi); 34 | /* ----- read the frequency count ------ */ 35 | fread(&treect, sizeof treect, 1, fi); 36 | /* ----- read the root offset ------ */ 37 | fread(&root, sizeof root, 1, fi); 38 | HelpTree = calloc(treect-256, sizeof(struct htr)); 39 | if (HelpTree != NULL) { 40 | /* ---- read in the tree --- */ 41 | for (i = 0; i < treect-256; i++) { 42 | fread(&HelpTree[i].left, sizeof(int), 1, fi); 43 | fread(&HelpTree[i].right, sizeof(int), 1, fi); 44 | } 45 | } 46 | } 47 | return fi; 48 | } 49 | 50 | /* ----- read a line of text from the help database ----- */ 51 | void *GetHelpLine(char *line) 52 | { 53 | int h; 54 | *line = '\0'; 55 | while (TRUE) { 56 | /* ----- decompress a line from the file ------ */ 57 | h = root; 58 | /* ----- walk the Huffman tree ----- */ 59 | while (h > 255) { 60 | /* --- h is a node pointer --- */ 61 | if (ct8 == 8) { 62 | /* --- read 8 bits of compressed data --- */ 63 | if ((in8 = fgetc(fi)) == EOF) { 64 | *line = '\0'; 65 | return NULL; 66 | } 67 | ct8 = 0; 68 | } 69 | /* -- point to left or right node based on msb -- */ 70 | if (in8 & 0x80) 71 | h = HelpTree[h-256].left; 72 | else 73 | h = HelpTree[h-256].right; 74 | /* --- shift the next bit in --- */ 75 | in8 <<= 1; 76 | ct8++; 77 | } 78 | /* --- h < 255 = decompressed character --- */ 79 | if (h == '\r') 80 | continue; /* skip the '\r' character */ 81 | /* --- put the character in the buffer --- */ 82 | *line++ = h; 83 | /* --- if '\n', end of line --- */ 84 | if (h == '\n') 85 | break; 86 | } 87 | *line = '\0'; /* null-terminate the line */ 88 | return line; 89 | } 90 | 91 | /* --- compute the database file byte and bit position --- */ 92 | void HelpFilePosition(long *offset, int *bit) 93 | { 94 | *offset = ftell(fi); 95 | if (ct8 < 8) 96 | --*offset; 97 | *bit = ct8; 98 | } 99 | 100 | /* -- position the database to the specified byte and bit -- */ 101 | void SeekHelpLine(long offset, int bit) 102 | { 103 | int fs = fseek(fi, offset, 0); 104 | assert(fs == 0); 105 | ct8 = bit; 106 | if (ct8 < 8) { 107 | in8 = fgetc(fi); 108 | in8 <<= bit; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /dfalloc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/dfalloc.c -------------------------------------------------------------------------------- /dflat.bld: -------------------------------------------------------------------------------- 1 | +menu & 2 | +window & 3 | +video & 4 | +message & 5 | +mouse & 6 | +console & 7 | +normal & 8 | +textbox & 9 | +listbox & 10 | +menubar & 11 | +popdown & 12 | +rect & 13 | +applicat & 14 | +keys & 15 | +config & 16 | +sysmenu & 17 | +editbox & 18 | +dialbox & 19 | +button & 20 | +msgbox & 21 | +helpbox & 22 | +lists & 23 | +statbar & 24 | +decomp & 25 | +combobox & 26 | +clipbord & 27 | +search & 28 | +fileopen & 29 | +dfalloc & 30 | +checkbox & 31 | +text & 32 | +radio & 33 | +box & 34 | +watch & 35 | +slidebox & 36 | +spinbutt & 37 | +direct & 38 | +barchart & 39 | +log & 40 | +calendar & 41 | +pictbox & 42 | +editor 43 | -------------------------------------------------------------------------------- /dflat.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/dflat.doc -------------------------------------------------------------------------------- /dflat.lbc: -------------------------------------------------------------------------------- 1 | +menu 2 | +window 3 | +video 4 | +message 5 | +mouse 6 | +console 7 | +normal 8 | +textbox 9 | +listbox 10 | +menubar 11 | +popdown 12 | +rect 13 | +applicat 14 | +keys 15 | +config 16 | +sysmenu 17 | +editbox 18 | +dialbox 19 | +button 20 | +msgbox 21 | +helpbox 22 | +lists 23 | +statbar 24 | +decomp 25 | +combobox 26 | +clipbord 27 | +search 28 | +fileopen 29 | +dfalloc 30 | +log 31 | +pictbox 32 | +calendar 33 | +barchart 34 | +checkbox 35 | +text 36 | +radio 37 | +box 38 | +spinbutt 39 | +watch 40 | +slidebox 41 | +direct 42 | +editor 43 | -------------------------------------------------------------------------------- /dflatmsg.h: -------------------------------------------------------------------------------- 1 | /* ----------- dflatmsg.h ------------ */ 2 | 3 | /* 4 | * message foundation file 5 | * make message changes here 6 | * other source files will adapt 7 | */ 8 | 9 | /* -------------- process communication messages ----------- */ 10 | DFlatMsg(START) /* start message processing */ 11 | DFlatMsg(STOP) /* stop message processing */ 12 | DFlatMsg(COMMAND) /* send a command to a window */ 13 | /* -------------- window management messages --------------- */ 14 | DFlatMsg(CREATE_WINDOW) /* create a window */ 15 | DFlatMsg(OPEN_WINDOW) /* open a window */ 16 | DFlatMsg(SHOW_WINDOW) /* show a window */ 17 | DFlatMsg(HIDE_WINDOW) /* hide a window */ 18 | DFlatMsg(CLOSE_WINDOW) /* delete a window */ 19 | DFlatMsg(SETFOCUS) /* set and clear the focus */ 20 | DFlatMsg(PAINT) /* paint the window's data space*/ 21 | DFlatMsg(BORDER) /* paint the window's border */ 22 | DFlatMsg(TITLE) /* display the window's title */ 23 | DFlatMsg(MOVE) /* move the window */ 24 | DFlatMsg(SIZE) /* change the window's size */ 25 | #ifdef INCLUDE_MAXIMIZE 26 | DFlatMsg(MAXIMIZE) /* maximize the window */ 27 | #endif 28 | #ifdef INCLUDE_MINIMIZE 29 | DFlatMsg(MINIMIZE) /* minimize the window */ 30 | #endif 31 | DFlatMsg(RESTORE) /* restore the window */ 32 | DFlatMsg(INSIDE_WINDOW) /* test x/y inside a window */ 33 | /* ---------------- clock messages ------------------------- */ 34 | DFlatMsg(CLOCKTICK) /* the clock ticked */ 35 | DFlatMsg(CAPTURE_CLOCK) /* capture clock into a window */ 36 | DFlatMsg(RELEASE_CLOCK) /* release clock to the system */ 37 | /* -------------- keyboard and screen messages ------------- */ 38 | DFlatMsg(KEYBOARD) /* key was pressed */ 39 | DFlatMsg(CAPTURE_KEYBOARD) /* capture keyboard into a window */ 40 | DFlatMsg(RELEASE_KEYBOARD) /* release keyboard to system */ 41 | DFlatMsg(KEYBOARD_CURSOR) /* position the keyboard cursor */ 42 | DFlatMsg(CURRENT_KEYBOARD_CURSOR) /*read the cursor position */ 43 | DFlatMsg(HIDE_CURSOR) /* hide the keyboard cursor */ 44 | DFlatMsg(SHOW_CURSOR) /* display the keyboard cursor */ 45 | DFlatMsg(SAVE_CURSOR) /* save the cursor's configuration*/ 46 | DFlatMsg(RESTORE_CURSOR) /* restore the saved cursor */ 47 | DFlatMsg(SHIFT_CHANGED) /* the shift status changed */ 48 | DFlatMsg(WAITKEYBOARD) /* waits for a key to be released */ 49 | /* ---------------- mouse messages ------------------------- */ 50 | DFlatMsg(RESET_MOUSE) /* reset the mouse */ 51 | DFlatMsg(MOUSE_TRAVEL) /* set the mouse travel */ 52 | DFlatMsg(MOUSE_INSTALLED) /* test for mouse installed */ 53 | DFlatMsg(RIGHT_BUTTON) /* right button pressed */ 54 | DFlatMsg(LEFT_BUTTON) /* left button pressed */ 55 | DFlatMsg(DOUBLE_CLICK) /* left button double-clicked */ 56 | DFlatMsg(MOUSE_MOVED) /* mouse changed position */ 57 | DFlatMsg(BUTTON_RELEASED) /* mouse button released */ 58 | DFlatMsg(CURRENT_MOUSE_CURSOR)/* get mouse position */ 59 | DFlatMsg(MOUSE_CURSOR) /* set mouse position */ 60 | DFlatMsg(SHOW_MOUSE) /* make mouse cursor visible */ 61 | DFlatMsg(HIDE_MOUSE) /* hide mouse cursor */ 62 | DFlatMsg(WAITMOUSE) /* wait until button released */ 63 | DFlatMsg(TESTMOUSE) /* test any mouse button pressed*/ 64 | DFlatMsg(CAPTURE_MOUSE) /* capture mouse into a window */ 65 | DFlatMsg(RELEASE_MOUSE) /* release the mouse to system */ 66 | /* ---------------- text box messages ---------------------- */ 67 | DFlatMsg(ADDTEXT) /* append text to the text box */ 68 | DFlatMsg(INSERTTEXT) /* insert line of text */ 69 | DFlatMsg(DELETETEXT) /* delete line of text */ 70 | DFlatMsg(CLEARTEXT) /* clear the edit box */ 71 | DFlatMsg(SETTEXT) /* copy text to text buffer */ 72 | DFlatMsg(SCROLL) /* vertical line scroll */ 73 | DFlatMsg(HORIZSCROLL) /* horizontal column scroll */ 74 | DFlatMsg(SCROLLPAGE) /* vertical page scroll */ 75 | DFlatMsg(HORIZPAGE) /* horizontal page scroll */ 76 | DFlatMsg(SCROLLDOC) /* scroll to beginning/end */ 77 | /* ---------------- edit box messages ---------------------- */ 78 | DFlatMsg(GETTEXT) /* get text from an edit box */ 79 | DFlatMsg(SETTEXTLENGTH) /* set maximum text length */ 80 | /* ---------------- menubar messages ----------------------- */ 81 | DFlatMsg(BUILDMENU) /* build the menu display */ 82 | DFlatMsg(MB_SELECTION) /* menubar selection */ 83 | /* ---------------- popdown messages ----------------------- */ 84 | DFlatMsg(BUILD_SELECTIONS) /* build the menu display */ 85 | DFlatMsg(CLOSE_POPDOWN) /* tell parent popdown is closing */ 86 | /* ---------------- list box messages ---------------------- */ 87 | DFlatMsg(LB_SELECTION) /* sent to parent on selection */ 88 | DFlatMsg(LB_CHOOSE) /* sent when user chooses */ 89 | DFlatMsg(LB_CURRENTSELECTION)/* return the current selection */ 90 | DFlatMsg(LB_GETTEXT) /* return the text of selection */ 91 | DFlatMsg(LB_SETSELECTION) /* sets the listbox selection */ 92 | /* ---------------- dialog box messages -------------------- */ 93 | DFlatMsg(INITIATE_DIALOG) /* begin a dialog */ 94 | DFlatMsg(ENTERFOCUS) /* tell DB control got focus */ 95 | DFlatMsg(LEAVEFOCUS) /* tell DB control lost focus */ 96 | DFlatMsg(ENDDIALOG) /* end a dialog */ 97 | /* ---------------- help box messages ---------------------- */ 98 | DFlatMsg(DISPLAY_HELP) 99 | /* --------------- application window messages ------------- */ 100 | DFlatMsg(ADDSTATUS) 101 | /* --------------- picture box messages -------------------- */ 102 | DFlatMsg(DRAWVECTOR) 103 | DFlatMsg(DRAWBOX) 104 | DFlatMsg(DRAWBAR) 105 | -------------------------------------------------------------------------------- /dialbox.h: -------------------------------------------------------------------------------- 1 | /* ----------------- dialbox.h ---------------- */ 2 | 3 | #ifndef DIALOG_H 4 | #define DIALOG_H 5 | 6 | #include 7 | 8 | #define MAXCONTROLS 30 9 | #define MAXRADIOS 20 10 | 11 | #define OFF FALSE 12 | #define ON TRUE 13 | 14 | /* -------- dialog box and control window structure ------- */ 15 | typedef struct { 16 | char *title; /* window title */ 17 | int x, y; /* relative coordinates */ 18 | int h, w; /* size */ 19 | } DIALOGWINDOW; 20 | 21 | /* ------ one of these for each control window ------- */ 22 | typedef struct { 23 | DIALOGWINDOW dwnd; 24 | CLASS Class; /* LISTBOX, BUTTON, etc */ 25 | char *itext; /* initialized text */ 26 | int command; /* command code */ 27 | char *help; /* help mnemonic */ 28 | BOOL isetting; /* initially ON or OFF */ 29 | BOOL setting; /* ON or OFF */ 30 | void *wnd; /* window handle */ 31 | } CTLWINDOW; 32 | 33 | /* --------- one of these for each dialog box ------- */ 34 | typedef struct { 35 | char *HelpName; 36 | DIALOGWINDOW dwnd; 37 | CTLWINDOW ctl[MAXCONTROLS+1]; 38 | } DBOX; 39 | 40 | /* -------- macros for dialog box resource compile -------- */ 41 | #define DIALOGBOX(db) DBOX db={ #db, 42 | #define DB_TITLE(ttl,x,y,h,w) {ttl,x,y,h,w},{ 43 | #define CONTROL(ty,tx,x,y,h,w,c) \ 44 | {{NULL,x,y,h,w},ty, \ 45 | (ty==EDITBOX||ty==COMBOBOX?NULL:tx), \ 46 | c,#c,(ty==BUTTON?ON:OFF),OFF,NULL}, 47 | 48 | #define ENDDB {{NULL}} }}; 49 | 50 | #define Cancel " Cancel " 51 | #define Ok " OK " 52 | #define Yes " Yes " 53 | #define No " No " 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /dialogs.c: -------------------------------------------------------------------------------- 1 | /* ----------- dialogs.c --------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | /* -------------- the File Open dialog box --------------- */ 6 | DIALOGBOX( FileOpen ) 7 | DB_TITLE( "Open File", -1,-1,19,57) 8 | CONTROL(TEXT, "~Filename:", 3, 1, 1, 9, ID_FILENAME) 9 | CONTROL(EDITBOX, NULL, 13, 1, 1,40, ID_FILENAME) 10 | CONTROL(TEXT, NULL, 3, 3, 1,50, ID_PATH ) 11 | CONTROL(TEXT, "F~iles:", 3, 5, 1, 6, ID_FILES ) 12 | CONTROL(LISTBOX, NULL, 3, 6,10,14, ID_FILES ) 13 | CONTROL(TEXT, "~Directories:",19, 5, 1,12, ID_DIRECTORY ) 14 | CONTROL(LISTBOX, NULL, 19, 6,10,13, ID_DIRECTORY ) 15 | CONTROL(TEXT, "Dri~ves:", 34, 5, 1, 7, ID_DRIVE ) 16 | CONTROL(LISTBOX, NULL, 34, 6,10,10, ID_DRIVE ) 17 | CONTROL(BUTTON, " ~OK ", 46, 7, 1, 8, ID_OK) 18 | CONTROL(BUTTON, " ~Cancel ", 46,10, 1, 8, ID_CANCEL) 19 | CONTROL(BUTTON, " ~Help ", 46,13, 1, 8, ID_HELP) 20 | ENDDB 21 | 22 | /* -------------- the Save As dialog box --------------- */ 23 | DIALOGBOX( SaveAs ) 24 | DB_TITLE( "Save As", -1,-1,19,57) 25 | CONTROL(TEXT, "~Filename:", 3, 1, 1, 9, ID_FILENAME) 26 | CONTROL(EDITBOX, NULL, 13, 1, 1,40, ID_FILENAME) 27 | CONTROL(TEXT, NULL, 3, 3, 1,50, ID_PATH ) 28 | CONTROL(TEXT, "F~iles:", 3, 5, 1, 6, ID_FILES ) 29 | CONTROL(LISTBOX, NULL, 3, 6,10,14, ID_FILES ) 30 | CONTROL(TEXT, "~Directories:",19, 5, 1,12, ID_DIRECTORY ) 31 | CONTROL(LISTBOX, NULL, 19, 6,10,13, ID_DIRECTORY ) 32 | CONTROL(TEXT, "Dri~ves:", 34, 5, 1, 7, ID_DRIVE ) 33 | CONTROL(LISTBOX, NULL, 34, 6,10,10, ID_DRIVE ) 34 | CONTROL(BUTTON, " ~OK ", 46, 7, 1, 8, ID_OK) 35 | CONTROL(BUTTON, " ~Cancel ", 46,10, 1, 8, ID_CANCEL) 36 | CONTROL(BUTTON, " ~Help ", 46,13, 1, 8, ID_HELP) 37 | ENDDB 38 | 39 | /* -------------- The Printer Setup dialog box ------------------ */ 40 | DIALOGBOX( PrintSetup ) 41 | DB_TITLE( "Printer Setup", -1, -1, 17, 32) 42 | CONTROL(BOX, "Margins", 2, 3, 9, 26, 0 ) 43 | CONTROL(TEXT, "~Port:", 4, 1, 1, 5, ID_PRINTERPORT) 44 | CONTROL(COMBOBOX, NULL, 12, 1, 8, 9, ID_PRINTERPORT) 45 | CONTROL(TEXT, "~Left:", 6, 4, 1, 5, ID_LEFTMARGIN) 46 | CONTROL(SPINBUTTON, NULL, 17, 4, 1, 6, ID_LEFTMARGIN) 47 | CONTROL(TEXT, "~Right:", 6, 6, 1, 6, ID_RIGHTMARGIN) 48 | CONTROL(SPINBUTTON, NULL, 17, 6, 1, 6, ID_RIGHTMARGIN) 49 | CONTROL(TEXT, "~Top:", 6, 8, 1, 4, ID_TOPMARGIN) 50 | CONTROL(SPINBUTTON, NULL, 17, 8, 1, 6, ID_TOPMARGIN) 51 | CONTROL(TEXT, "~Bottom:", 6, 10, 1, 7, ID_BOTTOMMARGIN) 52 | CONTROL(SPINBUTTON, NULL, 17, 10, 1, 6, ID_BOTTOMMARGIN) 53 | CONTROL(BUTTON, " ~OK ", 1, 13, 1, 8, ID_OK) 54 | CONTROL(BUTTON, " ~Cancel ", 11, 13, 1, 8, ID_CANCEL) 55 | CONTROL(BUTTON, " ~Help ", 21, 13, 1, 8, ID_HELP) 56 | ENDDB 57 | 58 | /* -------------- the Search Text dialog box --------------- */ 59 | DIALOGBOX( SearchTextDB ) 60 | DB_TITLE( "Search Text", -1,-1,9,48) 61 | CONTROL(TEXT, "~Search for:", 2, 1, 1, 11, ID_SEARCHFOR) 62 | CONTROL(EDITBOX, NULL, 14, 1, 1, 29, ID_SEARCHFOR) 63 | CONTROL(TEXT, "~Match upper/lower case:", 2, 3, 1, 23, ID_MATCHCASE) 64 | CONTROL(CHECKBOX, NULL, 26, 3, 1, 3, ID_MATCHCASE) 65 | CONTROL(BUTTON, " ~OK ", 7, 5, 1, 8, ID_OK) 66 | CONTROL(BUTTON, " ~Cancel ", 19, 5, 1, 8, ID_CANCEL) 67 | CONTROL(BUTTON, " ~Help ", 31, 5, 1, 8, ID_HELP) 68 | ENDDB 69 | 70 | /* -------------- the Replace Text dialog box --------------- */ 71 | DIALOGBOX( ReplaceTextDB ) 72 | DB_TITLE( "Replace Text", -1,-1,12,50) 73 | CONTROL(TEXT, "~Search for:", 2, 1, 1, 11, ID_SEARCHFOR) 74 | CONTROL(EDITBOX, NULL, 16, 1, 1, 29, ID_SEARCHFOR) 75 | CONTROL(TEXT, "~Replace with:", 2, 3, 1, 13, ID_REPLACEWITH) 76 | CONTROL(EDITBOX, NULL, 16, 3, 1, 29, ID_REPLACEWITH) 77 | CONTROL(TEXT, "~Match upper/lower case:", 2, 5, 1, 23, ID_MATCHCASE) 78 | CONTROL(CHECKBOX, NULL, 26, 5, 1, 3, ID_MATCHCASE) 79 | CONTROL(TEXT, "Replace ~Every Match:", 2, 6, 1, 23, ID_REPLACEALL) 80 | CONTROL(CHECKBOX, NULL, 26, 6, 1, 3, ID_REPLACEALL) 81 | CONTROL(BUTTON, " ~OK ", 7, 8, 1, 8, ID_OK) 82 | CONTROL(BUTTON, " ~Cancel ", 20, 8, 1, 8, ID_CANCEL) 83 | CONTROL(BUTTON, " ~Help ", 33, 8, 1, 8, ID_HELP) 84 | ENDDB 85 | 86 | /* -------------- generic message dialog box --------------- */ 87 | DIALOGBOX( MsgBox ) 88 | DB_TITLE( NULL, -1,-1, 0, 0) 89 | CONTROL(TEXT, NULL, 1, 1, 0, 0, 0) 90 | CONTROL(BUTTON, NULL, 0, 0, 1, 8, ID_OK) 91 | CONTROL(0, NULL, 0, 0, 1, 8, ID_CANCEL) 92 | ENDDB 93 | 94 | /* ----------- InputBox Dialog Box ------------ */ 95 | DIALOGBOX( InputBoxDB ) 96 | DB_TITLE( NULL, -1,-1, 9, 0) 97 | CONTROL(TEXT, NULL, 1, 1, 1, 0, 0) 98 | CONTROL(EDITBOX, NULL, 1, 3, 1, 0, ID_INPUTTEXT) 99 | CONTROL(BUTTON, " ~OK ", 0, 5, 1, 8, ID_OK) 100 | CONTROL(BUTTON, " ~Cancel ", 0, 5, 1, 8, ID_CANCEL) 101 | ENDDB 102 | 103 | /* ----------- SliderBox Dialog Box ------------- */ 104 | DIALOGBOX( SliderBoxDB ) 105 | DB_TITLE( NULL, -1,-1, 9, 0) 106 | CONTROL(TEXT, NULL, 0, 1, 1, 0, 0) 107 | CONTROL(TEXT, NULL, 0, 3, 1, 0, 0) 108 | CONTROL(BUTTON, " Cancel ", 0, 5, 1, 8, ID_CANCEL) 109 | ENDDB 110 | 111 | #ifdef INCLUDE_WINDOWOPTIONS 112 | #define offset 7 113 | #else 114 | #define offset 0 115 | #endif 116 | 117 | /* ------------ Display dialog box -------------- */ 118 | DIALOGBOX( Display ) 119 | DB_TITLE( "Display", -1, -1, 12+offset, 35) 120 | #ifdef INCLUDE_WINDOWOPTIONS 121 | CONTROL(BOX, "Window", 7, 1, 6,20, 0) 122 | CONTROL(CHECKBOX, NULL, 9, 2, 1, 3, ID_TITLE) 123 | CONTROL(TEXT, "~Title", 15, 2, 1, 5, ID_TITLE) 124 | CONTROL(CHECKBOX, NULL, 9, 3, 1, 3, ID_BORDER) 125 | CONTROL(TEXT, "~Border", 15, 3, 1, 6, ID_BORDER) 126 | CONTROL(CHECKBOX, NULL, 9, 4, 1, 3, ID_STATUSBAR) 127 | CONTROL(TEXT, "~Status bar",15, 4, 1,10, ID_STATUSBAR) 128 | CONTROL(CHECKBOX, NULL, 9, 5, 1, 3, ID_TEXTURE) 129 | CONTROL(TEXT, "Te~xture", 15, 5, 1, 7, ID_TEXTURE) 130 | #endif 131 | CONTROL(BOX, "Colors", 1, 1+offset,5,15, 0) 132 | CONTROL(RADIOBUTTON, NULL, 3, 2+offset,1,3,ID_COLOR) 133 | CONTROL(TEXT, "Co~lor", 7, 2+offset,1,5,ID_COLOR) 134 | CONTROL(RADIOBUTTON, NULL, 3, 3+offset,1,3,ID_MONO) 135 | CONTROL(TEXT, "~Mono", 7, 3+offset,1,4,ID_MONO) 136 | CONTROL(RADIOBUTTON, NULL, 3, 4+offset,1,3,ID_REVERSE) 137 | CONTROL(TEXT, "~Reverse", 7, 4+offset,1,7,ID_REVERSE) 138 | 139 | CONTROL(BOX, "Lines", 17, 1+offset,5,15, 0) 140 | CONTROL(RADIOBUTTON, NULL, 19, 2+offset,1,3,ID_25LINES) 141 | CONTROL(TEXT, "~25", 23, 2+offset,1,2,ID_25LINES) 142 | CONTROL(RADIOBUTTON, NULL, 19, 3+offset,1,3,ID_43LINES) 143 | CONTROL(TEXT, "~43", 23, 3+offset,1,2,ID_43LINES) 144 | CONTROL(RADIOBUTTON, NULL, 19, 4+offset,1,3,ID_50LINES) 145 | CONTROL(TEXT, "~50", 23, 4+offset,1,2,ID_50LINES) 146 | 147 | CONTROL(CHECKBOX, NULL, 11, 6+offset,1,3,ID_SNOWY) 148 | CONTROL(TEXT, "S~nowy", 15, 6+offset,1,7,ID_SNOWY) 149 | 150 | CONTROL(BUTTON, " ~OK ", 2, 8+offset,1,8,ID_OK) 151 | CONTROL(BUTTON, " ~Cancel ", 12, 8+offset,1,8,ID_CANCEL) 152 | CONTROL(BUTTON, " ~Help ", 22, 8+offset,1,8,ID_HELP) 153 | ENDDB 154 | 155 | /* ------------ Windows dialog box -------------- */ 156 | DIALOGBOX( Windows ) 157 | DB_TITLE( "Windows", -1, -1, 19, 24) 158 | CONTROL(LISTBOX, NULL, 1, 1,11,20, ID_WINDOWLIST) 159 | CONTROL(BUTTON, " ~OK ", 2, 13, 1, 8, ID_OK) 160 | CONTROL(BUTTON, " ~Cancel ", 12, 13, 1, 8, ID_CANCEL) 161 | CONTROL(BUTTON, " ~Help ", 7, 15, 1, 8, ID_HELP) 162 | ENDDB 163 | 164 | #ifdef INCLUDE_LOGGING 165 | /* ------------ Message Log dialog box -------------- */ 166 | DIALOGBOX( Log ) 167 | DB_TITLE( "D-Flat Message Log", -1, -1, 18, 41) 168 | CONTROL(TEXT, "~Messages", 10, 1, 1, 8, ID_LOGLIST) 169 | CONTROL(LISTBOX, NULL, 1, 2, 14, 26, ID_LOGLIST) 170 | CONTROL(TEXT, "~Logging:", 29, 4, 1, 10, ID_LOGGING) 171 | CONTROL(CHECKBOX, NULL, 31, 5, 1, 3, ID_LOGGING) 172 | CONTROL(BUTTON, " ~OK ", 29, 7, 1, 8, ID_OK) 173 | CONTROL(BUTTON, " ~Cancel ", 29, 10, 1, 8, ID_CANCEL) 174 | CONTROL(BUTTON, " ~Help ", 29, 13, 1, 8, ID_HELP) 175 | ENDDB 176 | #endif 177 | 178 | /* ------------ the Help window dialog box -------------- */ 179 | DIALOGBOX( HelpBox ) 180 | DB_TITLE( NULL, -1, -1, 0, 45) 181 | CONTROL(TEXTBOX, NULL, 1, 1, 0, 40, ID_HELPTEXT) 182 | CONTROL(BUTTON, " ~Close ", 0, 0, 1, 8, ID_CANCEL) 183 | CONTROL(BUTTON, " ~Back ", 10, 0, 1, 8, ID_BACK) 184 | CONTROL(BUTTON, "<< ~Prev ", 20, 0, 1, 8, ID_PREV) 185 | CONTROL(BUTTON, " ~Next >>", 30, 0, 1, 8, ID_NEXT) 186 | ENDDB 187 | -------------------------------------------------------------------------------- /direct.c: -------------------------------------------------------------------------------- 1 | /* ---------- direct.c --------- */ 2 | 3 | #include "dflat.h" 4 | 5 | #ifndef BCPP 6 | #define FA_DIREC 0x10 7 | #endif 8 | 9 | static char path[MAXPATH]; 10 | static char drive[MAXDRIVE] = " :"; 11 | static char dir[MAXDIR]; 12 | static char name[MAXFILE]; 13 | static char ext[MAXEXT]; 14 | 15 | /* ----- Create unambiguous path from file spec, filling in the 16 | drive and directory if incomplete. Optionally change to 17 | the new drive and subdirectory ------ */ 18 | void CreatePath(char *spath,char *fspec,int InclName,int Change) 19 | { 20 | int cm = 0; 21 | unsigned currdrive; 22 | char currdir[MAXPATH+1]; 23 | char *cp; 24 | 25 | if (!Change) { 26 | /* ---- save the current drive and subdirectory ---- */ 27 | currdrive = getdisk(); 28 | getcwd(currdir, sizeof currdir); 29 | memmove(currdir, currdir+2, strlen(currdir+1)); 30 | cp = currdir+strlen(currdir)-1; 31 | if (*cp == '\\') 32 | *cp = '\0'; 33 | } 34 | *drive = *dir = *name = *ext = '\0'; 35 | fnsplit(fspec, drive, dir, name, ext); 36 | if (!InclName) 37 | *name = *ext = '\0'; 38 | *drive = toupper(*drive); 39 | if (*ext) 40 | cm |= EXTENSION; 41 | if (InclName && *name) 42 | cm |= FILENAME; 43 | if (*dir) 44 | cm |= DIRECTORY; 45 | if (*drive) 46 | cm |= DRIVE; 47 | if (cm & DRIVE) 48 | setdisk(*drive - 'A'); 49 | else { 50 | *drive = getdisk(); 51 | *drive += 'A'; 52 | } 53 | if (cm & DIRECTORY) { 54 | cp = dir+strlen(dir)-1; 55 | if (*cp == '\\') 56 | *cp = '\0'; 57 | chdir(dir); 58 | } 59 | getcwd(dir, sizeof dir); 60 | memmove(dir, dir+2, strlen(dir+1)); 61 | if (InclName) { 62 | if (!(cm & FILENAME)) 63 | strcpy(name, "*"); 64 | if (!(cm & EXTENSION) && strchr(fspec, '.') != NULL) 65 | strcpy(ext, ".*"); 66 | } 67 | else 68 | *name = *ext = '\0'; 69 | if (dir[strlen(dir)-1] != '\\') 70 | strcat(dir, "\\"); 71 | if (spath != NULL) 72 | fnmerge(spath, drive, dir, name, ext); 73 | if (!Change) { 74 | setdisk(currdrive); 75 | chdir(currdir); 76 | } 77 | } 78 | 79 | static int dircmp(const void *c1, const void *c2) 80 | { 81 | return stricmp(*(char **)c1, *(char **)c2); 82 | } 83 | 84 | static BOOL BuildList(WINDOW wnd, char *fspec, BOOL dirs) 85 | { 86 | int ax, i = 0, criterr = 1; 87 | struct ffblk ff; 88 | CTLWINDOW *ct = FindCommand(wnd->extension, 89 | dirs ? ID_DIRECTORY : ID_FILES,LISTBOX); 90 | WINDOW lwnd; 91 | char **dirlist = NULL; 92 | 93 | if (ct != NULL) { 94 | lwnd = ct->wnd; 95 | SendMessage(lwnd, CLEARTEXT, 0, 0); 96 | 97 | while (criterr == 1) { 98 | ax = findfirst(fspec, &ff, dirs ? FA_DIREC: 0); 99 | criterr = TestCriticalError(); 100 | } 101 | if (criterr) 102 | return FALSE; 103 | while (ax == 0) { 104 | if (!dirs || (ff.ff_attrib & FA_DIREC) && strcmp(ff.ff_name, ".")) { 105 | dirlist = DFrealloc(dirlist, sizeof(char *)*(i+1)); 106 | dirlist[i] = DFmalloc(strlen(ff.ff_name)+1); 107 | strcpy(dirlist[i++], ff.ff_name); 108 | } 109 | ax = findnext(&ff); 110 | } 111 | if (dirlist != NULL) { 112 | int j; 113 | /* -- sort file or directory list box data -- */ 114 | qsort(dirlist, i, sizeof(void *), dircmp); 115 | /* ---- send sorted list to list box ---- */ 116 | for (j = 0; j < i; j++) { 117 | SendMessage(lwnd,ADDTEXT,(PARAM)dirlist[j],0); 118 | free(dirlist[j]); 119 | } 120 | free(dirlist); 121 | } 122 | SendMessage(lwnd, SHOW_WINDOW, 0, 0); 123 | } 124 | return TRUE; 125 | } 126 | 127 | BOOL BuildFileList(WINDOW wnd, char *fspec) 128 | { 129 | return BuildList(wnd, fspec, FALSE); 130 | } 131 | 132 | void BuildDirectoryList(WINDOW wnd) 133 | { 134 | BuildList(wnd, "*.*", TRUE); 135 | } 136 | 137 | void BuildDriveList(WINDOW wnd) 138 | { 139 | CTLWINDOW *ct = FindCommand(wnd->extension, ID_DRIVE,LISTBOX); 140 | if (ct != NULL) { 141 | union REGS regs; 142 | char drname[15]; 143 | unsigned int cd, dr; 144 | WINDOW lwnd = ct->wnd; 145 | SendMessage(lwnd, CLEARTEXT, 0, 0); 146 | 147 | cd = getdisk(); 148 | for (dr = 0; dr < 26; dr++) { 149 | unsigned ndr; 150 | setdisk(dr); 151 | ndr = getdisk(); 152 | if (ndr == dr) { 153 | /* ----- test for remapped B drive ----- */ 154 | if (dr == 1) { 155 | regs.x.ax = 0x440e; /* IOCTL func 14 */ 156 | regs.h.bl = dr+1; 157 | int86(DOS, ®s, ®s); 158 | if (regs.h.al != 0) 159 | continue; 160 | } 161 | 162 | sprintf(drname, "%c:", dr+'A'); 163 | 164 | /* ---- test for network or RAM disk ---- */ 165 | regs.x.ax = 0x4409; /* IOCTL func 9 */ 166 | regs.h.bl = dr+1; 167 | int86(DOS, ®s, ®s); 168 | if (!regs.x.cflag) { 169 | if (regs.x.dx & 0x1000) 170 | strcat(drname, " (Net)"); 171 | else if (regs.x.dx == 0x0800) 172 | strcat(drname, " (RAM)"); 173 | } 174 | SendMessage(lwnd,ADDTEXT,(PARAM)drname,0); 175 | } 176 | } 177 | SendMessage(lwnd, SHOW_WINDOW, 0, 0); 178 | setdisk(cd); 179 | } 180 | } 181 | 182 | void BuildPathDisplay(WINDOW wnd) 183 | { 184 | CTLWINDOW *ct = FindCommand(wnd->extension, ID_PATH,TEXT); 185 | if (ct != NULL) { 186 | int len; 187 | WINDOW lwnd = ct->wnd; 188 | CreatePath(path, "*.*", FALSE, FALSE); 189 | len = strlen(path); 190 | if (len > 3) 191 | path[len-1] = '\0'; 192 | SendMessage(lwnd,SETTEXT,(PARAM)path,0); 193 | SendMessage(lwnd, PAINT, 0, 0); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /editor.c: -------------------------------------------------------------------------------- 1 | /* ------------- editor.c ------------ */ 2 | #include "dflat.h" 3 | 4 | #define pTab ('\t' + 0x80) 5 | #define sTab ('\f' + 0x80) 6 | 7 | /* ---------- SETTEXT Message ------------ */ 8 | static int SetTextMsg(WINDOW wnd, char *Buf) 9 | { 10 | unsigned char *tp, *ep, *ttp; 11 | int x = 0; 12 | int sz = 0; 13 | int rtn; 14 | 15 | tp = Buf; 16 | /* --- compute the buffer size based on tabs in the text --- */ 17 | while (*tp) { 18 | if (*tp == '\t') { 19 | /* --- tab, adjust the buffer length --- */ 20 | int sps = cfg.Tabs - (x % cfg.Tabs); 21 | sz += sps; 22 | x += sps; 23 | } 24 | else { 25 | /* --- not a tab, count the character --- */ 26 | sz++; 27 | x++; 28 | } 29 | if (*tp == '\n') 30 | x = 0; /* newline, reset x --- */ 31 | tp++; 32 | } 33 | /* --- allocate a buffer --- */ 34 | ep = DFcalloc(1, sz+1); 35 | /* --- detab the input file --- */ 36 | tp = Buf; 37 | ttp = ep; 38 | x = 0; 39 | while (*tp) { 40 | /* --- put the character (\t, too) into the buffer --- */ 41 | x++; 42 | /* --- expand tab into subst tab (\f + 0x80) 43 | and expansions (\t + 0x80) --- */ 44 | if (*tp == '\t') { 45 | *ttp++ = sTab; /* --- substitute tab character --- */ 46 | while ((x % cfg.Tabs) != 0) 47 | *ttp++ = pTab, x++; 48 | } 49 | else { 50 | *ttp++ = *tp; 51 | if (*tp == '\n') 52 | x = 0; 53 | } 54 | tp++; 55 | } 56 | *ttp = '\0'; 57 | rtn = BaseWndProc(EDITOR, wnd, SETTEXT, (PARAM) ep, 0); 58 | free(ep); 59 | return rtn; 60 | } 61 | void CollapseTabs(WINDOW wnd) 62 | { 63 | unsigned char *cp = wnd->text, *cp2; 64 | while (*cp) { 65 | if (*cp == sTab) { 66 | *cp = '\t'; 67 | cp2 = cp; 68 | while (*++cp2 == pTab) 69 | ; 70 | memmove(cp+1, cp2, strlen(cp2)+1); 71 | } 72 | cp++; 73 | } 74 | } 75 | 76 | void ExpandTabs(WINDOW wnd) 77 | { 78 | int Holdwtop = wnd->wtop; 79 | int Holdwleft = wnd->wleft; 80 | int HoldRow = wnd->CurrLine; 81 | int HoldCol = wnd->CurrCol; 82 | int HoldwRow = wnd->WndRow; 83 | SendMessage(wnd, SETTEXT, (PARAM) wnd->text, 0); 84 | wnd->wtop = Holdwtop; 85 | wnd->wleft = Holdwleft; 86 | wnd->CurrLine = HoldRow; 87 | wnd->CurrCol = HoldCol; 88 | wnd->WndRow = HoldwRow; 89 | SendMessage(wnd, PAINT, 0, 0); 90 | SendMessage(wnd, KEYBOARD_CURSOR, 0, wnd->WndRow); 91 | } 92 | 93 | /* --- When inserting or deleting, adjust next following tab, same line --- */ 94 | static void AdjustTab(WINDOW wnd) 95 | { 96 | /* ---- test if there is a tab beyond this character ---- */ 97 | int col = wnd->CurrCol; 98 | while (*CurrChar && *CurrChar != '\n') { 99 | if (*CurrChar == sTab) { 100 | int exp = (cfg.Tabs - 1) - (wnd->CurrCol % cfg.Tabs); 101 | wnd->CurrCol++; 102 | while (*CurrChar == pTab) 103 | BaseWndProc(EDITOR, wnd, KEYBOARD, DEL, 0); 104 | while (exp--) 105 | BaseWndProc(EDITOR, wnd, KEYBOARD, pTab, 0); 106 | break; 107 | } 108 | wnd->CurrCol++; 109 | } 110 | wnd->CurrCol = col; 111 | } 112 | 113 | static void TurnOffDisplay(WINDOW wnd) 114 | { 115 | SendMessage(NULL, HIDE_CURSOR, 0, 0); 116 | ClearVisible(wnd); 117 | } 118 | 119 | static void TurnOnDisplay(WINDOW wnd) 120 | { 121 | SetVisible(wnd); 122 | SendMessage(NULL, SHOW_CURSOR, 0, 0); 123 | } 124 | 125 | static void RepaintLine(WINDOW wnd) 126 | { 127 | SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); 128 | WriteTextLine(wnd, NULL, wnd->CurrLine, FALSE); 129 | } 130 | 131 | /* --------- KEYBOARD Message ---------- */ 132 | static int KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2) 133 | { 134 | int c = (int) p1; 135 | BOOL delnl; 136 | PARAM pn = p1; 137 | if (WindowMoving || WindowSizing || ((int)p2 & ALTKEY)) 138 | return FALSE; 139 | switch (c) { 140 | case PGUP: 141 | case PGDN: 142 | case UP: 143 | case DN: 144 | pn = (PARAM) BS; 145 | case FWD: 146 | case BS: 147 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 148 | TurnOffDisplay(wnd); 149 | while (*CurrChar == pTab) 150 | BaseWndProc(EDITOR, wnd, KEYBOARD, pn, p2); 151 | TurnOnDisplay(wnd); 152 | return TRUE; 153 | case DEL: 154 | TurnOffDisplay(wnd); 155 | delnl = *CurrChar == '\n' || TextBlockMarked(wnd); 156 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 157 | while (*CurrChar == pTab) 158 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 159 | AdjustTab(wnd); 160 | TurnOnDisplay(wnd); 161 | RepaintLine(wnd); 162 | if (delnl) 163 | SendMessage(wnd, PAINT, 0, 0); 164 | return TRUE; 165 | case '\t': 166 | TurnOffDisplay(wnd); 167 | BaseWndProc(EDITOR, wnd, KEYBOARD, (PARAM) sTab, p2); 168 | while ((wnd->CurrCol % cfg.Tabs) != 0) 169 | BaseWndProc(EDITOR, wnd, KEYBOARD, pTab, p2); 170 | TurnOnDisplay(wnd); 171 | RepaintLine(wnd); 172 | return TRUE; 173 | default: 174 | if (((c & OFFSET) == 0) && (isprint(c) || c == '\r')) { 175 | TurnOffDisplay(wnd); 176 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 177 | AdjustTab(wnd); 178 | TurnOnDisplay(wnd); 179 | RepaintLine(wnd); 180 | if (c == '\r') 181 | SendMessage(wnd, PAINT, 0, 0); 182 | return TRUE; 183 | } 184 | break; 185 | } 186 | return FALSE; 187 | } 188 | 189 | /* ------- Window processing module for EDITBOX class ------ */ 190 | int EditorProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 191 | { 192 | switch (msg) { 193 | case KEYBOARD: 194 | if (KeyboardMsg(wnd, p1, p2)) 195 | return TRUE; 196 | break; 197 | case SETTEXT: 198 | return SetTextMsg(wnd, (char *) p1); 199 | default: 200 | break; 201 | } 202 | return BaseWndProc(EDITOR, wnd, msg, p1, p2); 203 | } 204 | -------------------------------------------------------------------------------- /fileopen.c: -------------------------------------------------------------------------------- 1 | /* ----------- fileopen.c ------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | static BOOL DlgFileOpen(char *, char *, char *, DBOX *); 6 | static int DlgFnOpen(WINDOW, MESSAGE, PARAM, PARAM); 7 | static void InitDlgBox(WINDOW); 8 | static void StripPath(char *); 9 | static BOOL IncompleteFilename(char *); 10 | 11 | static char FileSpec[15]; 12 | static char SrchSpec[15]; 13 | static char FileName[15]; 14 | 15 | extern DBOX FileOpen; 16 | extern DBOX SaveAs; 17 | 18 | /* 19 | * Dialog Box to select a file to open 20 | */ 21 | BOOL OpenFileDialogBox(char *Fspec, char *Fname) 22 | { 23 | return DlgFileOpen(Fspec, Fspec, Fname, &FileOpen); 24 | } 25 | 26 | /* 27 | * Dialog Box to select a file to save as 28 | */ 29 | BOOL SaveAsDialogBox(char *Fspec, char *Sspec, char *Fname) 30 | { 31 | return DlgFileOpen(Fspec, Sspec ? Sspec : Fspec, Fname, &SaveAs); 32 | } 33 | 34 | /* --------- generic file open ---------- */ 35 | static BOOL DlgFileOpen(char *Fspec, char *Sspec, char *Fname, DBOX *db) 36 | { 37 | BOOL rtn; 38 | 39 | strncpy(FileSpec, Fspec, 15); 40 | strncpy(SrchSpec, Sspec, 15); 41 | 42 | if ((rtn = DialogBox(NULL, db, TRUE, DlgFnOpen)) != FALSE) 43 | strcpy(Fname, FileName); 44 | 45 | return rtn; 46 | } 47 | 48 | /* 49 | * Process dialog box messages 50 | */ 51 | static int DlgFnOpen(WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2) 52 | { 53 | switch (msg) { 54 | case CREATE_WINDOW: { 55 | int rtn = DefaultWndProc(wnd, msg, p1, p2); 56 | DBOX *db = wnd->extension; 57 | WINDOW cwnd = ControlWindow(db, ID_FILENAME); 58 | SendMessage(cwnd, SETTEXTLENGTH, 64, 0); 59 | return rtn; 60 | } 61 | case INITIATE_DIALOG: 62 | InitDlgBox(wnd); 63 | break; 64 | case COMMAND: 65 | switch ((int) p1) { 66 | case ID_OK: 67 | { 68 | if ((int)p2 == 0) { 69 | char fn[MAXPATH+1]; 70 | char nm[MAXFILE]; 71 | char ext[MAXEXT]; 72 | GetItemText(wnd, ID_FILENAME, fn, MAXPATH); 73 | fnsplit(fn, NULL, NULL, nm, ext); 74 | strcpy(FileName, nm); 75 | strcat(FileName, ext); 76 | CreatePath(NULL, fn, FALSE, TRUE); 77 | if (IncompleteFilename(FileName)) { 78 | /* --- no file name yet --- */ 79 | DBOX *db = wnd->extension; 80 | WINDOW cwnd = ControlWindow(db, ID_FILENAME); 81 | strcpy(FileSpec, FileName); 82 | strcpy(SrchSpec, FileName); 83 | InitDlgBox(wnd); 84 | SendMessage(cwnd, SETFOCUS, TRUE, 0); 85 | return TRUE; 86 | } 87 | } 88 | break; 89 | } 90 | case ID_FILES: 91 | switch ((int) p2) { 92 | case ENTERFOCUS: 93 | case LB_SELECTION: 94 | /* selected a different filename */ 95 | GetDlgListText(wnd, FileName, ID_FILES); 96 | PutItemText(wnd, ID_FILENAME, FileName); 97 | break; 98 | case LB_CHOOSE: 99 | /* chose a file name */ 100 | GetDlgListText(wnd, FileName, ID_FILES); 101 | SendMessage(wnd, COMMAND, ID_OK, 0); 102 | break; 103 | default: 104 | break; 105 | } 106 | return TRUE; 107 | case ID_DIRECTORY: 108 | switch ((int) p2) { 109 | case ENTERFOCUS: 110 | PutItemText(wnd, ID_FILENAME, FileSpec); 111 | break; 112 | case LB_CHOOSE: 113 | { 114 | /* chose dir */ 115 | char dd[15]; 116 | GetDlgListText(wnd, dd, ID_DIRECTORY); 117 | chdir(dd); 118 | InitDlgBox(wnd); 119 | SendMessage(wnd, COMMAND, ID_OK, 0); 120 | break; 121 | } 122 | default: 123 | break; 124 | } 125 | return TRUE; 126 | 127 | case ID_DRIVE: 128 | switch ((int) p2) { 129 | case ENTERFOCUS: 130 | PutItemText(wnd, ID_FILENAME, FileSpec); 131 | break; 132 | case LB_CHOOSE: 133 | { 134 | /* chose dir */ 135 | char dr[15]; 136 | GetDlgListText(wnd, dr, ID_DRIVE); 137 | setdisk(*dr - 'A'); 138 | InitDlgBox(wnd); 139 | SendMessage(wnd, COMMAND, ID_OK, 0); 140 | } 141 | default: 142 | break; 143 | } 144 | return TRUE; 145 | 146 | default: 147 | break; 148 | } 149 | default: 150 | break; 151 | } 152 | return DefaultWndProc(wnd, msg, p1, p2); 153 | } 154 | 155 | BOOL BuildFileList(WINDOW, char *); 156 | void BuildDirectoryList(WINDOW); 157 | void BuildDriveList(WINDOW); 158 | void BuildPathDisplay(WINDOW); 159 | 160 | /* 161 | * Initialize the dialog box 162 | */ 163 | static void InitDlgBox(WINDOW wnd) 164 | { 165 | if (*FileSpec) 166 | PutItemText(wnd, ID_FILENAME, FileSpec); 167 | if (BuildFileList(wnd, SrchSpec)) 168 | BuildDirectoryList(wnd); 169 | BuildDriveList(wnd); 170 | BuildPathDisplay(wnd); 171 | } 172 | 173 | /* 174 | * Strip the drive and path information from a file spec 175 | */ 176 | static void StripPath(char *filespec) 177 | { 178 | char *cp, *cp1; 179 | 180 | cp = strchr(filespec, ':'); 181 | if (cp != NULL) 182 | cp++; 183 | else 184 | cp = filespec; 185 | while (TRUE) { 186 | cp1 = strchr(cp, '\\'); 187 | if (cp1 == NULL) 188 | break; 189 | cp = cp1+1; 190 | } 191 | strcpy(filespec, cp); 192 | } 193 | 194 | 195 | static BOOL IncompleteFilename(char *s) 196 | { 197 | int lc = strlen(s)-1; 198 | if (strchr(s, '?') || strchr(s, '*') || !*s) 199 | return TRUE; 200 | if (*(s+lc) == ':' || *(s+lc) == '\\') 201 | return TRUE; 202 | return FALSE; 203 | } 204 | -------------------------------------------------------------------------------- /fixhelp.c: -------------------------------------------------------------------------------- 1 | /* ------ fixhelp.c ------ */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include "htree.h" 7 | #define FIXHELP 8 | #include "helpbox.h" 9 | 10 | /* max() and min() may come from */ 11 | #ifndef max 12 | #define max(a,b) (((a) > (b)) ? (a) : (b)) 13 | #endif 14 | 15 | static FILE *helpfp; 16 | static char hline [160]; 17 | 18 | static struct helps *FirstHelp; 19 | static struct helps *LastHelp; 20 | static struct helps *ThisHelp; 21 | static char **Argv; 22 | 23 | static void WriteText(char *); 24 | 25 | /* ---- compute the displayed length of a help text line --- */ 26 | static int HelpLength(char *s) 27 | { 28 | int len = strlen(s); 29 | char *cp = strchr(s, '['); 30 | while (cp != NULL) { 31 | len -= 4; 32 | cp = strchr(cp+1, '['); 33 | } 34 | cp = strchr(s, '<'); 35 | while (cp != NULL) { 36 | char *cp1 = strchr(cp, '>'); 37 | if (cp1 != NULL) 38 | len -= (int) (cp1-cp)+1; 39 | cp = strchr(cp1, '<'); 40 | } 41 | return len; 42 | } 43 | 44 | int FindHelp(char *nm) 45 | { 46 | int hlp = 0; 47 | struct helps *thishelp = FirstHelp; 48 | if (nm == NULL) { 49 | return -1; 50 | } 51 | while (thishelp != NULL) { 52 | if (strcmp(nm, thishelp->hname) == 0) 53 | break; 54 | hlp++; 55 | thishelp = thishelp->NextHelp; 56 | } 57 | return thishelp ? hlp : -1; 58 | } 59 | 60 | int main(int argc, char *argv[]) 61 | { 62 | char *cp; 63 | int HelpCount = 0; 64 | long where; 65 | 66 | if (argc < 2) 67 | return -1; 68 | Argv = argv; 69 | if ((helpfp = OpenHelpFile(argv[1], "r+b")) == NULL) 70 | return -1; 71 | 72 | 73 | *hline = '\0'; 74 | while (*hline != '<') { 75 | if (GetHelpLine(hline) == NULL) { 76 | fclose(helpfp); 77 | return -1; 78 | } 79 | } 80 | while (*hline == '<') { 81 | if (strncmp(hline, "", 5) == 0) 82 | break; 83 | 84 | /* -------- parse the help window's text name ----- */ 85 | if ((cp = strchr(hline, '>')) != NULL) { 86 | ThisHelp = calloc(1, sizeof(struct helps)); 87 | if (FirstHelp == NULL) 88 | FirstHelp = ThisHelp; 89 | *cp = '\0'; 90 | ThisHelp->hname=malloc(strlen(hline+1)+1); 91 | strcpy(ThisHelp->hname, hline+1); 92 | 93 | HelpFilePosition(&ThisHelp->hptr, &ThisHelp->bit); 94 | 95 | if (GetHelpLine(hline) == NULL) 96 | break; 97 | 98 | /* ------- build the help linked list entry --- */ 99 | while (*hline == '[') { 100 | HelpFilePosition(&ThisHelp->hptr, 101 | &ThisHelp->bit); 102 | /* ------ parse a comment ----- */ 103 | if (strncmp(hline, "[*]", 3) == 0) { 104 | ThisHelp->comment=malloc(strlen(hline+3)+1); 105 | strcpy(ThisHelp->comment, hline+3); 106 | if (GetHelpLine(hline) == NULL) 107 | break; 108 | continue; 109 | } 110 | /* ---- parse the <'); 115 | if (cp1 != NULL) { 116 | int len = (int) (cp1-cp); 117 | ThisHelp->PrevName=calloc(1,len); 118 | strncpy(ThisHelp->PrevName, 119 | cp+1,len-1); 120 | } 121 | } 122 | if (GetHelpLine(hline) == NULL) 123 | break; 124 | continue; 125 | } 126 | /* ---- parse the next>> button pointer ---- */ 127 | else if (strncmp(hline, "[>>]", 4) == 0) { 128 | char *cp = strchr(hline+4, '<'); 129 | if (cp != NULL) { 130 | char *cp1 = strchr(cp, '>'); 131 | if (cp1 != NULL) { 132 | int len = (int) (cp1-cp); 133 | ThisHelp->NextName=calloc(1,len); 134 | strncpy(ThisHelp->NextName, 135 | cp+1,len-1); 136 | } 137 | } 138 | if (GetHelpLine(hline) == NULL) 139 | break; 140 | continue; 141 | } 142 | else 143 | break; 144 | } 145 | ThisHelp->hheight = 0; 146 | ThisHelp->hwidth = 0; 147 | ThisHelp->NextHelp = NULL; 148 | 149 | /* ------ append entry to the linked list ------ */ 150 | if (LastHelp != NULL) 151 | LastHelp->NextHelp = ThisHelp; 152 | LastHelp = ThisHelp; 153 | HelpCount++; 154 | } 155 | /* -------- move to the next token ------ */ 156 | if (GetHelpLine(hline) == NULL) 157 | strcpy(hline, ""); 158 | while (*hline != '<') { 159 | ThisHelp->hwidth = 160 | max(ThisHelp->hwidth, HelpLength(hline)); 161 | ThisHelp->hheight++; 162 | if (GetHelpLine(hline) == NULL) 163 | strcpy(hline, ""); 164 | } 165 | } 166 | /* --- append the help structures to the file --- */ 167 | fseek(helpfp, 0L, SEEK_END); 168 | where = ftell(helpfp); 169 | ThisHelp = FirstHelp; 170 | fwrite(&HelpCount, sizeof(int), 1, helpfp); 171 | while (ThisHelp != NULL) { 172 | ThisHelp->nexthlp = FindHelp(ThisHelp->NextName); 173 | ThisHelp->prevhlp = FindHelp(ThisHelp->PrevName); 174 | WriteText(ThisHelp->hname); 175 | WriteText(ThisHelp->comment); 176 | fwrite(&ThisHelp->hptr, sizeof(int)*5+sizeof(long), 1, helpfp); 177 | ThisHelp = ThisHelp->NextHelp; 178 | } 179 | fwrite(&where, sizeof(long), 1, helpfp); 180 | fclose(helpfp); 181 | return 0; 182 | } 183 | 184 | void BuildFileName(char *fn, const char *fname, const char *ext) 185 | { 186 | strcpy(fn, Argv[1]); 187 | strcat(fn, ext); 188 | } 189 | 190 | static void WriteText(char *text) 191 | { 192 | char *np = text ? text : ""; 193 | int len = strlen(np); 194 | fwrite(&len, sizeof(int), 1, helpfp); 195 | if (len) 196 | fwrite(np, len+1, 1, helpfp); 197 | } 198 | -------------------------------------------------------------------------------- /helpbox.h: -------------------------------------------------------------------------------- 1 | /* --------- helpbox.h ----------- */ 2 | 3 | #ifndef HELPBOX_H 4 | #define HELPBOX_H 5 | 6 | /* --------- linked list of help text collections -------- */ 7 | struct helps { 8 | char *hname; 9 | char *comment; 10 | long hptr; 11 | int bit; 12 | int hheight; 13 | int hwidth; 14 | int nexthlp; 15 | int prevhlp; 16 | void *hwnd; 17 | char *PrevName; 18 | char *NextName; 19 | #ifdef FIXHELP 20 | struct helps *NextHelp; 21 | #endif 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /htree.c: -------------------------------------------------------------------------------- 1 | /* ------------------- htree.c -------------------- */ 2 | 3 | #include "dflat.h" 4 | #include "htree.h" 5 | 6 | struct htree *ht; 7 | int root; 8 | int treect; 9 | 10 | /* ------ build a Huffman tree from a frequency array ------ */ 11 | void buildtree(void) 12 | { 13 | int i; 14 | 15 | treect = 256; 16 | /* ---- preset node pointers to -1 ---- */ 17 | for (i = 0; i < treect; i++) { 18 | ht[i].parent = -1; 19 | ht[i].right = -1; 20 | ht[i].left = -1; 21 | } 22 | /* ---- build the huffman tree ----- */ 23 | while (1) { 24 | int h1 = -1, h2 = -1; 25 | /* ---- find the two lowest frequencies ---- */ 26 | for (i = 0; i < treect; i++) { 27 | if (i != h1) { 28 | struct htree *htt = ht+i; 29 | /* --- find a node without a parent --- */ 30 | if (htt->cnt > 0 && htt->parent == -1) { 31 | /* ---- h1 & h2 -> lowest nodes ---- */ 32 | if (h1 == -1 || htt->cnt < ht[h1].cnt) { 33 | if (h2 == -1 || ht[h1].cnt < ht[h2].cnt) 34 | h2 = h1; 35 | h1 = i; 36 | } 37 | else if (h2 == -1 || htt->cnt < ht[h2].cnt) 38 | h2 = i; 39 | } 40 | } 41 | } 42 | /* --- if only h1 -> a node, that's the root --- */ 43 | if (h2 == -1) { 44 | root = h1; 45 | break; 46 | } 47 | /* --- combine two nodes and add one --- */ 48 | ht[h1].parent = treect; 49 | ht[h2].parent = treect; 50 | ht = realloc(ht, (treect+1) * sizeof(struct htree)); 51 | if (ht == NULL) 52 | break; 53 | /* --- the new node's frequency is the sum of the two 54 | nodes with the lowest frequencies --- */ 55 | ht[treect].cnt = ht[h1].cnt + ht[h2].cnt; 56 | /* - the new node points to the two that it combines */ 57 | ht[treect].right = h1; 58 | ht[treect].left = h2; 59 | /* --- the new node has no parent (yet) --- */ 60 | ht[treect].parent = -1; 61 | treect++; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /htree.h: -------------------------------------------------------------------------------- 1 | /* ------------------- htree.h -------------------- */ 2 | 3 | #ifndef HTREE_H 4 | #define HTREE_H 5 | 6 | typedef unsigned int BYTECOUNTER; 7 | 8 | /* ---- Huffman tree structure for building ---- */ 9 | struct htree { 10 | BYTECOUNTER cnt; /* character frequency */ 11 | int parent; /* offset to parent node */ 12 | int right; /* offset to right child node */ 13 | int left; /* offset to left child node */ 14 | }; 15 | 16 | /* ---- Huffman tree structure in compressed file ---- */ 17 | struct htr { 18 | int right; /* offset to right child node */ 19 | int left; /* offset to left child node */ 20 | }; 21 | 22 | extern struct htr *HelpTree; 23 | 24 | void buildtree(void); 25 | FILE *OpenHelpFile(const char *fn, const char *md); 26 | void HelpFilePosition(long *, int *); 27 | void *GetHelpLine(char *); 28 | void SeekHelpLine(long, int); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /huffc.c: -------------------------------------------------------------------------------- 1 | /* ------------------- huffc.c -------------------- */ 2 | 3 | #include "dflat.h" 4 | #include "htree.h" 5 | 6 | extern struct htree *ht; 7 | extern int root; 8 | extern int treect; 9 | static int lastchar = '\n'; 10 | 11 | static void compress(FILE *, int, int); 12 | static void outbit(FILE *fo, int bit); 13 | 14 | static int fgetcx(FILE *fi) 15 | { 16 | int c; 17 | 18 | /* ------- bypass comments ------- */ 19 | if ((c = fgetc(fi)) == ';' && lastchar == '\n') 20 | do { 21 | while (c != '\n' && c != EOF) 22 | c = fgetc(fi); 23 | } while (c == ';'); 24 | lastchar = c; 25 | return c; 26 | } 27 | 28 | void main(int argc, char *argv[]) 29 | { 30 | FILE *fi, *fo; 31 | int c; 32 | BYTECOUNTER bytectr = 0; 33 | 34 | if (argc < 3) { 35 | printf("\nusage: huffc infile outfile"); 36 | exit(1); 37 | } 38 | 39 | if ((fi = fopen(argv[1], "rb")) == NULL) { 40 | printf("\nCannot open %s", argv[1]); 41 | exit(1); 42 | } 43 | if ((fo = fopen(argv[2], "wb")) == NULL) { 44 | printf("\nCannot open %s", argv[2]); 45 | fclose(fi); 46 | exit(1); 47 | } 48 | 49 | ht = calloc(256, sizeof(struct htree)); 50 | 51 | /* - read the input file and count character frequency - */ 52 | while ((c = fgetcx(fi)) != EOF) { 53 | c &= 255; 54 | ht[c].cnt++; 55 | bytectr++; 56 | } 57 | 58 | /* ---- build the huffman tree ---- */ 59 | buildtree(); 60 | 61 | /* --- write the byte count to the output file --- */ 62 | fwrite(&bytectr, sizeof bytectr, 1, fo); 63 | 64 | /* --- write the tree count to the output file --- */ 65 | fwrite(&treect, sizeof treect, 1, fo); 66 | 67 | /* --- write the root offset to the output file --- */ 68 | fwrite(&root, sizeof root, 1, fo); 69 | 70 | /* -- write the tree to the output file -- */ 71 | for (c = 256; c < treect; c++) { 72 | int lf = ht[c].left; 73 | int rt = ht[c].right; 74 | fwrite(&lf, sizeof lf, 1, fo); 75 | fwrite(&rt, sizeof rt, 1, fo); 76 | } 77 | 78 | /* ------ compress the file ------ */ 79 | fseek(fi, 0L, 0); 80 | while ((c = fgetcx(fi)) != EOF) 81 | compress(fo, (c & 255), 0); 82 | outbit(fo, -1); 83 | fclose(fi); 84 | fclose(fo); 85 | free(ht); 86 | exit(0); 87 | } 88 | 89 | /* ---- compress a character value into a bit stream ---- */ 90 | static void compress(FILE *fo, int h, int child) 91 | { 92 | if (ht[h].parent != -1) 93 | compress(fo, ht[h].parent, h); 94 | if (child) { 95 | if (child == ht[h].right) 96 | outbit(fo, 0); 97 | else if (child == ht[h].left) 98 | outbit(fo, 1); 99 | } 100 | } 101 | 102 | static char out8; 103 | static int ct8; 104 | 105 | /* -- collect and write bits to the compressed output file -- */ 106 | static void outbit(FILE *fo, int bit) 107 | { 108 | if (ct8 == 8 || bit == -1) { 109 | while (ct8 < 8) { 110 | out8 <<= 1; 111 | ct8++; 112 | } 113 | fputc(out8, fo); 114 | ct8 = 0; 115 | } 116 | out8 = (out8 << 1) | bit; 117 | ct8++; 118 | } 119 | -------------------------------------------------------------------------------- /keys.c: -------------------------------------------------------------------------------- 1 | /* ------------- keys.c ----------- */ 2 | 3 | #include 4 | #include "keys.h" 5 | 6 | struct keys keys[] = { 7 | {F1, "F1"}, 8 | {F2, "F2"}, 9 | {F3, "F3"}, 10 | {F4, "F4"}, 11 | {F5, "F5"}, 12 | {F6, "F6"}, 13 | {F7, "F7"}, 14 | {F8, "F8"}, 15 | {F9, "F9"}, 16 | {F10, "F10"}, 17 | {CTRL_F1, "Ctrl+F1"}, 18 | {CTRL_F2, "Ctrl+F2"}, 19 | {CTRL_F3, "Ctrl+F3"}, 20 | {CTRL_F4, "Ctrl+F4"}, 21 | {CTRL_F5, "Ctrl+F5"}, 22 | {CTRL_F6, "Ctrl+F6"}, 23 | {CTRL_F7, "Ctrl+F7"}, 24 | {CTRL_F8, "Ctrl+F8"}, 25 | {CTRL_F9, "Ctrl+F9"}, 26 | {CTRL_F10, "Ctrl+F10"}, 27 | {ALT_F1, "Alt+F1"}, 28 | {ALT_F2, "Alt+F2"}, 29 | {ALT_F3, "Alt+F3"}, 30 | {ALT_F4, "Alt+F4"}, 31 | {ALT_F5, "Alt+F5"}, 32 | {ALT_F6, "Alt+F6"}, 33 | {ALT_F7, "Alt+F7"}, 34 | {ALT_F8, "Alt+F8"}, 35 | {ALT_F9, "Alt+F9"}, 36 | {ALT_F10, "Alt+F10"}, 37 | {HOME, "Home"}, 38 | {UP, "Up"}, 39 | {PGUP, "PgUp"}, 40 | {BS, "BS"}, 41 | {END, "End"}, 42 | {DN, "Dn"}, 43 | {PGDN, "PgDn"}, 44 | {INS, "Ins"}, 45 | {DEL, "Del"}, 46 | {CTRL_HOME, "Ctrl+Home"}, 47 | {CTRL_PGUP, "Ctrl+PgUp"}, 48 | {CTRL_BS, "Ctrl+BS"}, 49 | {CTRL_END, "Ctrl+End"}, 50 | {CTRL_PGDN, "Ctrl+PgDn"}, 51 | {SHIFT_HT, "Shift+Tab"}, 52 | {ALT_BS, "Alt+BS"}, 53 | {ALT_DEL, "Alt+Del"}, 54 | {SHIFT_DEL, "Shift+Del"}, 55 | {SHIFT_INS, "Shift+Ins"}, 56 | {CTRL_INS, "Ctrl+Ins"}, 57 | {ALT_A, "Alt+A"}, 58 | {ALT_B, "Alt+B"}, 59 | {ALT_C, "Alt+C"}, 60 | {ALT_D, "Alt+D"}, 61 | {ALT_E, "Alt+E"}, 62 | {ALT_F, "Alt+F"}, 63 | {ALT_G, "Alt+G"}, 64 | {ALT_H, "Alt+H"}, 65 | {ALT_I, "Alt+I"}, 66 | {ALT_J, "Alt+J"}, 67 | {ALT_K, "Alt+K"}, 68 | {ALT_L, "Alt+L"}, 69 | {ALT_M, "Alt+M"}, 70 | {ALT_N, "Alt+N"}, 71 | {ALT_O, "Alt+O"}, 72 | {ALT_P, "Alt+P"}, 73 | {ALT_Q, "Alt+Q"}, 74 | {ALT_R, "Alt+R"}, 75 | {ALT_S, "Alt+S"}, 76 | {ALT_T, "Alt+T"}, 77 | {ALT_U, "Alt+U"}, 78 | {ALT_V, "Alt+V"}, 79 | {ALT_W, "Alt+W"}, 80 | {ALT_X, "Alt+X"}, 81 | {ALT_Y, "Alt+Y"}, 82 | {ALT_Z, "Alt+Z"}, 83 | {-1, NULL} 84 | }; 85 | -------------------------------------------------------------------------------- /keys.h: -------------------------------------------------------------------------------- 1 | /* ----------- keys.h ------------ */ 2 | 3 | #ifndef KEYS_H 4 | #define KEYS_H 5 | 6 | #define OFFSET 0x1000 7 | 8 | #define RUBOUT 8 9 | #define BELL 7 10 | #define ESC 27 11 | #define ALT_BS (197+OFFSET) 12 | #define ALT_DEL (184+OFFSET) 13 | #define SHIFT_DEL (198+OFFSET) 14 | #define CTRL_INS (186+OFFSET) 15 | #define SHIFT_INS (185+OFFSET) 16 | #define SHIFT_F8 (219+OFFSET) 17 | #define F1 (187+OFFSET) 18 | #define F2 (188+OFFSET) 19 | #define F3 (189+OFFSET) 20 | #define F4 (190+OFFSET) 21 | #define F5 (191+OFFSET) 22 | #define F6 (192+OFFSET) 23 | #define F7 (193+OFFSET) 24 | #define F8 (194+OFFSET) 25 | #define F9 (195+OFFSET) 26 | #define F10 (196+OFFSET) 27 | #define CTRL_F1 (222+OFFSET) 28 | #define CTRL_F2 (223+OFFSET) 29 | #define CTRL_F3 (224+OFFSET) 30 | #define CTRL_F4 (225+OFFSET) 31 | #define CTRL_F5 (226+OFFSET) 32 | #define CTRL_F6 (227+OFFSET) 33 | #define CTRL_F7 (228+OFFSET) 34 | #define CTRL_F8 (229+OFFSET) 35 | #define CTRL_F9 (230+OFFSET) 36 | #define CTRL_F10 (231+OFFSET) 37 | #define ALT_F1 (232+OFFSET) 38 | #define ALT_F2 (233+OFFSET) 39 | #define ALT_F3 (234+OFFSET) 40 | #define ALT_F4 (235+OFFSET) 41 | #define ALT_F5 (236+OFFSET) 42 | #define ALT_F6 (237+OFFSET) 43 | #define ALT_F7 (238+OFFSET) 44 | #define ALT_F8 (239+OFFSET) 45 | #define ALT_F9 (240+OFFSET) 46 | #define ALT_F10 (241+OFFSET) 47 | #define HOME (199+OFFSET) 48 | #define UP (200+OFFSET) 49 | #define PGUP (201+OFFSET) 50 | #define BS (203+OFFSET) 51 | #define FWD (205+OFFSET) 52 | #define END (207+OFFSET) 53 | #define DN (208+OFFSET) 54 | #define PGDN (209+OFFSET) 55 | #define INS (210+OFFSET) 56 | #define DEL (211+OFFSET) 57 | #define CTRL_HOME (247+OFFSET) 58 | #define CTRL_PGUP (132+OFFSET) 59 | #define CTRL_BS (243+OFFSET) 60 | #define CTRL_FIVE (143+OFFSET) 61 | #define CTRL_FWD (244+OFFSET) 62 | #define CTRL_END (245+OFFSET) 63 | #define CTRL_PGDN (246+OFFSET) 64 | #define SHIFT_HT (143+OFFSET) 65 | #define ALT_A (158+OFFSET) 66 | #define ALT_B (176+OFFSET) 67 | #define ALT_C (174+OFFSET) 68 | #define ALT_D (160+OFFSET) 69 | #define ALT_E (146+OFFSET) 70 | #define ALT_F (161+OFFSET) 71 | #define ALT_G (162+OFFSET) 72 | #define ALT_H (163+OFFSET) 73 | #define ALT_I (151+OFFSET) 74 | #define ALT_J (164+OFFSET) 75 | #define ALT_K (165+OFFSET) 76 | #define ALT_L (166+OFFSET) 77 | #define ALT_M (178+OFFSET) 78 | #define ALT_N (177+OFFSET) 79 | #define ALT_O (152+OFFSET) 80 | #define ALT_P (153+OFFSET) 81 | #define ALT_Q (144+OFFSET) 82 | #define ALT_R (147+OFFSET) 83 | #define ALT_S (159+OFFSET) 84 | #define ALT_T (148+OFFSET) 85 | #define ALT_U (150+OFFSET) 86 | #define ALT_V (175+OFFSET) 87 | #define ALT_W (145+OFFSET) 88 | #define ALT_X (173+OFFSET) 89 | #define ALT_Y (149+OFFSET) 90 | #define ALT_Z (172+OFFSET) 91 | #define ALT_1 (0xf8+OFFSET) 92 | #define ALT_2 (0xf9+OFFSET) 93 | #define ALT_3 (0xfa+OFFSET) 94 | #define ALT_4 (0xfb+OFFSET) 95 | #define ALT_5 (0xfc+OFFSET) 96 | #define ALT_6 (0xfd+OFFSET) 97 | #define ALT_7 (0xfe +OFFSET) 98 | #define ALT_8 (0xff+OFFSET) 99 | #define ALT_9 (0x80+OFFSET) 100 | #define ALT_0 (0x81+OFFSET) 101 | #define ALT_HYPHEN (130+OFFSET) 102 | 103 | #define RIGHTSHIFT 0x01 104 | #define LEFTSHIFT 0x02 105 | #define CTRLKEY 0x04 106 | #define ALTKEY 0x08 107 | #define SCROLLLOCK 0x10 108 | #define NUMLOCK 0x20 109 | #define CAPSLOCK 0x40 110 | #define INSERTKEY 0x80 111 | 112 | #define CTRL_A 1 113 | #define CTRL_B 2 114 | #define CTRL_C 3 115 | #define CTRL_D 4 116 | #define CTRL_E 5 117 | #define CTRL_F 6 118 | #define CTRL_G 7 119 | #define CTRL_H 8 120 | #define CTRL_I 9 121 | #define CTRL_J 10 122 | #define CTRL_K 11 123 | #define CTRL_L 12 124 | #define CTRL_M 13 125 | #define CTRL_N 14 126 | #define CTRL_O 15 127 | #define CTRL_P 16 128 | #define CTRL_Q 17 129 | #define CTRL_R 18 130 | #define CTRL_S 19 131 | #define CTRL_T 20 132 | #define CTRL_U 21 133 | #define CTRL_V 22 134 | #define CTRL_W 23 135 | #define CTRL_X 24 136 | #define CTRL_Y 25 137 | #define CTRL_Z 26 138 | 139 | struct keys { 140 | int keycode; 141 | char *keylabel; 142 | }; 143 | extern struct keys keys[]; 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | D-Flat Windowing System Version 20 2 | 3 | by Al Stevens 4 | 5 | This is public domain code. You may use it in your applications 6 | without restriction. You may freely distribute source code. It 7 | would be nice if you would give credit to Dr. Dobb's Journal as 8 | the original publisher of the source code. 9 | 10 | (extracted from readme.doc) 11 | -------------------------------------------------------------------------------- /lists.c: -------------------------------------------------------------------------------- 1 | /* --------------- lists.c -------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | /* ----- set focus to the next sibling ----- */ 6 | void SetNextFocus(void) 7 | { 8 | if (inFocus != NULL) { 9 | WINDOW wnd1 = inFocus, pwnd; 10 | while (TRUE) { 11 | pwnd = GetParent(wnd1); 12 | if (NextWindow(wnd1) != NULL) 13 | wnd1 = NextWindow(wnd1); 14 | else if (pwnd != NULL) 15 | wnd1 = FirstWindow(pwnd); 16 | if (wnd1 == NULL || wnd1 == inFocus) { 17 | wnd1 = pwnd; 18 | break; 19 | } 20 | if (GetClass(wnd1) == STATUSBAR || GetClass(wnd1) == MENUBAR) 21 | continue; 22 | if (isVisible(wnd1)) 23 | break; 24 | } 25 | if (wnd1 != NULL) { 26 | while (wnd1->childfocus != NULL) 27 | wnd1 = wnd1->childfocus; 28 | if (wnd1->condition != ISCLOSING) 29 | SendMessage(wnd1, SETFOCUS, TRUE, 0); 30 | } 31 | } 32 | } 33 | 34 | /* ----- set focus to the previous sibling ----- */ 35 | void SetPrevFocus(void) 36 | { 37 | if (inFocus != NULL) { 38 | WINDOW wnd1 = inFocus, pwnd; 39 | while (TRUE) { 40 | pwnd = GetParent(wnd1); 41 | if (PrevWindow(wnd1) != NULL) 42 | wnd1 = PrevWindow(wnd1); 43 | else if (pwnd != NULL) 44 | wnd1 = LastWindow(pwnd); 45 | if (wnd1 == NULL || wnd1 == inFocus) { 46 | wnd1 = pwnd; 47 | break; 48 | } 49 | if (GetClass(wnd1) == STATUSBAR) 50 | continue; 51 | if (isVisible(wnd1)) 52 | break; 53 | } 54 | if (wnd1 != NULL) { 55 | while (wnd1->childfocus != NULL) 56 | wnd1 = wnd1->childfocus; 57 | if (wnd1->condition != ISCLOSING) 58 | SendMessage(wnd1, SETFOCUS, TRUE, 0); 59 | } 60 | } 61 | } 62 | 63 | /* ------- move a window to the end of its parents list ----- */ 64 | void ReFocus(WINDOW wnd) 65 | { 66 | if (GetParent(wnd) != NULL) { 67 | RemoveWindow(wnd); 68 | AppendWindow(wnd); 69 | ReFocus(GetParent(wnd)); 70 | } 71 | } 72 | 73 | /* ---- remove a window from the linked list ---- */ 74 | void RemoveWindow(WINDOW wnd) 75 | { 76 | if (wnd != NULL) { 77 | WINDOW pwnd = GetParent(wnd); 78 | if (PrevWindow(wnd) != NULL) 79 | NextWindow(PrevWindow(wnd)) = NextWindow(wnd); 80 | if (NextWindow(wnd) != NULL) 81 | PrevWindow(NextWindow(wnd)) = PrevWindow(wnd); 82 | if (pwnd != NULL) { 83 | if (wnd == FirstWindow(pwnd)) 84 | FirstWindow(pwnd) = NextWindow(wnd); 85 | if (wnd == LastWindow(pwnd)) 86 | LastWindow(pwnd) = PrevWindow(wnd); 87 | } 88 | } 89 | } 90 | 91 | /* ---- append a window to the linked list ---- */ 92 | void AppendWindow(WINDOW wnd) 93 | { 94 | if (wnd != NULL) { 95 | WINDOW pwnd = GetParent(wnd); 96 | if (pwnd != NULL) { 97 | if (FirstWindow(pwnd) == NULL) 98 | FirstWindow(pwnd) = wnd; 99 | if (LastWindow(pwnd) != NULL) 100 | NextWindow(LastWindow(pwnd)) = wnd; 101 | PrevWindow(wnd) = LastWindow(pwnd); 102 | LastWindow(pwnd) = wnd; 103 | } 104 | NextWindow(wnd) = NULL; 105 | } 106 | } 107 | 108 | /* ----- if document windows and statusbar or menubar get the focus, 109 | pass it on ------- */ 110 | void SkipApplicationControls(void) 111 | { 112 | BOOL EmptyAppl = FALSE; 113 | int ct = 0; 114 | while (!EmptyAppl && inFocus != NULL) { 115 | CLASS cl = GetClass(inFocus); 116 | if (cl == MENUBAR || cl == STATUSBAR) { 117 | SetPrevFocus(); 118 | EmptyAppl = (cl == MENUBAR && ct++); 119 | } 120 | else 121 | break; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /log.c: -------------------------------------------------------------------------------- 1 | /* ------------ log .c ------------ */ 2 | 3 | #include "dflat.h" 4 | 5 | #ifdef INCLUDE_LOGGING 6 | 7 | static char *message[] = { 8 | #undef DFlatMsg 9 | #define DFlatMsg(m) " " #m, 10 | #include "dflatmsg.h" 11 | NULL 12 | }; 13 | 14 | static FILE *log = NULL; 15 | extern DBOX Log; 16 | 17 | void LogMessages (WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 18 | { 19 | if (log != NULL && message[msg][0] != ' ') 20 | fprintf(log, 21 | "%-20.20s %-12.12s %-20.20s, %5.5ld, %5.5ld\n", 22 | wnd ? (GetTitle(wnd) ? GetTitle(wnd) : "") : "", 23 | wnd ? ClassNames[GetClass(wnd)] : "", 24 | message[msg]+1, p1, p2); 25 | } 26 | 27 | static int LogProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 28 | { 29 | WINDOW cwnd = ControlWindow(&Log, ID_LOGLIST); 30 | char **mn = message; 31 | switch (msg) { 32 | case INITIATE_DIALOG: 33 | AddAttribute(cwnd, MULTILINE | VSCROLLBAR); 34 | while (*mn) { 35 | SendMessage(cwnd, ADDTEXT, (PARAM) (*mn), 0); 36 | mn++; 37 | } 38 | SendMessage(cwnd, SHOW_WINDOW, 0, 0); 39 | break; 40 | case COMMAND: 41 | if ((int) p1 == ID_OK) { 42 | int item; 43 | int tl = GetTextLines(cwnd); 44 | for (item = 0; item < tl; item++) 45 | if (ItemSelected(cwnd, item)) 46 | mn[item][0] = LISTSELECTOR; 47 | } 48 | break; 49 | default: 50 | break; 51 | } 52 | return DefaultWndProc(wnd, msg, p1, p2); 53 | } 54 | 55 | void MessageLog(WINDOW wnd) 56 | { 57 | if (DialogBox(wnd, &Log, TRUE, LogProc)) { 58 | if (CheckBoxSetting(&Log, ID_LOGGING)) { 59 | log = fopen("DFLAT.LOG", "wt"); 60 | SetCommandToggle(&MainMenu, ID_LOG); 61 | } 62 | else if (log != NULL) { 63 | fclose(log); 64 | log = NULL; 65 | ClearCommandToggle(&MainMenu, ID_LOG); 66 | } 67 | } 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /makefile.bcc: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------- 2 | # D - F L A T M A K E F I L E - Borland C++ 3.1 and 4.0 3 | #------------------------------------------------------------------- 4 | 5 | all : memopad.exe memopad.hlp 6 | 7 | #------------------------------------------------ 8 | # NOTE: Set DRIVE to match where you installed your compiler 9 | #------------------------------------------------ 10 | DRIVE = d:\bc4 11 | #------------------------------------------------------------------- 12 | # Delete the TESTING macro to eliminate the Reload 13 | # Help file selection on the Help menu. 14 | #------------------------------------------------------------------- 15 | TESTING = TESTING_DFLAT 16 | #------------------------------------------------------------------- 17 | # This macro builds the full D-Flat system with all options enabled. 18 | # Comment it out for a minimum system or selectively 19 | # comment out the #defines at the top of dflat.h. 20 | #------------------------------------------------------------------- 21 | FULL = BUILD_FULL_DFLAT 22 | #------------------------------------------------------------------- 23 | 24 | MODEL = l 25 | #------------------------------------------------ 26 | # NOTE: Delete the DEBUG and LINKDEBUG macros to 27 | # build without debugging information in the .EXE 28 | #------------------------------------------------ 29 | DEBUG = -v 30 | LINKDEBUG = /m /v 31 | #------------------------------------------------ 32 | # NOTE: Temporary file space. Change to match 33 | # your computer. A RAM disk works best. 34 | #------------------------------------------------ 35 | HEADERS=c:\temp\tcdef.sym 36 | #------------------------------------------------ 37 | COMPILE = bcc -Od $(DEBUG) -D$(TESTING) -D$(FULL) -DBCPP -c -d -m$(MODEL) -H=$(HEADERS) 38 | LINK= tlink $(LINKDEBUG) $(DRIVE)\lib\c0$(MODEL) 39 | LIBS= $(DRIVE)\lib\c$(MODEL) 40 | #------------------------------------------------ 41 | 42 | .c.obj: 43 | $(COMPILE) {$*.c } 44 | 45 | memopad.exe : memopad.obj dialogs.obj menus.obj dflat.lib 46 | $(LINK) memopad dialogs menus,memopad.exe,memopad,dflat $(LIBS) 47 | 48 | dflat.lib : window.obj video.obj message.obj \ 49 | mouse.obj console.obj textbox.obj listbox.obj \ 50 | normal.obj config.obj menu.obj menubar.obj popdown.obj \ 51 | rect.obj applicat.obj keys.obj sysmenu.obj editbox.obj \ 52 | dialbox.obj button.obj fileopen.obj msgbox.obj \ 53 | helpbox.obj log.obj lists.obj statbar.obj decomp.obj \ 54 | combobox.obj pictbox.obj calendar.obj barchart.obj \ 55 | clipbord.obj search.obj dfalloc.obj checkbox.obj \ 56 | text.obj radio.obj box.obj spinbutt.obj watch.obj \ 57 | slidebox.obj direct.obj editor.obj 58 | del dflat.lib 59 | tlib dflat @dflat.bld 60 | 61 | huffc.exe : huffc.obj htree.obj 62 | $(LINK) huffc htree,$*.exe,$*,$(LIBS) 63 | 64 | fixhelp.exe : fixhelp.obj decomp.obj 65 | $(LINK) fixhelp decomp,$*.exe,$*,$(LIBS) 66 | 67 | memopad.hlp : memopad.txt huffc.exe fixhelp.exe 68 | huffc memopad.txt memopad.hlp 69 | fixhelp memopad 70 | -------------------------------------------------------------------------------- /makefile.tcc: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------- 2 | # D - F L A T M A K E F I L E - Turbo C++ 1.01 3 | #------------------------------------------------------------------- 4 | 5 | all : memopad.exe memopad.hlp 6 | 7 | #------------------------------------------------ 8 | # NOTE: Set DRIVE to match where you installed your compiler 9 | #------------------------------------------------ 10 | DRIVE = c:\tc 11 | #------------------------------------------------------------------- 12 | # Delete the TESTING macro to eliminate the Reload 13 | # Help file selection on the Help menu. 14 | #------------------------------------------------------------------- 15 | TESTING = TESTING_DFLAT 16 | #------------------------------------------------------------------- 17 | # This macro builds the full D-Flat system with all options enabled. 18 | # Comment it out for a minimum system or selectively 19 | # comment out the #defines at the top of dflat.h. 20 | #------------------------------------------------------------------- 21 | FULL = BUILD_FULL_DFLAT 22 | #------------------------------------------------------------------- 23 | 24 | MODEL = l 25 | #------------------------------------------------ 26 | # NOTE: Delete the DEBUG and LINKDEBUG macros to 27 | # build without debugging information in the .EXE 28 | #------------------------------------------------ 29 | DEBUG = -v 30 | LINKDEBUG = /m /v 31 | #------------------------------------------------ 32 | COMPILE = tcc $(DEBUG) -D$(TESTING) -D$(FULL) -DBCPP -c -d -m$(MODEL) 33 | LINK= tlink $(LINKDEBUG) $(DRIVE)\lib\c0$(MODEL) 34 | LIBS= $(DRIVE)\lib\c$(MODEL) 35 | #------------------------------------------------ 36 | 37 | .c.obj: 38 | $(COMPILE) {$*.c } 39 | 40 | memopad.exe : memopad.obj dialogs.obj menus.obj dflat.lib 41 | $(LINK) memopad dialogs menus,memopad.exe,memopad,dflat $(LIBS) 42 | 43 | dflat.lib : window.obj video.obj message.obj \ 44 | mouse.obj console.obj textbox.obj listbox.obj \ 45 | normal.obj config.obj menu.obj menubar.obj popdown.obj \ 46 | rect.obj applicat.obj keys.obj sysmenu.obj editbox.obj \ 47 | dialbox.obj button.obj fileopen.obj msgbox.obj \ 48 | helpbox.obj log.obj lists.obj statbar.obj decomp.obj \ 49 | combobox.obj pictbox.obj calendar.obj barchart.obj \ 50 | clipbord.obj search.obj dfalloc.obj checkbox.obj \ 51 | text.obj radio.obj box.obj spinbutt.obj watch.obj \ 52 | slidebox.obj direct.obj editor.obj 53 | del dflat.lib 54 | tlib dflat @dflat.bld 55 | 56 | huffc.exe : huffc.obj htree.obj 57 | $(LINK) huffc htree,$*.exe,$*,$(LIBS) 58 | 59 | fixhelp.exe : fixhelp.obj decomp.obj 60 | $(LINK) fixhelp decomp,$*.exe,$*,$(LIBS) 61 | 62 | memopad.hlp : memopad.txt huffc.exe fixhelp.exe 63 | huffc memopad.txt memopad.hlp 64 | fixhelp memopad 65 | -------------------------------------------------------------------------------- /makefile.wat: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------- 2 | # D - F L A T M A K E F I L E - W A T C O M C 3 | #------------------------------------------------------------------- 4 | 5 | all : memopad.exe memopad.hlp 6 | echo all done 7 | 8 | #------------------------------------------------------------------- 9 | # Delete the FULL macro for a minimal D-Flat application. You can 10 | # selectively remove features by deleting #define statements at 11 | # the beginning of DFLAT.H 12 | #------------------------------------------------------------------- 13 | FULL = BUILD_FULL_DFLAT 14 | #------------------------------------------------------------------- 15 | # Delete the TESTING macro to eliminate the D-Flat Log and the Reload 16 | # Help file selection on the Help menu 17 | #------------------------------------------------------------------- 18 | TESTING = TESTING_DFLAT 19 | #------------------------------------------------------------------- 20 | MODEL = l 21 | #------------------------------------------------ 22 | COMPILE = wcl /os /c /dWATCOM /d$(FULL) /d$(TESTING) /j /c /w4 /s /m$(MODEL) 23 | #------------------------------------------------ 24 | 25 | .c.obj: 26 | $(COMPILE) $* 27 | 28 | memopad.exe : memopad.obj dialogs.obj menus.obj dflat.lib 29 | wcl memopad.obj dialogs.obj menus.obj dflat.lib /k8192 /fe=memopad.exe 30 | 31 | dflat.lib : window.obj video.obj message.obj & 32 | mouse.obj console.obj textbox.obj listbox.obj & 33 | normal.obj config.obj menu.obj menubar.obj popdown.obj & 34 | rect.obj applicat.obj keys.obj sysmenu.obj editbox.obj & 35 | dialbox.obj button.obj fileopen.obj msgbox.obj & 36 | helpbox.obj log.obj lists.obj statbar.obj decomp.obj & 37 | combobox.obj pictbox.obj calendar.obj barchart.obj & 38 | clipbord.obj search.obj dfalloc.obj checkbox.obj & 39 | text.obj radio.obj box.obj spinbutt.obj watch.obj & 40 | slidebox.obj direct.obj editor.obj 41 | del dflat.lib 42 | wlib dflat @dflat 43 | 44 | huffc.exe : huffc.c htree.c 45 | wcl /dWATCOM /ml huffc.c htree.c 46 | 47 | fixhelp.exe : fixhelp.c decomp.c 48 | wcl /dWATCOM /ml fixhelp.c decomp.c 49 | 50 | # Note that if you're compiling in 64-bit Windows, huffc.exe and fixhelp.exe 51 | # will fail to execute and you will have to do this last step manually in 52 | # DOS. 53 | memopad.hlp : memopad.txt huffc.exe fixhelp.exe 54 | huffc memopad.txt memopad.hlp 55 | fixhelp memopad 56 | -------------------------------------------------------------------------------- /memopad.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/memopad.c -------------------------------------------------------------------------------- /memopad.lnk: -------------------------------------------------------------------------------- 1 | memopad+ 2 | calendar+ 3 | barchart+ 4 | menu+ 5 | window+ 6 | video+ 7 | message+ 8 | mouse+ 9 | console+ 10 | normal+ 11 | textbox+ 12 | listbox+ 13 | menubar+ 14 | popdown+ 15 | rect+ 16 | applicat+ 17 | keys+ 18 | config+ 19 | sysmenu+ 20 | menus+ 21 | editbox+ 22 | dialogs+ 23 | dialbox+ 24 | button+ 25 | fileopen+ 26 | msgbox+ 27 | helpbox+ 28 | log+ 29 | lists+ 30 | statbar+ 31 | decomp+ 32 | htree+ 33 | combobox+ 34 | pictbox+ 35 | clipbord+ 36 | search+ 37 | dfalloc+ 38 | checkbox.obj+ 39 | text.obj+ 40 | radio.obj+ 41 | box.obj+ 42 | spinbutt.obj+ 43 | watch.obj+ 44 | slidebox.obj+ 45 | -------------------------------------------------------------------------------- /memopad.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/memopad.txt -------------------------------------------------------------------------------- /menu.c: -------------------------------------------------------------------------------- 1 | /* ------------- menu.c ------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | static struct PopDown *FindCmd(MBAR *mn, int cmd) 6 | { 7 | MENU *mnu = mn->PullDown; 8 | while (mnu->Title != (void *)-1) { 9 | struct PopDown *pd = mnu->Selections; 10 | while (pd->SelectionTitle != NULL) { 11 | if (pd->ActionId == cmd) 12 | return pd; 13 | pd++; 14 | } 15 | mnu++; 16 | } 17 | return NULL; 18 | } 19 | 20 | char *GetCommandText(MBAR *mn, int cmd) 21 | { 22 | struct PopDown *pd = FindCmd(mn, cmd); 23 | if (pd != NULL) 24 | return pd->SelectionTitle; 25 | return NULL; 26 | } 27 | 28 | BOOL isCascadedCommand(MBAR *mn, int cmd) 29 | { 30 | struct PopDown *pd = FindCmd(mn, cmd); 31 | if (pd != NULL) 32 | return pd->Attrib & CASCADED; 33 | return FALSE; 34 | } 35 | 36 | void ActivateCommand(MBAR *mn, int cmd) 37 | { 38 | struct PopDown *pd = FindCmd(mn, cmd); 39 | if (pd != NULL) 40 | pd->Attrib &= ~INACTIVE; 41 | } 42 | 43 | void DeactivateCommand(MBAR *mn, int cmd) 44 | { 45 | struct PopDown *pd = FindCmd(mn, cmd); 46 | if (pd != NULL) 47 | pd->Attrib |= INACTIVE; 48 | } 49 | 50 | BOOL isActive(MBAR *mn, int cmd) 51 | { 52 | struct PopDown *pd = FindCmd(mn, cmd); 53 | if (pd != NULL) 54 | return !(pd->Attrib & INACTIVE); 55 | return FALSE; 56 | } 57 | 58 | BOOL GetCommandToggle(MBAR *mn, int cmd) 59 | { 60 | struct PopDown *pd = FindCmd(mn, cmd); 61 | if (pd != NULL) 62 | return (pd->Attrib & CHECKED) != 0; 63 | return FALSE; 64 | } 65 | 66 | void SetCommandToggle(MBAR *mn, int cmd) 67 | { 68 | struct PopDown *pd = FindCmd(mn, cmd); 69 | if (pd != NULL) 70 | pd->Attrib |= CHECKED; 71 | } 72 | 73 | void ClearCommandToggle(MBAR *mn, int cmd) 74 | { 75 | struct PopDown *pd = FindCmd(mn, cmd); 76 | if (pd != NULL) 77 | pd->Attrib &= ~CHECKED; 78 | } 79 | 80 | void InvertCommandToggle(MBAR *mn, int cmd) 81 | { 82 | struct PopDown *pd = FindCmd(mn, cmd); 83 | if (pd != NULL) 84 | pd->Attrib ^= CHECKED; 85 | } 86 | -------------------------------------------------------------------------------- /menu.h: -------------------------------------------------------------------------------- 1 | /* ------------ menu.h ------------- */ 2 | 3 | #ifndef MENU_H 4 | #define MENU_H 5 | 6 | #define MAXPULLDOWNS 15 7 | #define MAXSELECTIONS 20 8 | #define MAXCASCADES 3 /* nesting level of cascaded menus */ 9 | 10 | /* ----------- popdown menu selection structure 11 | one for each selection on a popdown menu --------- */ 12 | struct PopDown { 13 | unsigned char *SelectionTitle; /* title of the selection */ 14 | int ActionId; /* the command executed */ 15 | int Accelerator; /* the accelerator key */ 16 | int Attrib; /* INACTIVE | CHECKED | TOGGLE | CASCADED*/ 17 | char *help; /* Help mnemonic */ 18 | }; 19 | 20 | /* ----------- popdown menu structure 21 | one for each popdown menu on the menu bar -------- */ 22 | typedef struct Menu { 23 | char *Title; /* title on the menu bar */ 24 | void (*PrepMenu)(void *, struct Menu *); /* function */ 25 | char *StatusText; /* text for the status bar */ 26 | int CascadeId; /* command id of cascading selection */ 27 | int Selection; /* most recent selection */ 28 | struct PopDown Selections[MAXSELECTIONS+1]; 29 | } MENU; 30 | 31 | /* ----- one for each menu bar ----- */ 32 | typedef struct MenuBar { 33 | int ActiveSelection; 34 | MENU PullDown[MAXPULLDOWNS+1]; 35 | } MBAR; 36 | 37 | /* --------- macros to define a menu bar with 38 | popdowns and selections ------------- */ 39 | #define SEPCHAR "\xc4" 40 | #define DEFMENU(m) MBAR m = {-1,{ 41 | #define POPDOWN(ttl,func,stat) {ttl,func,stat,-1,0,{ 42 | #define CASCADED_POPDOWN(id,func) {NULL,func,NULL,id,0,{ 43 | #define SELECTION(stxt,acc,id,attr) {stxt,acc,id,attr,#acc}, 44 | #define SEPARATOR {SEPCHAR}, 45 | #define ENDPOPDOWN {NULL}}}, 46 | #define ENDMENU {(char *)-1} }}; 47 | 48 | /* -------- menu selection attributes -------- */ 49 | #define INACTIVE 1 50 | #define CHECKED 2 51 | #define TOGGLE 4 52 | #define CASCADED 8 53 | 54 | /* --------- the standard menus ---------- */ 55 | extern MBAR MainMenu; 56 | extern MBAR SystemMenu; 57 | extern MBAR *ActiveMenuBar; 58 | 59 | int MenuHeight(struct PopDown *); 60 | int MenuWidth(struct PopDown *); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /menubar.c: -------------------------------------------------------------------------------- 1 | /* ---------------- menubar.c ------------------ */ 2 | 3 | #include "dflat.h" 4 | 5 | static void reset_menubar(WINDOW); 6 | 7 | static struct { 8 | int x1, x2; /* position in menu bar */ 9 | char sc; /* shortcut key value */ 10 | } menu[10]; 11 | static int mctr; 12 | 13 | MBAR *ActiveMenuBar; 14 | static MENU *ActiveMenu; 15 | 16 | static WINDOW mwnd; 17 | static BOOL Selecting; 18 | 19 | static WINDOW Cascaders[MAXCASCADES]; 20 | static int casc; 21 | static WINDOW GetDocFocus(void); 22 | 23 | /* ----------- SETFOCUS Message ----------- */ 24 | static int SetFocusMsg(WINDOW wnd, PARAM p1) 25 | { 26 | int rtn; 27 | rtn = BaseWndProc(MENUBAR, wnd, SETFOCUS, p1, 0); 28 | if (!(int)p1) 29 | SendMessage(GetParent(wnd), ADDSTATUS, 0, 0); 30 | else 31 | SendMessage(NULL, HIDE_CURSOR, 0, 0); 32 | return rtn; 33 | } 34 | 35 | /* --------- BUILDMENU Message --------- */ 36 | static void BuildMenuMsg(WINDOW wnd, PARAM p1) 37 | { 38 | int offset = 3; 39 | reset_menubar(wnd); 40 | mctr = 0; 41 | ActiveMenuBar = (MBAR *) p1; 42 | ActiveMenu = ActiveMenuBar->PullDown; 43 | while (ActiveMenu->Title != NULL && 44 | ActiveMenu->Title != (void*)-1) { 45 | char *cp; 46 | if (strlen(GetText(wnd)+offset) < 47 | strlen(ActiveMenu->Title)+3) 48 | break; 49 | GetText(wnd) = DFrealloc(GetText(wnd), 50 | strlen(GetText(wnd))+5); 51 | memmove(GetText(wnd) + offset+4, GetText(wnd) + offset, 52 | strlen(GetText(wnd))-offset+1); 53 | CopyCommand(GetText(wnd)+offset,ActiveMenu->Title,FALSE, 54 | wnd->WindowColors [STD_COLOR] [BG]); 55 | menu[mctr].x1 = offset; 56 | offset += strlen(ActiveMenu->Title) + (3+MSPACE); 57 | menu[mctr].x2 = offset-MSPACE; 58 | cp = strchr(ActiveMenu->Title, SHORTCUTCHAR); 59 | if (cp) 60 | menu[mctr].sc = tolower(*(cp+1)); 61 | mctr++; 62 | ActiveMenu++; 63 | } 64 | ActiveMenu = ActiveMenuBar->PullDown; 65 | } 66 | 67 | /* ---------- PAINT Message ---------- */ 68 | static void PaintMsg(WINDOW wnd) 69 | { 70 | if (Selecting) 71 | return; 72 | if (wnd == inFocus) 73 | SendMessage(GetParent(wnd), ADDSTATUS, 0, 0); 74 | SetStandardColor(wnd); 75 | wputs(wnd, GetText(wnd), 0, 0); 76 | if (ActiveMenuBar->ActiveSelection != -1 && 77 | (wnd == inFocus || mwnd != NULL)) { 78 | char *sel, *cp; 79 | int offset, offset1; 80 | 81 | sel = DFmalloc(200); 82 | offset=menu[ActiveMenuBar->ActiveSelection].x1; 83 | offset1=menu[ActiveMenuBar->ActiveSelection].x2; 84 | GetText(wnd)[offset1] = '\0'; 85 | SetReverseColor(wnd); 86 | memset(sel, '\0', 200); 87 | strcpy(sel, GetText(wnd)+offset); 88 | cp = strchr(sel, CHANGECOLOR); 89 | if (cp != NULL) 90 | *(cp + 2) = background | 0x80; 91 | wputs(wnd, sel, 92 | offset-ActiveMenuBar->ActiveSelection*4, 0); 93 | GetText(wnd)[offset1] = ' '; 94 | if (mwnd == NULL && wnd == inFocus) { 95 | char *st = ActiveMenu 96 | [ActiveMenuBar->ActiveSelection].StatusText; 97 | if (st != NULL) 98 | SendMessage(GetParent(wnd), ADDSTATUS, 99 | (PARAM)st, 0); 100 | } 101 | free(sel); 102 | } 103 | } 104 | 105 | /* ------------ KEYBOARD Message ------------- */ 106 | static void KeyboardMsg(WINDOW wnd, PARAM p1) 107 | { 108 | MENU *mnu; 109 | int sel; 110 | if (mwnd == NULL) { 111 | /* ----- search for menu bar shortcut keys ---- */ 112 | int c = tolower((int)p1); 113 | int a = AltConvert((int)p1); 114 | int j; 115 | for (j = 0; j < mctr; j++) { 116 | if ((inFocus == wnd && menu[j].sc == c) || 117 | (a && menu[j].sc == a)) { 118 | SendMessage(wnd, SETFOCUS, TRUE, 0); 119 | SendMessage(wnd, MB_SELECTION, j, 0); 120 | return; 121 | } 122 | } 123 | } 124 | /* -------- search for accelerator keys -------- */ 125 | mnu = ActiveMenu; 126 | while (mnu->Title != (void *)-1) { 127 | struct PopDown *pd = mnu->Selections; 128 | if (mnu->PrepMenu) 129 | (*(mnu->PrepMenu))(GetDocFocus(), mnu); 130 | while (pd->SelectionTitle != NULL) { 131 | if (pd->Accelerator == (int) p1) { 132 | if (pd->Attrib & INACTIVE) 133 | beep(); 134 | else { 135 | if (pd->Attrib & TOGGLE) 136 | pd->Attrib ^= CHECKED; 137 | SendMessage(GetDocFocus(), 138 | SETFOCUS, TRUE, 0); 139 | PostMessage(GetParent(wnd), 140 | COMMAND, pd->ActionId, 0); 141 | } 142 | return; 143 | } 144 | pd++; 145 | } 146 | mnu++; 147 | } 148 | switch ((int)p1) { 149 | case F1: 150 | if (ActiveMenu == NULL || ActiveMenuBar == NULL) 151 | break; 152 | sel = ActiveMenuBar->ActiveSelection; 153 | if (sel == -1) { 154 | BaseWndProc(MENUBAR, wnd, KEYBOARD, F1, 0); 155 | return; 156 | } 157 | mnu = ActiveMenu+sel; 158 | if (mwnd == NULL || 159 | mnu->Selections[0].SelectionTitle == NULL) { 160 | DisplayHelp(wnd,mnu->Title); 161 | return; 162 | } 163 | break; 164 | case '\r': 165 | if (mwnd == NULL && 166 | ActiveMenuBar->ActiveSelection != -1) 167 | SendMessage(wnd, MB_SELECTION, 168 | ActiveMenuBar->ActiveSelection, 0); 169 | break; 170 | case F10: 171 | if (wnd != inFocus && mwnd == NULL) { 172 | SendMessage(wnd, SETFOCUS, TRUE, 0); 173 | if ( ActiveMenuBar->ActiveSelection == -1) 174 | ActiveMenuBar->ActiveSelection = 0; 175 | SendMessage(wnd, PAINT, 0, 0); 176 | break; 177 | } 178 | /* ------- fall through ------- */ 179 | case ESC: 180 | if (inFocus == wnd && mwnd == NULL) { 181 | ActiveMenuBar->ActiveSelection = -1; 182 | SendMessage(GetDocFocus(),SETFOCUS,TRUE,0); 183 | SendMessage(wnd, PAINT, 0, 0); 184 | } 185 | break; 186 | case FWD: 187 | ActiveMenuBar->ActiveSelection++; 188 | if (ActiveMenuBar->ActiveSelection == mctr) 189 | ActiveMenuBar->ActiveSelection = 0; 190 | if (mwnd != NULL) 191 | SendMessage(wnd, MB_SELECTION, 192 | ActiveMenuBar->ActiveSelection, 0); 193 | else 194 | SendMessage(wnd, PAINT, 0, 0); 195 | break; 196 | case BS: 197 | if (ActiveMenuBar->ActiveSelection == 0 || 198 | ActiveMenuBar->ActiveSelection == -1) 199 | ActiveMenuBar->ActiveSelection = mctr; 200 | --ActiveMenuBar->ActiveSelection; 201 | if (mwnd != NULL) 202 | SendMessage(wnd, MB_SELECTION, 203 | ActiveMenuBar->ActiveSelection, 0); 204 | else 205 | SendMessage(wnd, PAINT, 0, 0); 206 | break; 207 | default: 208 | break; 209 | } 210 | } 211 | 212 | /* --------------- LEFT_BUTTON Message ---------- */ 213 | static void LeftButtonMsg(WINDOW wnd, PARAM p1) 214 | { 215 | int i; 216 | int mx = (int) p1 - GetLeft(wnd); 217 | /* --- compute the selection that the left button hit --- */ 218 | for (i = 0; i < mctr; i++) 219 | if (mx >= menu[i].x1-4*i && 220 | mx <= menu[i].x2-4*i-5) 221 | break; 222 | if (i < mctr) 223 | if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL) 224 | SendMessage(wnd, MB_SELECTION, i, 0); 225 | } 226 | 227 | /* -------------- MB_SELECTION Message -------------- */ 228 | static void SelectionMsg(WINDOW wnd, PARAM p1, PARAM p2) 229 | { 230 | int wd, mx, my; 231 | MENU *mnu; 232 | 233 | if (!p2) { 234 | ActiveMenuBar->ActiveSelection = -1; 235 | SendMessage(wnd, PAINT, 0, 0); 236 | } 237 | Selecting = TRUE; 238 | mnu = ActiveMenu+(int)p1; 239 | if (mnu->PrepMenu != NULL) 240 | (*(mnu->PrepMenu))(GetDocFocus(), mnu); 241 | wd = MenuWidth(mnu->Selections); 242 | if (p2) { 243 | int brd = GetRight(wnd); 244 | mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1; 245 | if (mx + wd > brd) 246 | mx = brd - wd; 247 | my = GetTop(mwnd) + mwnd->selection; 248 | } 249 | else { 250 | int offset = menu[(int)p1].x1 - 4 * (int)p1; 251 | if (mwnd != NULL) 252 | SendMessage(mwnd, CLOSE_WINDOW, 0, 0); 253 | ActiveMenuBar->ActiveSelection = (int) p1; 254 | if (offset > WindowWidth(wnd)-wd) 255 | offset = WindowWidth(wnd)-wd; 256 | mx = GetLeft(wnd)+offset; 257 | my = GetTop(wnd)+1; 258 | } 259 | mwnd = CreateWindow(POPDOWNMENU, NULL, 260 | mx, my, 261 | MenuHeight(mnu->Selections), 262 | wd, 263 | NULL, 264 | wnd, 265 | NULL, 266 | SHADOW); 267 | if (!p2) { 268 | Selecting = FALSE; 269 | SendMessage(wnd, PAINT, 0, 0); 270 | Selecting = TRUE; 271 | } 272 | if (mnu->Selections[0].SelectionTitle != NULL) { 273 | SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0); 274 | SendMessage(mwnd, SETFOCUS, TRUE, 0); 275 | SendMessage(mwnd, SHOW_WINDOW, 0, 0); 276 | } 277 | Selecting = FALSE; 278 | } 279 | 280 | /* --------- COMMAND Message ---------- */ 281 | static void CommandMsg(WINDOW wnd, PARAM p1, PARAM p2) 282 | { 283 | if (p1 == ID_HELP) { 284 | BaseWndProc(MENUBAR, wnd, COMMAND, p1, p2); 285 | return; 286 | } 287 | if (isCascadedCommand(ActiveMenuBar, (int)p1)) { 288 | /* find the cascaded menu based on command id in p1 */ 289 | MENU *mnu = ActiveMenu+mctr; 290 | while (mnu->Title != (void *)-1) { 291 | if (mnu->CascadeId == (int) p1) { 292 | if (casc < MAXCASCADES) { 293 | Cascaders[casc++] = mwnd; 294 | SendMessage(wnd, MB_SELECTION, 295 | (PARAM)(mnu-ActiveMenu), TRUE); 296 | } 297 | break; 298 | } 299 | mnu++; 300 | } 301 | } 302 | else { 303 | if (mwnd != NULL) 304 | SendMessage(mwnd, CLOSE_WINDOW, 0, 0); 305 | SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0); 306 | PostMessage(GetParent(wnd), COMMAND, p1, p2); 307 | } 308 | } 309 | 310 | /* --------------- CLOSE_POPDOWN Message --------------- */ 311 | static void ClosePopdownMsg(WINDOW wnd) 312 | { 313 | if (casc > 0) 314 | SendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0); 315 | else { 316 | mwnd = NULL; 317 | ActiveMenuBar->ActiveSelection = -1; 318 | if (!Selecting) { 319 | SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0); 320 | SendMessage(wnd, PAINT, 0, 0); 321 | } 322 | } 323 | } 324 | 325 | /* ---------------- CLOSE_WINDOW Message --------------- */ 326 | static void CloseWindowMsg(WINDOW wnd) 327 | { 328 | if (GetText(wnd) != NULL) { 329 | free(GetText(wnd)); 330 | GetText(wnd) = NULL; 331 | } 332 | mctr = 0; 333 | ActiveMenuBar->ActiveSelection = -1; 334 | ActiveMenu = NULL; 335 | ActiveMenuBar = NULL; 336 | } 337 | 338 | /* --- Window processing module for MENUBAR window class --- */ 339 | int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 340 | { 341 | int rtn; 342 | 343 | switch (msg) { 344 | case CREATE_WINDOW: 345 | reset_menubar(wnd); 346 | break; 347 | case SETFOCUS: 348 | return SetFocusMsg(wnd, p1); 349 | case BUILDMENU: 350 | BuildMenuMsg(wnd, p1); 351 | break; 352 | case PAINT: 353 | if (!isVisible(wnd) || GetText(wnd) == NULL) 354 | break; 355 | PaintMsg(wnd); 356 | return FALSE; 357 | case BORDER: 358 | if (mwnd == NULL) 359 | SendMessage(wnd, PAINT, 0, 0); 360 | return TRUE; 361 | case KEYBOARD: 362 | KeyboardMsg(wnd, p1); 363 | return TRUE; 364 | case LEFT_BUTTON: 365 | LeftButtonMsg(wnd, p1); 366 | return TRUE; 367 | case MB_SELECTION: 368 | SelectionMsg(wnd, p1, p2); 369 | break; 370 | case COMMAND: 371 | CommandMsg(wnd, p1, p2); 372 | return TRUE; 373 | case INSIDE_WINDOW: 374 | return InsideRect(p1, p2, WindowRect(wnd)); 375 | case CLOSE_POPDOWN: 376 | ClosePopdownMsg(wnd); 377 | return TRUE; 378 | case CLOSE_WINDOW: 379 | rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2); 380 | CloseWindowMsg(wnd); 381 | return rtn; 382 | default: 383 | break; 384 | } 385 | return BaseWndProc(MENUBAR, wnd, msg, p1, p2); 386 | } 387 | 388 | /* ------------- reset the MENUBAR -------------- */ 389 | static void reset_menubar(WINDOW wnd) 390 | { 391 | GetText(wnd) = DFrealloc(GetText(wnd), SCREENWIDTH+5); 392 | memset(GetText(wnd), ' ', SCREENWIDTH); 393 | *(GetText(wnd)+WindowWidth(wnd)) = '\0'; 394 | } 395 | 396 | static WINDOW GetDocFocus(void) 397 | { 398 | WINDOW wnd = ApplicationWindow; 399 | if (wnd != NULL) { 400 | wnd = LastWindow(wnd); 401 | while (wnd != NULL && (GetClass(wnd) == MENUBAR || 402 | GetClass(wnd) == STATUSBAR)) 403 | wnd = PrevWindow(wnd); 404 | if (wnd != NULL) 405 | while (wnd->childfocus != NULL) 406 | wnd = wnd->childfocus; 407 | } 408 | return wnd ? wnd : ApplicationWindow; 409 | } 410 | -------------------------------------------------------------------------------- /menus.c: -------------------------------------------------------------------------------- 1 | /* -------------- menus.c ------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | /* --------------------- the main menu --------------------- */ 6 | DEFMENU(MainMenu) 7 | /* --------------- the File popdown menu ----------------*/ 8 | POPDOWN( "~File", PrepFileMenu, "Read/write/print files. Go to DOS" ) 9 | SELECTION( "~New", ID_NEW, 0, 0 ) 10 | SELECTION( "~Open...", ID_OPEN, 0, 0 ) 11 | SEPARATOR 12 | SELECTION( "~Save", ID_SAVE, 0, INACTIVE) 13 | SELECTION( "Save ~as...", ID_SAVEAS, 0, INACTIVE) 14 | SELECTION( "D~elete", ID_DELETEFILE, 0, INACTIVE) 15 | SEPARATOR 16 | SELECTION( "~Print", ID_PRINT, 0, INACTIVE) 17 | SELECTION( "P~rinter setup...", ID_PRINTSETUP, 0, 0 ) 18 | SEPARATOR 19 | SELECTION( "~DOS", ID_DOS, 0, 0 ) 20 | SELECTION( "E~xit", ID_EXIT, ALT_X, 0 ) 21 | ENDPOPDOWN 22 | 23 | /* --------------- the Edit popdown menu ----------------*/ 24 | POPDOWN( "~Edit", PrepEditMenu, "Clipboard, delete text, paragraph" ) 25 | SELECTION( "~Undo", ID_UNDO, ALT_BS, INACTIVE) 26 | SEPARATOR 27 | SELECTION( "Cu~t", ID_CUT, SHIFT_DEL, INACTIVE) 28 | SELECTION( "~Copy", ID_COPY, CTRL_INS, INACTIVE) 29 | SELECTION( "~Paste", ID_PASTE, SHIFT_INS, INACTIVE) 30 | SEPARATOR 31 | SELECTION( "Cl~ear", ID_CLEAR, 0, INACTIVE) 32 | SELECTION( "~Delete", ID_DELETETEXT, DEL, INACTIVE) 33 | SEPARATOR 34 | SELECTION( "Pa~ragraph", ID_PARAGRAPH, ALT_P,INACTIVE) 35 | ENDPOPDOWN 36 | 37 | /* --------------- the Search popdown menu ----------------*/ 38 | POPDOWN( "~Search", PrepSearchMenu, "Search and replace" ) 39 | SELECTION( "~Search...", ID_SEARCH, 0, INACTIVE) 40 | SELECTION( "~Replace...",ID_REPLACE, 0, INACTIVE) 41 | SELECTION( "~Next", ID_SEARCHNEXT, F3, INACTIVE) 42 | ENDPOPDOWN 43 | 44 | /* ------------ the Utilities popdown menu --------------- */ 45 | POPDOWN( "~Utilities", NULL, "Utility programs" ) 46 | SELECTION( "~Calendar", ID_CALENDAR, 0, 0) 47 | SELECTION( "~Bar chart", ID_BARCHART, 0, 0) 48 | ENDPOPDOWN 49 | 50 | /* ------------- the Options popdown menu ---------------*/ 51 | POPDOWN( "~Options", NULL, "Editor and display options" ) 52 | SELECTION( "~Display...", ID_DISPLAY, 0, 0 ) 53 | SEPARATOR 54 | #ifdef INCLUDE_LOGGING 55 | SELECTION( "~Log messages", ID_LOG, ALT_L, 0 ) 56 | SEPARATOR 57 | #endif 58 | SELECTION( "~Insert", ID_INSERT, INS, TOGGLE) 59 | SELECTION( "~Word wrap", ID_WRAP, 0, TOGGLE) 60 | SELECTION( "~Tabs ( )", ID_TABS, 0, CASCADED) 61 | SEPARATOR 62 | SELECTION( "~Save options", ID_SAVEOPTIONS, 0, 0 ) 63 | ENDPOPDOWN 64 | 65 | /* --------------- the Window popdown menu --------------*/ 66 | POPDOWN( "~Window", PrepWindowMenu, "Select/close document windows" ) 67 | SELECTION( NULL, ID_CLOSEALL, 0, 0) 68 | SEPARATOR 69 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 70 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 71 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 72 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 73 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 74 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 75 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 76 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 77 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 78 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 79 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 80 | SELECTION( "~More Windows...", ID_MOREWINDOWS, 0, 0) 81 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 82 | ENDPOPDOWN 83 | 84 | /* --------------- the Help popdown menu ----------------*/ 85 | POPDOWN( "~Help", NULL, "Get help" ) 86 | SELECTION( "~Help for help...", ID_HELPHELP, 0, 0 ) 87 | SELECTION( "~Extended help...", ID_EXTHELP, 0, 0 ) 88 | SELECTION( "~Keys help...", ID_KEYSHELP, 0, 0 ) 89 | SELECTION( "Help ~index...", ID_HELPINDEX, 0, 0 ) 90 | SEPARATOR 91 | SELECTION( "~About...", ID_ABOUT, 0, 0 ) 92 | ENDPOPDOWN 93 | 94 | /* ----- cascaded pulldown from Tabs... above ----- */ 95 | CASCADED_POPDOWN( ID_TABS, NULL ) 96 | SELECTION( "~2 tab stops", ID_TAB2, 0, 0) 97 | SELECTION( "~4 tab stops", ID_TAB4, 0, 0) 98 | SELECTION( "~6 tab stops", ID_TAB6, 0, 0) 99 | SELECTION( "~8 tab stops", ID_TAB8, 0, 0) 100 | ENDPOPDOWN 101 | 102 | ENDMENU 103 | 104 | /* ------------- the System Menu --------------------- */ 105 | DEFMENU(SystemMenu) 106 | POPDOWN("System Menu", NULL, NULL) 107 | #ifdef INCLUDE_RESTORE 108 | SELECTION("~Restore", ID_SYSRESTORE, 0, 0 ) 109 | #endif 110 | SELECTION("~Move", ID_SYSMOVE, 0, 0 ) 111 | SELECTION("~Size", ID_SYSSIZE, 0, 0 ) 112 | #ifdef INCLUDE_MINIMIZE 113 | SELECTION("Mi~nimize", ID_SYSMINIMIZE, 0, 0 ) 114 | #endif 115 | #ifdef INCLUDE_MAXIMIZE 116 | SELECTION("Ma~ximize", ID_SYSMAXIMIZE, 0, 0 ) 117 | #endif 118 | SEPARATOR 119 | SELECTION("~Close", ID_SYSCLOSE, CTRL_F4, 0 ) 120 | ENDPOPDOWN 121 | ENDMENU 122 | -------------------------------------------------------------------------------- /mfixhelp.txt: -------------------------------------------------------------------------------- 1 | -dosh 2 | -Wall 3 | -DBUILD_FULL_DFLAT 4 | -o fixhelp.exe 5 | fixhelp.c decomp.c 6 | -------------------------------------------------------------------------------- /mhuffc.txt: -------------------------------------------------------------------------------- 1 | -dosh 2 | -Wall 3 | -DBUILD_FULL_DFLAT 4 | -o huffc.exe 5 | huffc.c htree.c 6 | -------------------------------------------------------------------------------- /mldflat.txt: -------------------------------------------------------------------------------- 1 | -dosh 2 | -Wall 3 | -DBUILD_FULL_DFLAT 4 | -c -o ldflat.a 5 | window.c video.c message.c 6 | mouse.c console.c textbox.c listbox.c 7 | normal.c config.c menu.c menubar.c popdown.c 8 | rect.c applicat.c keys.c sysmenu.c editbox.c 9 | dialbox.c button.c fileopen.c msgbox.c 10 | helpbox.c log.c lists.c statbar.c decomp.c 11 | combobox.c pictbox.c calendar.c barchart.c 12 | clipbord.c search.c dfalloc.c checkbox.c 13 | text.c radio.c box.c spinbutt.c watch.c 14 | slidebox.c direct.c editor.c 15 | -------------------------------------------------------------------------------- /mmemopad.txt: -------------------------------------------------------------------------------- 1 | -dosh 2 | -Wall 3 | -DBUILD_FULL_DFLAT 4 | -o memopad.exe -map memopad.map 5 | memopad.c dialogs.c menus.c 6 | scdos.c 7 | ldflat.a 8 | -------------------------------------------------------------------------------- /mouse.c: -------------------------------------------------------------------------------- 1 | /* ------------- mouse.c ------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | static union REGS regs; 6 | /* 7 | static struct SREGS sregs; 8 | */ 9 | 10 | static void near mouse(int m1,int m2,int m3,int m4) 11 | { 12 | regs.x.dx = m4; 13 | regs.x.cx = m3; 14 | regs.x.bx = m2; 15 | regs.x.ax = m1; 16 | /* 17 | int86x(MOUSE, ®s, ®s, &sregs); 18 | */ 19 | int86(MOUSE, ®s, ®s); 20 | } 21 | 22 | /* ---------- reset the mouse ---------- */ 23 | void resetmouse(void) 24 | { 25 | /* 26 | segread(&sregs); 27 | */ 28 | mouse(0,0,0,0); 29 | } 30 | 31 | /* ----- test to see if the mouse driver is installed ----- */ 32 | BOOL mouse_installed(void) 33 | { 34 | unsigned char far *ms; 35 | ms = MK_FP(peek(0, MOUSE*4+2), peek(0, MOUSE*4)); 36 | return (SCREENWIDTH <= 80 && ms != NULL && *ms != 0xcf); 37 | } 38 | 39 | /* ------ return true if mouse buttons are pressed ------- */ 40 | int mousebuttons(void) 41 | { 42 | if (mouse_installed()) { 43 | /* 44 | segread(&sregs); 45 | */ 46 | mouse(3,0,0,0); 47 | return regs.x.bx & 3; 48 | } 49 | return 0; 50 | } 51 | 52 | /* ---------- return mouse coordinates ---------- */ 53 | void get_mouseposition(int *x, int *y) 54 | { 55 | *x = *y = -1; 56 | if (mouse_installed()) { 57 | /* 58 | segread(&sregs); 59 | */ 60 | mouse(3,0,0,0); 61 | *x = regs.x.cx/8; 62 | *y = regs.x.dx/8; 63 | if (SCREENWIDTH == 40) 64 | *x /= 2; 65 | } 66 | } 67 | 68 | /* -------- position the mouse cursor -------- */ 69 | void set_mouseposition(int x, int y) 70 | { 71 | if (mouse_installed()) { 72 | /* 73 | segread(&sregs); 74 | */ 75 | if (SCREENWIDTH == 40) 76 | x *= 2; 77 | mouse(4,0,x*8,y*8); 78 | } 79 | } 80 | 81 | /* --------- display the mouse cursor -------- */ 82 | void show_mousecursor(void) 83 | { 84 | if (mouse_installed()) { 85 | /* 86 | segread(&sregs); 87 | */ 88 | mouse(1,0,0,0); 89 | } 90 | } 91 | 92 | /* --------- hide the mouse cursor ------- */ 93 | void hide_mousecursor(void) 94 | { 95 | if (mouse_installed()) { 96 | /* 97 | segread(&sregs); 98 | */ 99 | mouse(2,0,0,0); 100 | } 101 | } 102 | 103 | /* --- return true if a mouse button has been released --- */ 104 | int button_releases(void) 105 | { 106 | if (mouse_installed()) { 107 | /* 108 | segread(&sregs); 109 | */ 110 | mouse(6,0,0,0); 111 | return regs.x.bx; 112 | } 113 | return 0; 114 | } 115 | 116 | /* ----- set mouse travel limits ------- */ 117 | void set_mousetravel(int minx, int maxx, int miny, int maxy) 118 | { 119 | if (mouse_installed()) { 120 | if (SCREENWIDTH == 40) { 121 | minx *= 2; 122 | maxx *= 2; 123 | } 124 | /* 125 | segread(&sregs); 126 | */ 127 | mouse(7, 0, minx*8, maxx*8); 128 | mouse(8, 0, miny*8, maxy*8); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /msgbox.c: -------------------------------------------------------------------------------- 1 | /* ------------------ msgbox.c ------------------ */ 2 | 3 | #include "dflat.h" 4 | 5 | extern DBOX MsgBox; 6 | extern DBOX InputBoxDB; 7 | WINDOW CancelWnd; 8 | 9 | static int ReturnValue; 10 | 11 | int MessageBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 12 | { 13 | switch (msg) { 14 | case CREATE_WINDOW: 15 | GetClass(wnd) = MESSAGEBOX; 16 | InitWindowColors(wnd); 17 | ClearAttribute(wnd, CONTROLBOX); 18 | break; 19 | case KEYBOARD: 20 | if (p1 == '\r' || p1 == ESC) 21 | ReturnValue = (int)p1; 22 | break; 23 | default: 24 | break; 25 | } 26 | return BaseWndProc(MESSAGEBOX, wnd, msg, p1, p2); 27 | } 28 | 29 | int YesNoBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 30 | { 31 | switch (msg) { 32 | case CREATE_WINDOW: 33 | GetClass(wnd) = MESSAGEBOX; 34 | InitWindowColors(wnd); 35 | ClearAttribute(wnd, CONTROLBOX); 36 | break; 37 | case KEYBOARD: { 38 | int c = tolower((int)p1); 39 | if (c == 'y') 40 | SendMessage(wnd, COMMAND, ID_OK, 0); 41 | else if (c == 'n') 42 | SendMessage(wnd, COMMAND, ID_CANCEL, 0); 43 | break; 44 | } 45 | default: 46 | break; 47 | } 48 | return BaseWndProc(MESSAGEBOX, wnd, msg, p1, p2); 49 | } 50 | 51 | int ErrorBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 52 | { 53 | switch (msg) { 54 | case CREATE_WINDOW: 55 | GetClass(wnd) = ERRORBOX; 56 | InitWindowColors(wnd); 57 | break; 58 | case KEYBOARD: 59 | if (p1 == '\r' || p1 == ESC) 60 | ReturnValue = (int)p1; 61 | break; 62 | default: 63 | break; 64 | } 65 | return BaseWndProc(ERRORBOX, wnd, msg, p1, p2); 66 | } 67 | 68 | int CancelBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 69 | { 70 | switch (msg) { 71 | case CREATE_WINDOW: 72 | CancelWnd = wnd; 73 | SendMessage(wnd, CAPTURE_MOUSE, 0, 0); 74 | SendMessage(wnd, CAPTURE_KEYBOARD, 0, 0); 75 | break; 76 | case COMMAND: 77 | if ((int) p1 == ID_CANCEL && (int) p2 == 0) 78 | SendMessage(GetParent(wnd), msg, p1, p2); 79 | return TRUE; 80 | case CLOSE_WINDOW: 81 | CancelWnd = NULL; 82 | SendMessage(wnd, RELEASE_MOUSE, 0, 0); 83 | SendMessage(wnd, RELEASE_KEYBOARD, 0, 0); 84 | p1 = TRUE; 85 | break; 86 | default: 87 | break; 88 | } 89 | return BaseWndProc(MESSAGEBOX, wnd, msg, p1, p2); 90 | } 91 | 92 | void CloseCancelBox(void) 93 | { 94 | if (CancelWnd != NULL) 95 | SendMessage(CancelWnd, CLOSE_WINDOW, 0, 0); 96 | } 97 | 98 | static char *InputText; 99 | static int TextLength; 100 | 101 | int InputBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 102 | { 103 | int rtn; 104 | switch (msg) { 105 | case CREATE_WINDOW: 106 | rtn = DefaultWndProc(wnd, msg, p1, p2); 107 | SendMessage(ControlWindow(&InputBoxDB,ID_INPUTTEXT), 108 | SETTEXTLENGTH, TextLength, 0); 109 | SendMessage(ControlWindow(&InputBoxDB,ID_INPUTTEXT), 110 | ADDTEXT, (PARAM) InputText, 0); 111 | return rtn; 112 | case COMMAND: 113 | if ((int) p1 == ID_OK && (int) p2 == 0) 114 | GetItemText(wnd, ID_INPUTTEXT, 115 | InputText, TextLength); 116 | break; 117 | default: 118 | break; 119 | } 120 | return DefaultWndProc(wnd, msg, p1, p2); 121 | } 122 | 123 | BOOL InputBox(WINDOW wnd,char *ttl,char *msg,char *text,int len,int wd) 124 | { 125 | int ln = wd ? wd : len; 126 | ln = min(SCREENWIDTH-8, ln); 127 | InputText = text; 128 | TextLength = len; 129 | InputBoxDB.dwnd.title = ttl; 130 | InputBoxDB.dwnd.w = 4 + max(20, max(ln, max(strlen(ttl), strlen(msg)))); 131 | InputBoxDB.ctl[1].dwnd.x = (InputBoxDB.dwnd.w-2-ln)/2; 132 | InputBoxDB.ctl[0].dwnd.w = strlen(msg); 133 | InputBoxDB.ctl[0].itext = msg; 134 | InputBoxDB.ctl[1].itext = NULL; 135 | InputBoxDB.ctl[1].dwnd.w = ln; 136 | InputBoxDB.ctl[2].dwnd.x = (InputBoxDB.dwnd.w - 20) / 2; 137 | InputBoxDB.ctl[3].dwnd.x = InputBoxDB.ctl[2].dwnd.x + 10; 138 | InputBoxDB.ctl[2].isetting = ON; 139 | InputBoxDB.ctl[3].isetting = ON; 140 | return DialogBox(wnd, &InputBoxDB, TRUE, InputBoxProc); 141 | } 142 | 143 | BOOL GenericMessage(WINDOW wnd,char *ttl,char *msg,int buttonct, 144 | int (*wndproc)(struct window *,enum messages,PARAM,PARAM), 145 | char *b1, char *b2, int c1, int c2, int isModal) 146 | { 147 | BOOL rtn; 148 | MsgBox.dwnd.title = ttl; 149 | MsgBox.ctl[0].dwnd.h = MsgHeight(msg); 150 | MsgBox.ctl[0].dwnd.w = max(max(MsgWidth(msg), 151 | buttonct*8 + buttonct + 2), strlen(ttl)+2); 152 | MsgBox.dwnd.h = MsgBox.ctl[0].dwnd.h+6; 153 | MsgBox.dwnd.w = MsgBox.ctl[0].dwnd.w+4; 154 | if (buttonct == 1) 155 | MsgBox.ctl[1].dwnd.x = (MsgBox.dwnd.w - 10) / 2; 156 | else { 157 | MsgBox.ctl[1].dwnd.x = (MsgBox.dwnd.w - 20) / 2; 158 | MsgBox.ctl[2].dwnd.x = MsgBox.ctl[1].dwnd.x + 10; 159 | MsgBox.ctl[2].Class = BUTTON; 160 | } 161 | MsgBox.ctl[1].dwnd.y = MsgBox.dwnd.h - 4; 162 | MsgBox.ctl[2].dwnd.y = MsgBox.dwnd.h - 4; 163 | MsgBox.ctl[0].itext = msg; 164 | MsgBox.ctl[1].itext = b1; 165 | MsgBox.ctl[2].itext = b2; 166 | MsgBox.ctl[1].command = c1; 167 | MsgBox.ctl[2].command = c2; 168 | MsgBox.ctl[1].isetting = ON; 169 | MsgBox.ctl[2].isetting = ON; 170 | rtn = DialogBox(wnd, &MsgBox, isModal, wndproc); 171 | MsgBox.ctl[2].Class = 0; 172 | return rtn; 173 | } 174 | 175 | WINDOW MomentaryMessage(char *msg) 176 | { 177 | WINDOW wnd = CreateWindow( 178 | TEXTBOX, 179 | NULL, 180 | -1,-1,MsgHeight(msg)+2,MsgWidth(msg)+2, 181 | NULL,NULL,NULL, 182 | HASBORDER | SHADOW | SAVESELF); 183 | SendMessage(wnd, SETTEXT, (PARAM) msg, 0); 184 | if (cfg.mono == 0) { 185 | WindowClientColor(wnd, WHITE, GREEN); 186 | WindowFrameColor(wnd, WHITE, GREEN); 187 | } 188 | SendMessage(wnd, SHOW_WINDOW, 0, 0); 189 | return wnd; 190 | } 191 | 192 | int MsgHeight(char *msg) 193 | { 194 | int h = 1; 195 | while ((msg = strchr(msg, '\n')) != NULL) { 196 | h++; 197 | msg++; 198 | } 199 | return min(h, SCREENHEIGHT-10); 200 | } 201 | 202 | int MsgWidth(char *msg) 203 | { 204 | int w = 0; 205 | char *cp = msg; 206 | while ((cp = strchr(msg, '\n')) != NULL) { 207 | w = max(w, (int) (cp-msg)); 208 | msg = cp+1; 209 | } 210 | return min(max(strlen(msg),w), SCREENWIDTH-10); 211 | } 212 | -------------------------------------------------------------------------------- /pictbox.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/pictbox.c -------------------------------------------------------------------------------- /popdown.c: -------------------------------------------------------------------------------- 1 | /* ------------- popdown.c ----------- */ 2 | 3 | #include "dflat.h" 4 | 5 | static int SelectionWidth(struct PopDown *); 6 | static int py = -1; 7 | int CurrentMenuSelection; 8 | 9 | /* ------------ CREATE_WINDOW Message ------------- */ 10 | static int CreateWindowMsg(WINDOW wnd) 11 | { 12 | int rtn, adj; 13 | ClearAttribute(wnd, HASTITLEBAR | 14 | VSCROLLBAR | 15 | MOVEABLE | 16 | SIZEABLE | 17 | HSCROLLBAR); 18 | /* ------ adjust to keep popdown on screen ----- */ 19 | adj = SCREENHEIGHT-1-wnd->rc.bt; 20 | if (adj < 0) { 21 | wnd->rc.tp += adj; 22 | wnd->rc.bt += adj; 23 | } 24 | adj = SCREENWIDTH-1-wnd->rc.rt; 25 | if (adj < 0) { 26 | wnd->rc.lf += adj; 27 | wnd->rc.rt += adj; 28 | } 29 | rtn = BaseWndProc(POPDOWNMENU, wnd, CREATE_WINDOW, 0, 0); 30 | SendMessage(wnd, CAPTURE_MOUSE, 0, 0); 31 | SendMessage(wnd, CAPTURE_KEYBOARD, 0, 0); 32 | SendMessage(NULL, SAVE_CURSOR, 0, 0); 33 | SendMessage(NULL, HIDE_CURSOR, 0, 0); 34 | wnd->oldFocus = inFocus; 35 | inFocus = wnd; 36 | return rtn; 37 | } 38 | 39 | /* --------- LEFT_BUTTON Message --------- */ 40 | static void LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2) 41 | { 42 | int my = (int) p2 - GetTop(wnd); 43 | if (InsideRect(p1, p2, ClientRect(wnd))) { 44 | if (my != py) { 45 | SendMessage(wnd, LB_SELECTION, 46 | (PARAM) wnd->wtop+my-1, TRUE); 47 | py = my; 48 | } 49 | } 50 | else if ((int)p2 == GetTop(GetParent(wnd))) 51 | if (GetClass(GetParent(wnd)) == MENUBAR) 52 | PostMessage(GetParent(wnd), LEFT_BUTTON, p1, p2); 53 | } 54 | 55 | /* -------- BUTTON_RELEASED Message -------- */ 56 | static BOOL ButtonReleasedMsg(WINDOW wnd, PARAM p1, PARAM p2) 57 | { 58 | py = -1; 59 | if (InsideRect((int)p1, (int)p2, ClientRect(wnd))) { 60 | int sel = (int)p2 - GetClientTop(wnd); 61 | if (*TextLine(wnd, sel) != LINE) 62 | SendMessage(wnd, LB_CHOOSE, wnd->selection, 0); 63 | } 64 | else { 65 | WINDOW pwnd = GetParent(wnd); 66 | if (GetClass(pwnd) == MENUBAR && (int)p2==GetTop(pwnd)) 67 | return FALSE; 68 | if ((int)p1 == GetLeft(pwnd)+2) 69 | return FALSE; 70 | SendMessage(wnd, CLOSE_WINDOW, 0, 0); 71 | return TRUE; 72 | } 73 | return FALSE; 74 | } 75 | 76 | /* --------- PAINT Message -------- */ 77 | static void PaintMsg(WINDOW wnd) 78 | { 79 | int wd; 80 | unsigned char sep[80], *cp = sep; 81 | unsigned char sel[80]; 82 | struct PopDown *ActivePopDown; 83 | struct PopDown *pd1; 84 | 85 | ActivePopDown = pd1 = wnd->mnu->Selections; 86 | wd = MenuWidth(ActivePopDown)-2; 87 | while (wd--) 88 | *cp++ = LINE; 89 | *cp = '\0'; 90 | SendMessage(wnd, CLEARTEXT, 0, 0); 91 | wnd->selection = wnd->mnu->Selection; 92 | while (pd1->SelectionTitle != NULL) { 93 | if (*pd1->SelectionTitle == LINE) 94 | SendMessage(wnd, ADDTEXT, (PARAM) sep, 0); 95 | else { 96 | int len; 97 | memset(sel, '\0', sizeof sel); 98 | if (pd1->Attrib & INACTIVE) 99 | /* ------ inactive menu selection ----- */ 100 | sprintf(sel, "%c%c%c", 101 | CHANGECOLOR, 102 | wnd->WindowColors [HILITE_COLOR] [FG]|0x80, 103 | wnd->WindowColors [STD_COLOR] [BG]|0x80); 104 | strcat(sel, " "); 105 | if (pd1->Attrib & CHECKED) 106 | /* ---- paint the toggle checkmark ---- */ 107 | sel[strlen(sel)-1] = CHECKMARK; 108 | len=CopyCommand(sel+strlen(sel),pd1->SelectionTitle, 109 | pd1->Attrib & INACTIVE, 110 | wnd->WindowColors [STD_COLOR] [BG]); 111 | if (pd1->Accelerator) { 112 | /* ---- paint accelerator key ---- */ 113 | int i; 114 | int wd1 = 2+SelectionWidth(ActivePopDown) - 115 | strlen(pd1->SelectionTitle); 116 | int key = pd1->Accelerator; 117 | if (key > 0 && key < 27) { 118 | /* --- CTRL+ key --- */ 119 | while (wd1--) 120 | strcat(sel, " "); 121 | sprintf(sel+strlen(sel), "[Ctrl+%c]", key-1+'A'); 122 | } 123 | else { 124 | for (i = 0; keys[i].keylabel; i++) { 125 | if (keys[i].keycode == key) { 126 | while (wd1--) 127 | strcat(sel, " "); 128 | sprintf(sel+strlen(sel), "[%s]", 129 | keys[i].keylabel); 130 | break; 131 | } 132 | } 133 | } 134 | } 135 | if (pd1->Attrib & CASCADED) { 136 | /* ---- paint cascaded menu token ---- */ 137 | if (!pd1->Accelerator) { 138 | wd = MenuWidth(ActivePopDown)-len+1; 139 | while (wd--) 140 | strcat(sel, " "); 141 | } 142 | sel[strlen(sel)-1] = CASCADEPOINTER; 143 | } 144 | else 145 | strcat(sel, " "); 146 | strcat(sel, " "); 147 | sel[strlen(sel)-1] = RESETCOLOR; 148 | SendMessage(wnd, ADDTEXT, (PARAM) sel, 0); 149 | } 150 | pd1++; 151 | } 152 | } 153 | 154 | /* ---------- BORDER Message ----------- */ 155 | static int BorderMsg(WINDOW wnd) 156 | { 157 | int i, rtn = TRUE; 158 | WINDOW currFocus; 159 | if (wnd->mnu != NULL) { 160 | currFocus = inFocus; 161 | inFocus = NULL; 162 | rtn = BaseWndProc(POPDOWNMENU, wnd, BORDER, 0, 0); 163 | inFocus = currFocus; 164 | for (i = 0; i < ClientHeight(wnd); i++) { 165 | if (*TextLine(wnd, i) == LINE) { 166 | wputch(wnd, LEDGE, 0, i+1); 167 | wputch(wnd, REDGE, WindowWidth(wnd)-1, i+1); 168 | } 169 | } 170 | } 171 | return rtn; 172 | } 173 | 174 | /* -------------- LB_CHOOSE Message -------------- */ 175 | static void LBChooseMsg(WINDOW wnd, PARAM p1) 176 | { 177 | struct PopDown *ActivePopDown = wnd->mnu->Selections; 178 | if (ActivePopDown != NULL) { 179 | int *attr = &(ActivePopDown+(int)p1)->Attrib; 180 | wnd->mnu->Selection = (int)p1; 181 | if (!(*attr & INACTIVE)) { 182 | WINDOW pwnd = GetParent(wnd); 183 | if (*attr & TOGGLE) 184 | *attr ^= CHECKED; 185 | if (pwnd != NULL) { 186 | CurrentMenuSelection = p1; 187 | PostMessage(pwnd, COMMAND, 188 | (ActivePopDown+(int)p1)->ActionId, 0); /* p2 was p1 */ 189 | } 190 | } 191 | else 192 | beep(); 193 | } 194 | } 195 | 196 | /* ---------- KEYBOARD Message --------- */ 197 | static BOOL KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2) 198 | { 199 | struct PopDown *ActivePopDown = wnd->mnu->Selections; 200 | if (wnd->mnu != NULL) { 201 | if (ActivePopDown != NULL) { 202 | int c = (int)p1; 203 | int sel = 0; 204 | int a; 205 | struct PopDown *pd = ActivePopDown; 206 | 207 | if ((c & OFFSET) == 0) 208 | c = tolower(c); 209 | a = AltConvert(c); 210 | 211 | while (pd->SelectionTitle != NULL) { 212 | char *cp = strchr(pd->SelectionTitle, 213 | SHORTCUTCHAR); 214 | if (cp) { 215 | int sc = tolower(*(cp+1)); 216 | if ((cp && sc == c) || 217 | (a && sc == a) || 218 | pd->Accelerator == c) { 219 | PostMessage(wnd, LB_SELECTION, sel, 0); 220 | PostMessage(wnd, LB_CHOOSE, sel, TRUE); 221 | return TRUE; 222 | } 223 | } 224 | pd++, sel++; 225 | } 226 | } 227 | } 228 | switch ((int)p1) { 229 | case F1: 230 | if (ActivePopDown == NULL) 231 | SendMessage(GetParent(wnd), KEYBOARD, p1, p2); 232 | else 233 | DisplayHelp(wnd, 234 | (ActivePopDown+wnd->selection)->help); 235 | return TRUE; 236 | case ESC: 237 | SendMessage(wnd, CLOSE_WINDOW, 0, 0); 238 | return TRUE; 239 | case FWD: 240 | case BS: 241 | if (GetClass(GetParent(wnd)) == MENUBAR) 242 | PostMessage(GetParent(wnd), KEYBOARD, p1, p2); 243 | return TRUE; 244 | case UP: 245 | if (wnd->selection == 0) { 246 | if (wnd->wlines == ClientHeight(wnd)) { 247 | PostMessage(wnd, LB_SELECTION, 248 | wnd->wlines-1, FALSE); 249 | return TRUE; 250 | } 251 | } 252 | break; 253 | case DN: 254 | if (wnd->selection == wnd->wlines-1) { 255 | if (wnd->wlines == ClientHeight(wnd)) { 256 | PostMessage(wnd, LB_SELECTION, 0, FALSE); 257 | return TRUE; 258 | } 259 | } 260 | break; 261 | case HOME: 262 | case END: 263 | case '\r': 264 | break; 265 | default: 266 | return TRUE; 267 | } 268 | return FALSE; 269 | } 270 | 271 | /* ----------- CLOSE_WINDOW Message ---------- */ 272 | static int CloseWindowMsg(WINDOW wnd) 273 | { 274 | int rtn; 275 | WINDOW pwnd = GetParent(wnd); 276 | SendMessage(wnd, RELEASE_MOUSE, 0, 0); 277 | SendMessage(wnd, RELEASE_KEYBOARD, 0, 0); 278 | SendMessage(NULL, RESTORE_CURSOR, 0, 0); 279 | inFocus = wnd->oldFocus; 280 | rtn = BaseWndProc(POPDOWNMENU, wnd, CLOSE_WINDOW, 0, 0); 281 | SendMessage(pwnd, CLOSE_POPDOWN, 0, 0); 282 | return rtn; 283 | } 284 | 285 | /* - Window processing module for POPDOWNMENU window class - */ 286 | int PopDownProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 287 | { 288 | switch (msg) { 289 | case CREATE_WINDOW: 290 | return CreateWindowMsg(wnd); 291 | case LEFT_BUTTON: 292 | LeftButtonMsg(wnd, p1, p2); 293 | return FALSE; 294 | case DOUBLE_CLICK: 295 | return TRUE; 296 | case LB_SELECTION: 297 | if (*TextLine(wnd, (int)p1) == LINE) 298 | return TRUE; 299 | wnd->mnu->Selection = (int)p1; 300 | break; 301 | case BUTTON_RELEASED: 302 | if (ButtonReleasedMsg(wnd, p1, p2)) 303 | return TRUE; 304 | break; 305 | case BUILD_SELECTIONS: 306 | wnd->mnu = (void *) p1; 307 | wnd->selection = wnd->mnu->Selection; 308 | break; 309 | case PAINT: 310 | if (wnd->mnu == NULL) 311 | return TRUE; 312 | PaintMsg(wnd); 313 | break; 314 | case BORDER: 315 | return BorderMsg(wnd); 316 | case LB_CHOOSE: 317 | LBChooseMsg(wnd, p1); 318 | return TRUE; 319 | case KEYBOARD: 320 | if (KeyboardMsg(wnd, p1, p2)) 321 | return TRUE; 322 | break; 323 | case CLOSE_WINDOW: 324 | return CloseWindowMsg(wnd); 325 | default: 326 | break; 327 | } 328 | return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2); 329 | } 330 | 331 | /* --------- compute menu height -------- */ 332 | int MenuHeight(struct PopDown *pd) 333 | { 334 | int ht = 0; 335 | while (pd[ht].SelectionTitle != NULL) 336 | ht++; 337 | return ht+2; 338 | } 339 | 340 | /* --------- compute menu width -------- */ 341 | int MenuWidth(struct PopDown *pd) 342 | { 343 | int wd = 0, i; 344 | int len = 0; 345 | 346 | wd = SelectionWidth(pd); 347 | while (pd->SelectionTitle != NULL) { 348 | if (pd->Accelerator) { 349 | for (i = 0; keys[i].keylabel; i++) 350 | if (keys[i].keycode == pd->Accelerator) { 351 | len = max(len, 2+strlen(keys[i].keylabel)); 352 | break; 353 | } 354 | } 355 | if (pd->Attrib & CASCADED) 356 | len = max(len, 2); 357 | pd++; 358 | } 359 | return wd+5+len; 360 | } 361 | 362 | /* ---- compute the maximum selection width in a menu ---- */ 363 | static int SelectionWidth(struct PopDown *pd) 364 | { 365 | int wd = 0; 366 | while (pd->SelectionTitle != NULL) { 367 | int len = strlen(pd->SelectionTitle)-1; 368 | wd = max(wd, len); 369 | pd++; 370 | } 371 | return wd; 372 | } 373 | 374 | /* ----- copy a menu command to a display buffer ---- */ 375 | int CopyCommand(unsigned char *dest, unsigned char *src, 376 | int skipcolor, int bg) 377 | { 378 | unsigned char *d = dest; 379 | while (*src && *src != '\n') { 380 | if (*src == SHORTCUTCHAR) { 381 | src++; 382 | if (!skipcolor) { 383 | *dest++ = CHANGECOLOR; 384 | *dest++ = cfg.clr[POPDOWNMENU] 385 | [HILITE_COLOR] [BG] | 0x80; 386 | *dest++ = bg | 0x80; 387 | *dest++ = *src++; 388 | *dest++ = RESETCOLOR; 389 | } 390 | } 391 | else 392 | *dest++ = *src++; 393 | } 394 | return (int) (dest - d); 395 | } 396 | -------------------------------------------------------------------------------- /radio.c: -------------------------------------------------------------------------------- 1 | /* -------- radio.c -------- */ 2 | 3 | #include "dflat.h" 4 | 5 | static CTLWINDOW *rct[MAXRADIOS]; 6 | 7 | int RadioButtonProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 8 | { 9 | int rtn; 10 | DBOX *db = GetParent(wnd)->extension; 11 | CTLWINDOW *ct = GetControl(wnd); 12 | if (ct != NULL) { 13 | switch (msg) { 14 | case SETFOCUS: 15 | if (!(int)p1) 16 | SendMessage(NULL, HIDE_CURSOR, 0, 0); 17 | case MOVE: 18 | rtn = BaseWndProc(RADIOBUTTON,wnd,msg,p1,p2); 19 | SetFocusCursor(wnd); 20 | return rtn; 21 | case PAINT: { 22 | char rb[] = "( )"; 23 | if (ct->setting) 24 | rb[1] = 7; 25 | SendMessage(wnd, CLEARTEXT, 0, 0); 26 | SendMessage(wnd, ADDTEXT, (PARAM) rb, 0); 27 | SetFocusCursor(wnd); 28 | break; 29 | } 30 | case KEYBOARD: 31 | if ((int)p1 != ' ') 32 | break; 33 | case LEFT_BUTTON: 34 | SetRadioButton(db, ct); 35 | break; 36 | default: 37 | break; 38 | } 39 | } 40 | return BaseWndProc(RADIOBUTTON, wnd, msg, p1, p2); 41 | } 42 | 43 | static BOOL Setting = TRUE; 44 | 45 | void SetRadioButton(DBOX *db, CTLWINDOW *ct) 46 | { 47 | Setting = FALSE; 48 | PushRadioButton(db, ct->command); 49 | Setting = TRUE; 50 | } 51 | 52 | void PushRadioButton(DBOX *db, enum commands cmd) 53 | { 54 | CTLWINDOW *ctt = db->ctl; 55 | CTLWINDOW *ct = FindCommand(db, cmd, RADIOBUTTON); 56 | int i; 57 | 58 | if (ct == NULL) 59 | return; 60 | 61 | /* --- clear all the radio buttons 62 | in this group on the dialog box --- */ 63 | 64 | /* -------- build a table of all radio buttons at the 65 | same x vector ---------- */ 66 | for (i = 0; i < MAXRADIOS; i++) 67 | rct[i] = NULL; 68 | while (ctt->Class) { 69 | if (ctt->Class == RADIOBUTTON) 70 | if (ct->dwnd.x == ctt->dwnd.x) 71 | rct[ctt->dwnd.y] = ctt; 72 | ctt++; 73 | } 74 | 75 | /* ----- find the start of the radiobutton group ---- */ 76 | i = ct->dwnd.y; 77 | while (i >= 0 && rct[i] != NULL) 78 | --i; 79 | /* ---- ignore everthing before the group ------ */ 80 | while (i >= 0) 81 | rct[i--] = NULL; 82 | 83 | /* ----- find the end of the radiobutton group ---- */ 84 | i = ct->dwnd.y; 85 | while (i < MAXRADIOS && rct[i] != NULL) 86 | i++; 87 | /* ---- ignore everthing past the group ------ */ 88 | while (i < MAXRADIOS) 89 | rct[i++] = NULL; 90 | 91 | for (i = 0; i < MAXRADIOS; i++) { 92 | if (rct[i] != NULL) { 93 | int wason = rct[i]->setting; 94 | rct[i]->setting = OFF; 95 | if (Setting) 96 | rct[i]->isetting = OFF; 97 | if (wason) 98 | SendMessage(rct[i]->wnd, PAINT, 0, 0); 99 | } 100 | } 101 | /* ----- set the specified radio button on ----- */ 102 | ct->setting = ON; 103 | if (Setting) 104 | ct->isetting = ON; 105 | SendMessage(ct->wnd, PAINT, 0, 0); 106 | } 107 | 108 | BOOL RadioButtonSetting(DBOX *db, enum commands cmd) 109 | { 110 | CTLWINDOW *ct = FindCommand(db, cmd, RADIOBUTTON); 111 | return ct ? (ct->wnd ? (ct->setting==ON) : (ct->isetting==ON)) : FALSE; 112 | } 113 | -------------------------------------------------------------------------------- /readme.doc: -------------------------------------------------------------------------------- 1 | D-Flat has been adapted for compilation with the Smaller C compiler 2 | (https://github.com/alexfru/SmallerC). See compilin.txt on how to 3 | compile the D-Flat library and the MemoPad demo application for DOS 4 | with Smaller C. 5 | 6 | ======================================================= 7 | 8 | February, 1995 9 | 10 | D-Flat Version 20 11 | 12 | The source files in the DFLAT archive constitute the D-Flat windowing 13 | system. This is public domain code. You may use it in your 14 | applications without restriction. You may freely distribute source 15 | code. It would be nice if you would give credit to Dr. Dobb's Journal 16 | as the original publisher of the source code. 17 | 18 | The software build procedure makes a program named memopad.exe. It is 19 | a multiple-document notepad program. Observe the #define VERSION 20 | statement in dflat.h. The version number should correspond with the 21 | nn in the DFLTnn.ZIP filename that you downloaded. Check the uploads 22 | periodically to see if there is a more recent version available. 23 | 24 | For other examples download the Quincy and IMail applications. The 25 | IMail application uses the DFWRAP C++ class wrapper. 26 | 27 | My CompuServe ID is 71101,1262. I monitor the DDJFORUM every day and 28 | prefer that you discuss D-Flat there so that every one can benefit 29 | from your comments. 30 | 31 | Al Stevens 32 | 33 | ========== Turbo C++ 1.01 ============ 34 | 35 | To build with the Turbo C++ 1.01 make utility: 36 | 37 | Set the DRIVE macro in the makefile to the drive and directory 38 | where your compiler is installed. 39 | 40 | Type this command: 41 | 42 | C>make /fmakefile.tcc 43 | 44 | ========== Borland C++ 3.1 or 4.0 ============ 45 | 46 | To build with the Borland C++ 3.1 or 4.x make utility: 47 | 48 | Set the DRIVE macro in the makefile to the drive and directory 49 | where your compiler is installed. 50 | 51 | Type this command: 52 | 53 | C>make /fmakefile.bcc 54 | 55 | ========== (OPEN) WATCOM C ============ 56 | 57 | To build with Watcom C 8.0 or Open Watcom C 1.9, type this command: 58 | 59 | C>wmake /f makefile.wat 60 | 61 | ======================================================= 62 | 63 | D-Flat uses Compressed help files. It uses an adaptation of the 64 | Huffman compression programs from the Dr. Dobb's Journal C 65 | Programming Column of early 1991. 66 | 67 | The makefile compresses the help file with these commands: 68 | 69 | C>huffc memopad.txt memopad.hlp 70 | C>fixhelp memopad.hlp 71 | 72 | Both of the programs must be run in order for the help system to work 73 | properly. Note that .hlp files from previous versions are not 74 | compatible with versions 18 and higher. The .txt files are, however, 75 | so you can use the huffc and fixhelp programs to rebuild the .hlp 76 | file. 77 | 78 | =============================================== 79 | 80 | This is version 20. It incorporates these changes: 81 | 82 | 1. Dialog boxes displayed twice upon open. 83 | 84 | 2. The intended #define of FA_DIREC in direct.c was inadvertently 85 | released with #include as the preprocessing directive. 86 | 87 | 3. Changed status bar to display time after screen takeover. 88 | 89 | 4. Statbar incorrectly captured clock with every MOVE message. Caused 90 | hangups when compiled with BCC 3.1 and user moved application window. 91 | 92 | 5. Modeless dialog boxes did not redisplay properly when there was 93 | more than one window open. 94 | 95 | 6. Added ButtonEnabled and CheckBoxEnabled functions. 96 | 97 | 7. Changed LB_SETSELECTION message to accept -1 to turn off 98 | selections in the listbox. 99 | 100 | 8. Moved processing of ID_SEARCH, ID_SEARCHNEXT, ID_REPLACE, ID_CUT, 101 | ID_COPY, ID_PASTE, ID_DELETETEXT, ID_UNDO, and ID_CLEAR to editbox.c, 102 | relieving applications of these common processes. 103 | 104 | 9. Now allow marking blocks, cut, copy, paste, etc. on single line 105 | editboxes. 106 | 107 | 10. Added SetProtect function. 108 | 109 | 11. The Window menu listed doc windows that were not visible. 110 | 111 | 12. Changed class identifiers to Class. 112 | 113 | 13. ClearWindow did not work properly for a window with a status bar 114 | and menu bar and no title bar. 115 | 116 | 14. Added the void *wrapper field to the window structure to support 117 | a C++ class wrapper around the D-Flat C function library. 118 | 119 | 15. Sizeable windows with borders now display a small token in the 120 | lower right corner to indicate that they are sizeable. 121 | 122 | =============================================== 123 | 124 | Buy the DDJ CD-ROM from Miller-Freeman to get the complete D-Flat 125 | narrative from May '91 to October '92. These columns describe the 126 | development of D-Flat and serve as a tutorial on its use. The D-Flat 127 | reference manual is DFLAT.DOC. 128 | -------------------------------------------------------------------------------- /rect.c: -------------------------------------------------------------------------------- 1 | /* ------------- rect.c --------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | /* --- Produce the vector end points produced by the overlap 6 | of two other vectors --- */ 7 | static void subVector(int *v1, int *v2, 8 | int t1, int t2, int o1, int o2) 9 | { 10 | *v1 = *v2 = -1; 11 | if (within(o1, t1, t2)) { 12 | *v1 = o1; 13 | if (within(o2, t1, t2)) 14 | *v2 = o2; 15 | else 16 | *v2 = t2; 17 | } 18 | else if (within(o2, t1, t2)) { 19 | *v2 = o2; 20 | if (within(o1, t1, t2)) 21 | *v1 = o1; 22 | else 23 | *v1 = t1; 24 | } 25 | else if (within(t1, o1, o2)) { 26 | *v1 = t1; 27 | if (within(t2, o1, o2)) 28 | *v2 = t2; 29 | else 30 | *v2 = o2; 31 | } 32 | else if (within(t2, o1, o2)) { 33 | *v2 = t2; 34 | if (within(t1, o1, o2)) 35 | *v1 = t1; 36 | else 37 | *v1 = o1; 38 | } 39 | } 40 | 41 | /* --- Return the rectangle produced by the overlap 42 | of two other rectangles ---- */ 43 | RECT subRectangle(RECT r1, RECT r2) 44 | { 45 | RECT r = {0,0,0,0}; 46 | subVector((int *) &RectLeft(r), (int *) &RectRight(r), 47 | RectLeft(r1), RectRight(r1), 48 | RectLeft(r2), RectRight(r2)); 49 | subVector((int *) &RectTop(r), (int *) &RectBottom(r), 50 | RectTop(r1), RectBottom(r1), 51 | RectTop(r2), RectBottom(r2)); 52 | if (RectRight(r) == -1 || RectTop(r) == -1) 53 | RectRight(r) = 54 | RectLeft(r) = 55 | RectTop(r) = 56 | RectBottom(r) = 0; 57 | return r; 58 | } 59 | 60 | /* ------- return the client rectangle of a window ------ */ 61 | RECT ClientRect(void *wnd) 62 | { 63 | RECT rc; 64 | 65 | RectLeft(rc) = GetClientLeft((WINDOW)wnd); 66 | RectTop(rc) = GetClientTop((WINDOW)wnd); 67 | RectRight(rc) = GetClientRight((WINDOW)wnd); 68 | RectBottom(rc) = GetClientBottom((WINDOW)wnd); 69 | return rc; 70 | } 71 | 72 | /* ----- return the rectangle relative to 73 | its window's screen position -------- */ 74 | RECT RelativeWindowRect(void *wnd, RECT rc) 75 | { 76 | RectLeft(rc) -= GetLeft((WINDOW)wnd); 77 | RectRight(rc) -= GetLeft((WINDOW)wnd); 78 | RectTop(rc) -= GetTop((WINDOW)wnd); 79 | RectBottom(rc) -= GetTop((WINDOW)wnd); 80 | return rc; 81 | } 82 | 83 | /* ----- clip a rectangle to the parents of the window ----- */ 84 | RECT ClipRectangle(void *wnd, RECT rc) 85 | { 86 | RECT sr; 87 | RectLeft(sr) = RectTop(sr) = 0; 88 | RectRight(sr) = SCREENWIDTH-1; 89 | RectBottom(sr) = SCREENHEIGHT-1; 90 | if (!TestAttribute((WINDOW)wnd, NOCLIP)) 91 | while ((wnd = GetParent((WINDOW)wnd)) != NULL) 92 | rc = subRectangle(rc, ClientRect(wnd)); 93 | return subRectangle(rc, sr); 94 | } 95 | -------------------------------------------------------------------------------- /rect.h: -------------------------------------------------------------------------------- 1 | /* ----------- rect.h ------------ */ 2 | #ifndef RECT_H 3 | #define RECT_H 4 | 5 | typedef struct { 6 | int lf,tp,rt,bt; 7 | } RECT; 8 | #define within(p,v1,v2) ((p)>=(v1)&&(p)<=(v2)) 9 | #define RectTop(r) (r.tp) 10 | #define RectBottom(r) (r.bt) 11 | #define RectLeft(r) (r.lf) 12 | #define RectRight(r) (r.rt) 13 | #define InsideRect(x,y,r) (within((x),RectLeft(r),RectRight(r))\ 14 | && \ 15 | within((y),RectTop(r),RectBottom(r))) 16 | #define ValidRect(r) (RectRight(r) || RectLeft(r) || \ 17 | RectTop(r) || RectBottom(r)) 18 | #define RectWidth(r) (RectRight(r)-RectLeft(r)+1) 19 | #define RectHeight(r) (RectBottom(r)-RectTop(r)+1) 20 | RECT subRectangle(RECT, RECT); 21 | RECT ClientRect(void *); 22 | RECT RelativeWindowRect(void *, RECT); 23 | RECT ClipRectangle(void *, RECT); 24 | #endif 25 | -------------------------------------------------------------------------------- /scdos.c: -------------------------------------------------------------------------------- 1 | /* 2 | Select non-standard functionality commonly available in C compilers 3 | for DOS in , , , , , which 4 | is not (yet?) provided by Smaller C's library. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "scdos.h" 12 | 13 | #ifndef __HUGE__ 14 | #ifndef __UNREAL__ 15 | #error This program requires the huge or unreal mode(l) 16 | #endif 17 | #endif 18 | 19 | unsigned char inportb(int port) 20 | { 21 | asm("mov dx, [bp+8]\n" 22 | "in al, dx\n" 23 | "movzx eax, al"); 24 | } 25 | 26 | void outportb(int port, unsigned char value) 27 | { 28 | asm("mov dx, [bp+8]\n" 29 | "mov al, [bp+12]\n" 30 | "out dx, al"); 31 | } 32 | 33 | void setvect(int intno, void __interrupt isr()) 34 | { 35 | unsigned addr = (unsigned)isr; 36 | unsigned ofs = (addr >> 20 << 4) | (addr & 0xF); 37 | unsigned seg = (addr >> 4) & 0xFFFF; 38 | asm("pushfd\n" 39 | "cli"); 40 | poke(0, intno * 4, ofs); 41 | poke(0, intno * 4 + 2, seg); 42 | asm("popfd"); 43 | } 44 | 45 | void __interrupt (*getvect(int intno))() 46 | { 47 | asm("pushfd\n" 48 | "cli"); 49 | unsigned ofs = peek(0, intno * 4); 50 | unsigned seg = peek(0, intno * 4 + 2); 51 | unsigned addr = (ofs & 0xF) | (seg << 4) | (ofs >> 4 << 20); 52 | asm("popfd"); 53 | return (void __interrupt (*)())addr; 54 | } 55 | 56 | /* Calls the old ISR from the new ISR */ 57 | void callisr(void __interrupt isr()) 58 | { 59 | asm("pushfd\n" 60 | "cli\n" 61 | "rol dword [bp + 8], 12\n" 62 | "rol word [bp + 8], 4\n" 63 | "pushf\n" 64 | "call far [bp + 8]\n" 65 | "popfd"); 66 | } 67 | 68 | int stricmp(char* s1, char* s2) 69 | { 70 | while (toupper((unsigned char)*s1) == toupper((unsigned char)*s2)) 71 | { 72 | if (!*s1) 73 | return 0; 74 | ++s1; 75 | ++s2; 76 | } 77 | 78 | return ((unsigned char)*s1) - ((unsigned char)*s2); 79 | } 80 | 81 | void movedata(unsigned srcseg, unsigned srcoff, unsigned dstseg, unsigned dstoff, unsigned n) 82 | { 83 | memcpy(MK_FP(dstseg, dstoff), MK_FP(srcseg, srcoff), n); 84 | } 85 | 86 | /* REGS: unsigned short ax, bx, cx, dx, si, di, cflag, flags */ 87 | int int86(int intno, union REGS* inregs, union REGS* outregs) 88 | { 89 | asm(" db 0x66, 0x68\n" /* push dword next */ 90 | "patch_next:\n" 91 | " dd next\n" 92 | "section .relot\n" 93 | " dd patch_next\n" 94 | 95 | "section .text\n" 96 | " movzx ax, byte [bp+8]\n" 97 | " shl eax, 16\n" 98 | " or eax, 0xEA00CD90\n" /* nop; int intno; jmp far absolute next */ 99 | " push eax\n" 100 | " mov ax, sp\n" 101 | " push ebp\n" 102 | " push ss\n" 103 | " push ax\n" 104 | 105 | " mov edi, [bp+12]\n" 106 | " ror edi, 4\n" 107 | " mov ds, di\n" 108 | " shr edi, 28\n" 109 | " mov ax, [di]\n" 110 | " mov bx, [di+2]\n" 111 | " mov cx, [di+4]\n" 112 | " mov dx, [di+6]\n" 113 | " mov si, [di+8]\n" 114 | " mov di, [di+10]\n" 115 | 116 | " retf\n" 117 | "next:\n" 118 | " pop ebp\n" 119 | " pushf\n" 120 | " mov [bp+8], di\n" 121 | " pop word [bp+12]\n" 122 | " mov edi, [bp+16]\n" 123 | " ror edi, 4\n" 124 | " mov ds, di\n" 125 | " shr edi, 28\n" 126 | " mov [di], ax\n" 127 | " mov [di+2], bx\n" 128 | " mov [di+4], cx\n" 129 | " mov [di+6], dx\n" 130 | " mov [di+8], si\n" 131 | " mov bx, [bp+8]\n" 132 | " mov [di+10], bx\n" 133 | " mov bx, [bp+12]\n" 134 | " mov [di+14], bx\n" 135 | " and bx, 1\n" 136 | " mov [di+12], bx\n" 137 | 138 | " add sp, 8\n" 139 | " movzx eax, ax"); 140 | 141 | #ifdef __UNREAL__ 142 | asm("push dword 0\n" 143 | "pop es\n" 144 | "pop ds"); 145 | #endif 146 | } 147 | 148 | int kbhit(void) 149 | { 150 | asm("mov ah, 1\n" 151 | "int 0x16\n" 152 | "setnz al\n" 153 | "movzx eax, al"); 154 | } 155 | 156 | int bioskey(int cmd) 157 | { 158 | assert(cmd == 0); 159 | asm("mov ah, 0\n" 160 | "int 0x16\n" 161 | "movzx eax, ax"); 162 | } 163 | 164 | int getdisk(void) 165 | { 166 | asm("mov ah, 0x19\n" 167 | "int 0x21\n" 168 | "movzx eax, al"); 169 | } 170 | 171 | int setdisk(int drive) 172 | { 173 | asm("mov ah, 0xE\n" 174 | "mov dl, [bp+8]\n" 175 | "int 0x21\n" 176 | "movzx eax, al"); 177 | } 178 | 179 | static 180 | int DosGetCurDir(char buf[64], int drive, unsigned* error) 181 | { 182 | asm("mov ah, 0x47\n" 183 | "mov esi, [bp + 8]\n" 184 | "ror esi, 4\n" 185 | "mov ds, si\n" 186 | "shr esi, 28\n" 187 | "mov dl, [bp + 12]\n" 188 | "int 0x21"); 189 | asm("movzx ebx, ax\n" 190 | "cmc\n" 191 | "sbb ax, ax\n" 192 | "and eax, 1\n" 193 | "mov esi, [bp + 16]"); 194 | #ifdef __HUGE__ 195 | asm("ror esi, 4\n" 196 | "mov ds, si\n" 197 | "shr esi, 28\n" 198 | "mov [si], ebx"); 199 | #else 200 | asm("push word 0\n" 201 | "pop ds\n" 202 | "mov [esi], ebx"); 203 | #endif 204 | } 205 | 206 | char* getcwd(char* buf, int len) 207 | { 208 | /* Not setting errno! */ 209 | char b[3 + 64]; 210 | unsigned err; 211 | int l; 212 | b[0] = getdisk() + 'A'; 213 | b[1] = ':'; 214 | b[2] = '\\'; 215 | if (!DosGetCurDir(b + 3, 0/*current drive*/, &err)) 216 | return NULL; 217 | l = strlen(b) + 1; 218 | if (!buf) 219 | { 220 | if (!(buf = malloc(l))) 221 | return NULL; 222 | } 223 | else if (len < l) 224 | { 225 | return NULL; 226 | } 227 | return memcpy(buf, b, l); 228 | } 229 | 230 | static 231 | int DosChDir(char* path, unsigned* error) 232 | { 233 | asm("mov ah, 0x3B\n" 234 | "mov edx, [bp + 8]\n" 235 | "ror edx, 4\n" 236 | "mov ds, dx\n" 237 | "shr edx, 28\n" 238 | "int 0x21"); 239 | asm("movzx ebx, ax\n" 240 | "cmc\n" 241 | "sbb ax, ax\n" 242 | "and eax, 1\n" 243 | "mov esi, [bp + 12]"); 244 | #ifdef __HUGE__ 245 | asm("ror esi, 4\n" 246 | "mov ds, si\n" 247 | "shr esi, 28\n" 248 | "mov [si], ebx"); 249 | #else 250 | asm("push word 0\n" 251 | "pop ds\n" 252 | "mov [esi], ebx"); 253 | #endif 254 | } 255 | 256 | int chdir(char* path) 257 | { 258 | /* Not setting errno! */ 259 | unsigned err; 260 | if (!path || !DosChDir(path, &err)) 261 | return -1; 262 | return 0; 263 | } 264 | 265 | static 266 | void DosSetDTA(struct ffblk* dta) 267 | { 268 | asm("mov ah, 0x1A\n" 269 | "mov edx, [bp + 8]\n" 270 | "ror edx, 4\n" 271 | "mov ds, dx\n" 272 | "shr edx, 28\n" 273 | "int 0x21"); 274 | #ifdef __UNREAL__ 275 | asm("push word 0\n" 276 | "pop ds"); 277 | #endif 278 | } 279 | 280 | static 281 | int DosFindFirst(char* path, int attr, unsigned* error) 282 | { 283 | asm("mov ah, 0x4E\n" 284 | "mov edx, [bp + 8]\n" 285 | "ror edx, 4\n" 286 | "mov ds, dx\n" 287 | "shr edx, 28\n" 288 | "mov cx, [bp + 12]\n" 289 | "int 0x21"); 290 | asm("movzx ebx, ax\n" 291 | "cmc\n" 292 | "sbb ax, ax\n" 293 | "and eax, 1\n" 294 | "mov esi, [bp + 16]"); 295 | #ifdef __HUGE__ 296 | asm("ror esi, 4\n" 297 | "mov ds, si\n" 298 | "shr esi, 28\n" 299 | "mov [si], ebx"); 300 | #else 301 | asm("push word 0\n" 302 | "pop ds\n" 303 | "mov [esi], ebx"); 304 | #endif 305 | } 306 | 307 | static 308 | int DosFindNext(struct ffblk* dta, unsigned* error) 309 | { 310 | asm("mov ah, 0x4F\n" 311 | "mov edx, [bp + 8]\n" 312 | "ror edx, 4\n" 313 | "mov ds, dx\n" 314 | "shr edx, 28\n" 315 | "int 0x21"); 316 | asm("movzx ebx, ax\n" 317 | "cmc\n" 318 | "sbb ax, ax\n" 319 | "and eax, 1\n" 320 | "mov esi, [bp + 12]"); 321 | #ifdef __HUGE__ 322 | asm("ror esi, 4\n" 323 | "mov ds, si\n" 324 | "shr esi, 28\n" 325 | "mov [si], ebx"); 326 | #else 327 | asm("push word 0\n" 328 | "pop ds\n" 329 | "mov [esi], ebx"); 330 | #endif 331 | } 332 | 333 | int findfirst(char* path, struct ffblk* ffblk, int attrib) 334 | { 335 | unsigned err; 336 | if (!path || !ffblk) 337 | return -1; 338 | DosSetDTA(ffblk); 339 | if (!DosFindFirst(path, attrib, &err)) 340 | return -1; 341 | return 0; 342 | } 343 | 344 | int findnext(struct ffblk* ffblk) 345 | { 346 | unsigned err; 347 | if (!ffblk || !DosFindNext(ffblk, &err)) 348 | return -1; 349 | return 0; 350 | } 351 | 352 | void fnmerge(char* path, char* drive, char* dir, char* name, char* ext) 353 | { 354 | if (drive && *drive) 355 | { 356 | *path++ = *drive; 357 | *path++ = ':'; 358 | } 359 | if (dir && *dir) 360 | { 361 | size_t len = strlen(dir); 362 | int c = dir[len - 1]; 363 | memcpy(path, dir, len); 364 | path += len; 365 | if (c != '\\' && c != '/') 366 | *path++ = '\\'; 367 | } 368 | if (name && *name) 369 | { 370 | size_t len = strlen(name); 371 | memcpy(path, name, len); 372 | path += len; 373 | } 374 | if (ext && *ext) 375 | { 376 | size_t len = strlen(ext); 377 | if (*ext != '.') 378 | *path++ = '.'; 379 | memcpy(path, ext, len); 380 | path += len; 381 | } 382 | *path = '\0'; 383 | } 384 | 385 | int fnsplit(char* path, char* drive, char* dir, char* name, char* ext) 386 | { 387 | int flags = 0; 388 | char* p = path; 389 | 390 | if (drive) 391 | *drive = '\0'; 392 | if (dir) 393 | *dir = '\0'; 394 | if (name) 395 | *name = '\0'; 396 | if (ext) 397 | *ext = '\0'; 398 | 399 | if (isalpha((unsigned char)*p) && p[1] == ':') 400 | { 401 | if (drive) 402 | { 403 | *drive++ = *p++; 404 | *drive++ = *p++; 405 | *drive = '\0'; 406 | } 407 | flags |= DRIVE; 408 | } 409 | 410 | { 411 | char* lastSlash = strrchr(p, '/'); 412 | char* lastBackslash = strrchr(p, '\\'); 413 | char* dirEnd; 414 | /* Find the last (back)slash, if any. */ 415 | if (lastSlash && lastBackslash) 416 | dirEnd = (lastSlash < lastBackslash) ? lastBackslash : lastSlash; 417 | else 418 | dirEnd = lastBackslash ? lastBackslash : lastSlash; 419 | if (dirEnd) 420 | { 421 | size_t len = dirEnd - p + 1; 422 | if (dir) 423 | { 424 | memcpy(dir, p, len); 425 | dir[len] = '\0'; 426 | } 427 | p += len; 428 | flags |= DIRECTORY; 429 | } 430 | } 431 | 432 | { 433 | /* "." and ".." are directory names, not extensions. */ 434 | size_t len = 0; 435 | if (*p == '.') 436 | { 437 | if (p[1] == '\0') 438 | len = 1; 439 | else if (p[1] == '.' && p[2] == '\0') 440 | len = 2; 441 | } 442 | /* Filename is before the last dot, if any. */ 443 | if (!len) 444 | { 445 | char* lastDot = strrchr(p, '.'); 446 | len = lastDot ? (size_t)(lastDot - p) : strlen(p); 447 | } 448 | if (len) 449 | { 450 | if (name) 451 | { 452 | memcpy(name, p, len); 453 | name[len] = '\0'; 454 | } 455 | p += len; 456 | flags |= FILENAME; 457 | } 458 | } 459 | 460 | if (*p == '.') 461 | { 462 | if (ext) 463 | strcpy(ext, p); 464 | flags |= EXTENSION; 465 | } 466 | 467 | if (path[strcspn(path, "?*")]) 468 | flags |= WILDCARDS; 469 | 470 | return flags; 471 | } 472 | -------------------------------------------------------------------------------- /scdos.h: -------------------------------------------------------------------------------- 1 | /* 2 | Select non-standard functionality commonly available in C compilers 3 | for DOS in , , , , , which 4 | is not (yet?) provided by Smaller C's library. 5 | */ 6 | 7 | #ifndef __DOS_H 8 | #define __DOS_H 9 | 10 | #define far 11 | #define near 12 | #define interrupt __interrupt 13 | 14 | /* max() and min() may come from */ 15 | #define max(a,b) (((a) > (b)) ? (a) : (b)) 16 | #define min(a,b) (((a) < (b)) ? (a) : (b)) 17 | 18 | #define FP_OFF(p) ((unsigned long)(p) & 0xF) 19 | #define FP_SEG(p) ((unsigned)((unsigned long)(p) >> 4)) 20 | #define MK_FP(s,o) ((void*)(((unsigned long)(s) << 4) + (unsigned)(o))) 21 | 22 | #define poke(a,b,c) (*((unsigned short far*)MK_FP((a),(b))) = (c)) 23 | #define pokeb(a,b,c) (*((unsigned char far*)MK_FP((a),(b))) = (c)) 24 | #define peek(a,b) (*((unsigned short far*)MK_FP((a),(b)))) 25 | #define peekb(a,b) (*((unsigned char far*)MK_FP((a),(b)))) 26 | 27 | #define MAXPATH 80 28 | #define MAXDRIVE 3 29 | #define MAXDIR 66 30 | #define MAXFILE 9 31 | #define MAXEXT 5 32 | 33 | #define WILDCARDS 0x01 34 | #define EXTENSION 0x02 35 | #define FILENAME 0x04 36 | #define DIRECTORY 0x08 37 | #define DRIVE 0x10 38 | 39 | #pragma pack(push, 1) 40 | struct ffblk /* AKA Disk Transfer Address (DTA) */ 41 | { 42 | char ff_reserved[21]; 43 | char ff_attrib; 44 | unsigned short ff_ftime; 45 | unsigned short ff_fdate; 46 | long ff_fsize; 47 | char ff_name[13]; 48 | }; 49 | #pragma pack(pop) 50 | 51 | struct WORDREGS 52 | { 53 | unsigned short ax, bx, cx, dx, si, di, cflag, flags; 54 | }; 55 | 56 | struct BYTEREGS 57 | { 58 | unsigned char al, ah, bl, bh, cl, ch, dl, dh; 59 | }; 60 | 61 | union REGS 62 | { 63 | struct WORDREGS x; 64 | struct BYTEREGS h; 65 | }; 66 | 67 | struct INTREGS 68 | { 69 | unsigned short gs, fs, es, ds; 70 | unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax; 71 | unsigned short ss, ip, cs, flags; 72 | }; 73 | 74 | unsigned char inportb(int port); 75 | void outportb(int port, unsigned char value); 76 | #define inp(port) inportb(port) 77 | #define outp(port,val) outportb(port,val) 78 | 79 | int int86(int intno, union REGS* inregs, union REGS* outregs); 80 | 81 | int kbhit(void); 82 | int bioskey(int cmd); 83 | 84 | #ifdef _DOS 85 | /* 86 | This header file is pulled by the huffc and fixhelp tools. 87 | In case they're not compiled for DOS, __interrupt won't be recognized. 88 | */ 89 | void setvect(int intno, void __interrupt isr()); 90 | void __interrupt (*getvect(int intno))(); 91 | void callisr(void __interrupt isr()); 92 | #endif 93 | 94 | int stricmp(char* s1, char* s2); 95 | void movedata(unsigned srcseg, unsigned srcoff, unsigned dstseg, unsigned dstoff, unsigned n); 96 | 97 | int getdisk(void); 98 | int setdisk(int drive); 99 | char* getcwd(char* buf, int len); 100 | int chdir(char* path); 101 | int findfirst(char* path, struct ffblk* ffblk, int attrib); 102 | int findnext(struct ffblk* ffblk); 103 | void fnmerge(char* path, char* drive, char* dir, char* name, char* ext); 104 | int fnsplit(char* path, char* drive, char* dir, char* name, char* ext); 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /scrnshot/memopad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/scrnshot/memopad.png -------------------------------------------------------------------------------- /search.c: -------------------------------------------------------------------------------- 1 | /* ---------------- search.c ------------- */ 2 | #include "dflat.h" 3 | 4 | extern DBOX SearchTextDB; 5 | extern DBOX ReplaceTextDB; 6 | static int CheckCase = TRUE; 7 | static int Replacing = FALSE; 8 | static int lastsize; 9 | 10 | /* - case-insensitive, white-space-normalized char compare - */ 11 | static BOOL SearchCmp(int a, int b) 12 | { 13 | if (b == '\n') 14 | b = ' '; 15 | if (CheckCase) 16 | return a != b; 17 | return tolower(a) != tolower(b); 18 | } 19 | 20 | /* ----- replace a matching block of text ----- */ 21 | static void replacetext(WINDOW wnd, char *cp1, DBOX *db) 22 | { 23 | char *cr = GetEditBoxText(db, ID_REPLACEWITH); 24 | char *cp = GetEditBoxText(db, ID_SEARCHFOR); 25 | int oldlen = strlen(cp); /* length of text being replaced */ 26 | int newlen = strlen(cr); /* length of replacing text */ 27 | int dif; 28 | lastsize = newlen; 29 | if (oldlen < newlen) { 30 | /* ---- new text expands text size ---- */ 31 | dif = newlen-oldlen; 32 | if (wnd->textlen < strlen(wnd->text)+dif) { 33 | /* ---- need to reallocate the text buffer ---- */ 34 | int offset = (int)(cp1-wnd->text); 35 | wnd->textlen += dif; 36 | wnd->text = DFrealloc(wnd->text, wnd->textlen+2); 37 | cp1 = wnd->text + offset; 38 | } 39 | memmove(cp1+dif, cp1, strlen(cp1)+1); 40 | } 41 | else if (oldlen > newlen) { 42 | /* ---- new text collapses text size ---- */ 43 | dif = oldlen-newlen; 44 | memmove(cp1, cp1+dif, strlen(cp1)+1); 45 | } 46 | strncpy(cp1, cr, newlen); 47 | } 48 | 49 | /* ------- search for the occurrance of a string ------- */ 50 | static void SearchTextBox(WINDOW wnd, int incr) 51 | { 52 | char *s1 = NULL, *s2, *cp1; 53 | DBOX *db = Replacing ? &ReplaceTextDB : &SearchTextDB; 54 | char *cp = GetEditBoxText(db, ID_SEARCHFOR); 55 | BOOL rpl = TRUE, FoundOne = FALSE; 56 | 57 | while (rpl == TRUE && cp != NULL && *cp) { 58 | rpl = Replacing ? 59 | CheckBoxSetting(&ReplaceTextDB, ID_REPLACEALL) : 60 | FALSE; 61 | if (TextBlockMarked(wnd)) { 62 | ClearTextBlock(wnd); 63 | SendMessage(wnd, PAINT, 0, 0); 64 | } 65 | /* search for a match starting at cursor position */ 66 | cp1 = CurrChar; 67 | if (incr) 68 | cp1 += lastsize; /* start past the last hit */ 69 | /* --- compare at each character position --- */ 70 | while (*cp1) { 71 | s1 = cp; 72 | s2 = cp1; 73 | while (*s1 && *s1 != '\n') { 74 | if (SearchCmp(*s1, *s2)) 75 | break; 76 | s1++, s2++; 77 | } 78 | if (*s1 == '\0' || *s1 == '\n') 79 | break; 80 | cp1++; 81 | } 82 | if (s1 != NULL && (*s1 == 0 || *s1 == '\n')) { 83 | /* ----- match at *cp1 ------- */ 84 | FoundOne = TRUE; 85 | 86 | /* mark a block at beginning of matching text */ 87 | wnd->BlkEndLine = TextLineNumber(wnd, s2); 88 | wnd->BlkBegLine = TextLineNumber(wnd, cp1); 89 | if (wnd->BlkEndLine < wnd->BlkBegLine) 90 | wnd->BlkEndLine = wnd->BlkBegLine; 91 | wnd->BlkEndCol = 92 | (int)(s2 - TextLine(wnd, wnd->BlkEndLine)); 93 | wnd->BlkBegCol = 94 | (int)(cp1 - TextLine(wnd, wnd->BlkBegLine)); 95 | 96 | /* position the cursor at the matching text */ 97 | wnd->CurrCol = wnd->BlkBegCol; 98 | wnd->CurrLine = wnd->BlkBegLine; 99 | wnd->WndRow = wnd->CurrLine - wnd->wtop; 100 | 101 | /* -- remember the size of the matching text -- */ 102 | lastsize = strlen(cp); 103 | 104 | /* align the window scroll to matching text */ 105 | if (WndCol > ClientWidth(wnd)-1) 106 | wnd->wleft = wnd->CurrCol; 107 | if (wnd->WndRow > ClientHeight(wnd)-1) { 108 | wnd->wtop = wnd->CurrLine; 109 | wnd->WndRow = 0; 110 | } 111 | 112 | SendMessage(wnd, PAINT, 0, 0); 113 | SendMessage(wnd, KEYBOARD_CURSOR, 114 | WndCol, wnd->WndRow); 115 | 116 | if (Replacing) { 117 | if (rpl || YesNoBox("Replace the text?")) { 118 | replacetext(wnd, cp1, db); 119 | wnd->TextChanged = TRUE; 120 | BuildTextPointers(wnd); 121 | if (rpl) { 122 | incr = TRUE; 123 | continue; 124 | } 125 | } 126 | ClearTextBlock(wnd); 127 | SendMessage(wnd, PAINT, 0, 0); 128 | } 129 | return; 130 | } 131 | break; 132 | } 133 | if (!FoundOne) 134 | MessageBox("Search/Replace Text", "No match found"); 135 | } 136 | 137 | /* ------- search for the occurrance of a string, 138 | replace it with a specified string ------- */ 139 | void ReplaceText(WINDOW wnd) 140 | { 141 | Replacing = TRUE; 142 | lastsize = 0; 143 | if (CheckCase) 144 | SetCheckBox(&ReplaceTextDB, ID_MATCHCASE); 145 | if (DialogBox(NULL, &ReplaceTextDB, TRUE, NULL)) { 146 | CheckCase=CheckBoxSetting(&ReplaceTextDB,ID_MATCHCASE); 147 | SearchTextBox(wnd, FALSE); 148 | } 149 | } 150 | 151 | /* ------- search for the first occurrance of a string ------ */ 152 | void SearchText(WINDOW wnd) 153 | { 154 | Replacing = FALSE; 155 | lastsize = 0; 156 | if (CheckCase) 157 | SetCheckBox(&SearchTextDB, ID_MATCHCASE); 158 | if (DialogBox(NULL, &SearchTextDB, TRUE, NULL)) { 159 | CheckCase=CheckBoxSetting(&SearchTextDB,ID_MATCHCASE); 160 | SearchTextBox(wnd, FALSE); 161 | } 162 | } 163 | 164 | /* ------- search for the next occurrance of a string ------- */ 165 | void SearchNext(WINDOW wnd) 166 | { 167 | SearchTextBox(wnd, TRUE); 168 | } 169 | -------------------------------------------------------------------------------- /slidebox.c: -------------------------------------------------------------------------------- 1 | /* ------------- slidebox.c ------------ */ 2 | 3 | #include "dflat.h" 4 | 5 | static int (*GenericProc) 6 | (WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2); 7 | static BOOL KeepRunning; 8 | static int SliderLen; 9 | static int Percent; 10 | extern DBOX SliderBoxDB; 11 | 12 | static void InsertPercent(char *s) 13 | { 14 | int offset; 15 | char pcc[5]; 16 | 17 | sprintf(s, "%c%c%c", 18 | CHANGECOLOR, 19 | color[DIALOG][SELECT_COLOR][FG]+0x80, 20 | color[DIALOG][SELECT_COLOR][BG]+0x80); 21 | s += 3; 22 | memset(s, ' ', SliderLen); 23 | *(s+SliderLen) = '\0'; 24 | sprintf(pcc, "%d%%", Percent); 25 | strncpy(s+SliderLen/2-1, pcc, strlen(pcc)); 26 | offset = (SliderLen * Percent) / 100; 27 | memmove(s+offset+4, s+offset, strlen(s+offset)+1); 28 | sprintf(pcc, "%c%c%c%c", 29 | RESETCOLOR, 30 | CHANGECOLOR, 31 | color[DIALOG][SELECT_COLOR][BG]+0x80, 32 | color[DIALOG][SELECT_COLOR][FG]+0x80); 33 | strncpy(s+offset, pcc, 4); 34 | *(s + strlen(s) - 1) = RESETCOLOR; 35 | } 36 | 37 | static int SliderTextProc( 38 | WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2) 39 | { 40 | switch (msg) { 41 | case PAINT: 42 | Percent = (int)p2; 43 | InsertPercent(GetText(wnd) ? 44 | (char*)GetText(wnd) : SliderBoxDB.ctl[1].itext); 45 | GenericProc(wnd, PAINT, 0, 0); 46 | if (Percent >= 100) 47 | SendMessage(GetParent(wnd),COMMAND,ID_CANCEL,0); 48 | if (!dispatch_message()) 49 | PostMessage(GetParent(wnd), ENDDIALOG, 0, 0); 50 | return KeepRunning; 51 | default: 52 | break; 53 | } 54 | return GenericProc(wnd, msg, p1, p2); 55 | } 56 | 57 | static int SliderBoxProc( 58 | WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 59 | { 60 | int rtn; 61 | WINDOW twnd; 62 | switch (msg) { 63 | case CREATE_WINDOW: 64 | AddAttribute(wnd, SAVESELF); 65 | rtn = DefaultWndProc(wnd, msg, p1, p2); 66 | twnd = SliderBoxDB.ctl[1].wnd; 67 | GenericProc = twnd->wndproc; 68 | twnd->wndproc = SliderTextProc; 69 | KeepRunning = TRUE; 70 | SendMessage(wnd, CAPTURE_MOUSE, 0, 0); 71 | SendMessage(wnd, CAPTURE_KEYBOARD, 0, 0); 72 | return rtn; 73 | case COMMAND: 74 | if ((int)p2 == 0 && (int)p1 == ID_CANCEL) { 75 | if (Percent >= 100 || 76 | YesNoBox("Terminate process?")) 77 | KeepRunning = FALSE; 78 | else 79 | return TRUE; 80 | } 81 | break; 82 | case CLOSE_WINDOW: 83 | SendMessage(wnd, RELEASE_MOUSE, 0, 0); 84 | SendMessage(wnd, RELEASE_KEYBOARD, 0, 0); 85 | break; 86 | default: 87 | break; 88 | } 89 | return DefaultWndProc(wnd, msg, p1, p2); 90 | } 91 | 92 | WINDOW SliderBox(int len, char *ttl, char *msg) 93 | { 94 | SliderLen = len; 95 | SliderBoxDB.dwnd.title = ttl; 96 | SliderBoxDB.dwnd.w = 97 | max(strlen(ttl),max(len, strlen(msg)))+4; 98 | SliderBoxDB.ctl[0].itext = msg; 99 | SliderBoxDB.ctl[0].dwnd.w = strlen(msg); 100 | SliderBoxDB.ctl[0].dwnd.x = 101 | (SliderBoxDB.dwnd.w - strlen(msg)-1) / 2; 102 | SliderBoxDB.ctl[1].itext = 103 | DFrealloc(SliderBoxDB.ctl[1].itext, len+10); 104 | Percent = 0; 105 | InsertPercent(SliderBoxDB.ctl[1].itext); 106 | SliderBoxDB.ctl[1].dwnd.w = len; 107 | SliderBoxDB.ctl[1].dwnd.x = (SliderBoxDB.dwnd.w-len-1)/2; 108 | SliderBoxDB.ctl[2].dwnd.x = (SliderBoxDB.dwnd.w-10)/2; 109 | DialogBox(NULL, &SliderBoxDB, FALSE, SliderBoxProc); 110 | return SliderBoxDB.ctl[1].wnd; 111 | } 112 | -------------------------------------------------------------------------------- /spinbutt.c: -------------------------------------------------------------------------------- 1 | /* ------------ spinbutt.c ------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | int SpinButtonProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 6 | { 7 | int rtn; 8 | CTLWINDOW *ct = GetControl(wnd); 9 | if (ct != NULL) { 10 | switch (msg) { 11 | case CREATE_WINDOW: 12 | wnd->wd -= 2; 13 | wnd->rc.rt -= 2; 14 | break; 15 | case SETFOCUS: 16 | rtn = BaseWndProc(SPINBUTTON, wnd, msg, p1, p2); 17 | if (!(int)p1) 18 | SendMessage(NULL, HIDE_CURSOR, 0, 0); 19 | SetFocusCursor(wnd); 20 | return rtn; 21 | case PAINT: 22 | foreground = WndBackground(wnd); 23 | background = WndForeground(wnd); 24 | wputch(wnd,UPSCROLLBOX,WindowWidth(wnd), 0); 25 | wputch(wnd,DOWNSCROLLBOX,WindowWidth(wnd)+1,0); 26 | SetFocusCursor(wnd); 27 | break; 28 | case LEFT_BUTTON: 29 | if (p1 == GetRight(wnd) + 1) 30 | SendMessage(wnd, KEYBOARD, UP, 0); 31 | else if (p1 == GetRight(wnd) + 2) 32 | SendMessage(wnd, KEYBOARD, DN, 0); 33 | if (wnd != inFocus) 34 | SendMessage(wnd, SETFOCUS, TRUE, 0); 35 | return TRUE; 36 | case LB_SETSELECTION: 37 | rtn = BaseWndProc(SPINBUTTON, wnd, msg, p1, p2); 38 | wnd->wtop = (int) p1; 39 | SendMessage(wnd, PAINT, 0, 0); 40 | return rtn; 41 | default: 42 | break; 43 | } 44 | } 45 | return BaseWndProc(SPINBUTTON, wnd, msg, p1, p2); 46 | } 47 | -------------------------------------------------------------------------------- /statbar.c: -------------------------------------------------------------------------------- 1 | /* ---------------- statbar.c -------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | extern char time_string[]; 6 | 7 | int StatusBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 8 | { 9 | char *statusbar; 10 | switch (msg) { 11 | case CREATE_WINDOW: 12 | SendMessage(wnd, CAPTURE_CLOCK, 0, 0); 13 | break; 14 | case KEYBOARD: 15 | if ((int)p1 == CTRL_F4) 16 | return TRUE; 17 | break; 18 | case PAINT: 19 | if (!isVisible(wnd)) 20 | break; 21 | statusbar = DFcalloc(1, WindowWidth(wnd)+1); 22 | memset(statusbar, ' ', WindowWidth(wnd)); 23 | *(statusbar+WindowWidth(wnd)) = '\0'; 24 | strncpy(statusbar+1, "F1=Help", 7); 25 | if (wnd->text) { 26 | int len = min(strlen(wnd->text), WindowWidth(wnd)-17); 27 | if (len > 0) { 28 | int off=(WindowWidth(wnd)-len)/2; 29 | strncpy(statusbar+off, wnd->text, len); 30 | } 31 | } 32 | if (wnd->TimePosted) 33 | *(statusbar+WindowWidth(wnd)-8) = '\0'; 34 | else 35 | strncpy(statusbar+WindowWidth(wnd)-8, time_string, 9); 36 | SetStandardColor(wnd); 37 | PutWindowLine(wnd, statusbar, 0, 0); 38 | free(statusbar); 39 | return TRUE; 40 | case BORDER: 41 | return TRUE; 42 | case CLOCKTICK: 43 | SetStandardColor(wnd); 44 | PutWindowLine(wnd, (char *)p1, WindowWidth(wnd)-8, 0); 45 | wnd->TimePosted = TRUE; 46 | SendMessage(wnd->PrevClock, msg, p1, p2); 47 | return TRUE; 48 | case CLOSE_WINDOW: 49 | SendMessage(wnd, RELEASE_CLOCK, 0, 0); 50 | break; 51 | default: 52 | break; 53 | } 54 | return BaseWndProc(STATUSBAR, wnd, msg, p1, p2); 55 | } 56 | -------------------------------------------------------------------------------- /sysmenu.c: -------------------------------------------------------------------------------- 1 | /* ------------- sysmenu.c ------------ */ 2 | 3 | #include "dflat.h" 4 | 5 | int SystemMenuProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 6 | { 7 | int mx, my; 8 | WINDOW wnd1; 9 | switch (msg) { 10 | case CREATE_WINDOW: 11 | wnd->holdmenu = ActiveMenuBar; 12 | ActiveMenuBar = &SystemMenu; 13 | SystemMenu.PullDown[0].Selection = 0; 14 | break; 15 | case LEFT_BUTTON: 16 | wnd1 = GetParent(wnd); 17 | mx = (int) p1 - GetLeft(wnd1); 18 | my = (int) p2 - GetTop(wnd1); 19 | if (HitControlBox(wnd1, mx, my)) 20 | return TRUE; 21 | break; 22 | case LB_CHOOSE: 23 | PostMessage(wnd, CLOSE_WINDOW, 0, 0); 24 | break; 25 | case DOUBLE_CLICK: 26 | if (p2 == GetTop(GetParent(wnd))) { 27 | PostMessage(GetParent(wnd), msg, p1, p2); 28 | SendMessage(wnd, CLOSE_WINDOW, TRUE, 0); 29 | } 30 | return TRUE; 31 | case SHIFT_CHANGED: 32 | return TRUE; 33 | case CLOSE_WINDOW: 34 | ActiveMenuBar = wnd->holdmenu; 35 | break; 36 | default: 37 | break; 38 | } 39 | return DefaultWndProc(wnd, msg, p1, p2); 40 | } 41 | 42 | /* ------- Build a system menu -------- */ 43 | void BuildSystemMenu(WINDOW wnd) 44 | { 45 | int lf, tp, ht, wd; 46 | WINDOW SystemMenuWnd; 47 | 48 | SystemMenu.PullDown[0].Selections[6].Accelerator = 49 | (GetClass(wnd) == APPLICATION) ? ALT_F4 : CTRL_F4; 50 | 51 | lf = GetLeft(wnd)+1; 52 | tp = GetTop(wnd)+1; 53 | ht = MenuHeight(SystemMenu.PullDown[0].Selections); 54 | wd = MenuWidth(SystemMenu.PullDown[0].Selections); 55 | 56 | if (lf+wd > SCREENWIDTH-1) 57 | lf = (SCREENWIDTH-1) - wd; 58 | if (tp+ht > SCREENHEIGHT-2) 59 | tp = (SCREENHEIGHT-2) - ht; 60 | 61 | SystemMenuWnd = CreateWindow(POPDOWNMENU, NULL, 62 | lf,tp,ht,wd,NULL,wnd,SystemMenuProc, 0); 63 | 64 | #ifdef INCLUDE_RESTORE 65 | if (wnd->condition == ISRESTORED) 66 | DeactivateCommand(&SystemMenu, ID_SYSRESTORE); 67 | else 68 | ActivateCommand(&SystemMenu, ID_SYSRESTORE); 69 | #endif 70 | 71 | if (TestAttribute(wnd, MOVEABLE) 72 | #ifdef INCLUDE_MAXIMIZE 73 | && wnd->condition != ISMAXIMIZED 74 | #endif 75 | ) 76 | ActivateCommand(&SystemMenu, ID_SYSMOVE); 77 | else 78 | DeactivateCommand(&SystemMenu, ID_SYSMOVE); 79 | 80 | if (wnd->condition != ISRESTORED || 81 | TestAttribute(wnd, SIZEABLE) == FALSE) 82 | DeactivateCommand(&SystemMenu, ID_SYSSIZE); 83 | else 84 | ActivateCommand(&SystemMenu, ID_SYSSIZE); 85 | 86 | #ifdef INCLUDE_MINIMIZE 87 | if (wnd->condition == ISMINIMIZED || 88 | TestAttribute(wnd, MINMAXBOX) == FALSE) 89 | DeactivateCommand(&SystemMenu, ID_SYSMINIMIZE); 90 | else 91 | ActivateCommand(&SystemMenu, ID_SYSMINIMIZE); 92 | #endif 93 | 94 | #ifdef INCLUDE_MAXIMIZE 95 | if (wnd->condition != ISRESTORED || 96 | TestAttribute(wnd, MINMAXBOX) == FALSE) 97 | DeactivateCommand(&SystemMenu, ID_SYSMAXIMIZE); 98 | else 99 | ActivateCommand(&SystemMenu, ID_SYSMAXIMIZE); 100 | #endif 101 | 102 | SendMessage(SystemMenuWnd, BUILD_SELECTIONS, 103 | (PARAM) &SystemMenu.PullDown[0], 0); 104 | SendMessage(SystemMenuWnd, SETFOCUS, TRUE, 0); 105 | SendMessage(SystemMenuWnd, SHOW_WINDOW, 0, 0); 106 | } 107 | -------------------------------------------------------------------------------- /system.h: -------------------------------------------------------------------------------- 1 | /* --------------- system.h -------------- */ 2 | #ifndef SYSTEM_H 3 | #define SYSTEM_H 4 | 5 | #ifdef __SMALLER_C__ 6 | #include "scdos.h" 7 | #else 8 | #if MSC | WATCOM 9 | #include 10 | #else 11 | #include 12 | #endif 13 | #endif 14 | 15 | #define swap(a,b){int x=a;a=b;b=x;} 16 | /* ----- interrupt vectors ----- */ 17 | #define TIMER 8 18 | #define VIDEO 0x10 19 | #define KEYBRD 0x16 20 | #define DOS 0x21 21 | #define CRIT 0x24 22 | #define MOUSE 0x33 23 | #define KEYBOARDVECT 9 24 | /* ------- platform-dependent values ------ */ 25 | #define KEYBOARDPORT 0x60 26 | #define FREQUENCY 100 27 | #define COUNT (1193280L / FREQUENCY) 28 | #define ZEROFLAG 0x40 29 | #define MAXSAVES 50 30 | #define SCREENWIDTH (peekb(0x40,0x4a) & 255) 31 | #define SCREENHEIGHT (isVGA() || isEGA() ? peekb(0x40,0x84)+1 : 25) 32 | #define clearBIOSbuffer() *(unsigned short far *)(MK_FP(0x40,0x1a)) = \ 33 | *(unsigned short far *)(MK_FP(0x40,0x1c)); 34 | #define waitforkeyboard() while ((keyportvalue & 0x80) == 0) \ 35 | clearBIOSbuffer() 36 | /* ----- keyboard BIOS (0x16) functions -------- */ 37 | #define READKB 0 38 | #define KBSTAT 1 39 | /* ------- video BIOS (0x10) functions --------- */ 40 | #define SETCURSORTYPE 1 41 | #define SETCURSOR 2 42 | #define READCURSOR 3 43 | #define READATTRCHAR 8 44 | #define WRITEATTRCHAR 9 45 | #define HIDECURSOR 0x20 46 | /* ------- the interrupt function registers -------- */ 47 | typedef struct { 48 | int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,fl; 49 | } IREGS; 50 | /* ---------- keyboard prototypes -------- */ 51 | int AltConvert(int); 52 | int getkey(void); 53 | int getshift(void); 54 | BOOL keyhit(void); 55 | void beep(void); 56 | /* ---------- cursor prototypes -------- */ 57 | void curr_cursor(int *x, int *y); 58 | void cursor(int x, int y); 59 | void hidecursor(void); 60 | void unhidecursor(void); 61 | void savecursor(void); 62 | void restorecursor(void); 63 | void normalcursor(void); 64 | void set_cursor_type(unsigned t); 65 | void videomode(void); 66 | void SwapCursorStack(void); 67 | /* --------- screen prototpyes -------- */ 68 | void clearscreen(void); 69 | /* ---------- mouse prototypes ---------- */ 70 | BOOL mouse_installed(void); 71 | int mousebuttons(void); 72 | void get_mouseposition(int *x, int *y); 73 | void set_mouseposition(int x, int y); 74 | void show_mousecursor(void); 75 | void hide_mousecursor(void); 76 | int button_releases(void); 77 | void resetmouse(void); 78 | void set_mousetravel(int, int, int, int); 79 | #define leftbutton() (mousebuttons()&1) 80 | #define rightbutton() (mousebuttons()&2) 81 | #define waitformouse() while(mousebuttons()); 82 | /* ------------ timer macros -------------- */ 83 | #define timed_out(timer) (timer==0) 84 | #define set_timer(timer, secs) timer=(secs)*182/10+1 85 | #define disable_timer(timer) timer = -1 86 | #define timer_running(timer) (timer > 0) 87 | #define countdown(timer) --timer 88 | #define timer_disabled(timer) (timer == -1) 89 | /* ----------- video adaptor prototypes ----------- */ 90 | BOOL isEGA(void); 91 | BOOL isVGA(void); 92 | void Set25(void); 93 | void Set43(void); 94 | void Set50(void); 95 | 96 | #ifndef TURBOC 97 | #ifndef BCPP 98 | /* ============= Color Macros ============ */ 99 | #define BLACK 0 100 | #define BLUE 1 101 | #define GREEN 2 102 | #define CYAN 3 103 | #define RED 4 104 | #define MAGENTA 5 105 | #define BROWN 6 106 | #define LIGHTGRAY 7 107 | #define DARKGRAY 8 108 | #define LIGHTBLUE 9 109 | #define LIGHTGREEN 10 110 | #define LIGHTCYAN 11 111 | #define LIGHTRED 12 112 | #define LIGHTMAGENTA 13 113 | #define YELLOW 14 114 | #define WHITE 15 115 | #define keyhit kbhit 116 | #endif 117 | #endif 118 | 119 | #if MSC | WATCOM 120 | /* ============= Compatibility Macros ============ */ 121 | #define asm __asm 122 | #undef FP_OFF 123 | #undef FP_SEG 124 | #undef MK_FP 125 | #define FP_OFF(p) ((unsigned)(p)) 126 | #define FP_SEG(p) ((unsigned)((unsigned long)(p) >> 16)) 127 | #define MK_FP(s,o) ((void far *) \ 128 | (((unsigned long)(s) << 16) | (unsigned)(o))) 129 | #define findfirst(p,f,a) _dos_findfirst(p,a,f) 130 | #define findnext(f) _dos_findnext(f) 131 | #define ffblk find_t 132 | #define ff_name name 133 | #define ff_fsize size 134 | #define ff_attrib attrib 135 | #define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c)) 136 | #define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c)) 137 | #define peek(a,b) (*((int far*)MK_FP((a),(b)))) 138 | #define peekb(a,b) (*((char far*)MK_FP((a),(b)))) 139 | #define getvect(v) _dos_getvect(v) 140 | #define setvect(v,f) _dos_setvect(v,f) 141 | #define fnsplit _splitpath 142 | #define fnmerge _makepath 143 | #define EXTENSION 2 144 | #define FILENAME 4 145 | #define DIRECTORY 8 146 | #define DRIVE 16 147 | int getdisk(void); 148 | #define setdisk(d) _dos_setdrive((d)+1, NULL) 149 | #define bioskey _bios_keybrd 150 | #define MAXPATH 80 151 | #define MAXDRIVE 3 152 | #define MAXDIR 66 153 | #define MAXFILE 9 154 | #define MAXEXT 5 155 | #endif 156 | 157 | typedef enum messages { 158 | #ifdef WATCOM 159 | WATCOMFIX1 = -1, 160 | #endif 161 | #undef DFlatMsg 162 | #define DFlatMsg(m) m, 163 | #include "dflatmsg.h" 164 | MESSAGECOUNT 165 | } MESSAGE; 166 | 167 | typedef enum window_class { 168 | #ifdef WATCOM 169 | WATCOMFIX2 = -1, 170 | #endif 171 | #define ClassDef(c,b,p,a) c, 172 | #include "classes.h" 173 | CLASSCOUNT 174 | } CLASS; 175 | 176 | #endif 177 | -------------------------------------------------------------------------------- /text.c: -------------------------------------------------------------------------------- 1 | /* -------------- text.c -------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | int TextProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 6 | { 7 | int i, len; 8 | CTLWINDOW *ct = GetControl(wnd); 9 | char *cp, *cp2 = ct->itext; 10 | switch (msg) { 11 | case SETFOCUS: 12 | return TRUE; 13 | case LEFT_BUTTON: 14 | return TRUE; 15 | case PAINT: 16 | if (ct == NULL || 17 | ct->itext == NULL || 18 | GetText(wnd) != NULL) 19 | break; 20 | len = min(ct->dwnd.h, MsgHeight(cp2)); 21 | cp = cp2; 22 | for (i = 0; i < len; i++) { 23 | int mlen; 24 | char *txt = cp; 25 | char *cp1 = cp; 26 | char *np = strchr(cp, '\n'); 27 | if (np != NULL) 28 | *np = '\0'; 29 | mlen = strlen(cp); 30 | while ((cp1=strchr(cp1,SHORTCUTCHAR)) != NULL) { 31 | mlen += 3; 32 | cp1++; 33 | } 34 | if (np != NULL) 35 | *np = '\n'; 36 | txt = DFmalloc(mlen+1); 37 | CopyCommand(txt, cp, FALSE, WndBackground(wnd)); 38 | txt[mlen] = '\0'; 39 | SendMessage(wnd, ADDTEXT, (PARAM)txt, 0); 40 | if ((cp = strchr(cp, '\n')) != NULL) 41 | cp++; 42 | free(txt); 43 | } 44 | break; 45 | default: 46 | break; 47 | } 48 | return BaseWndProc(TEXT, wnd, msg, p1, p2); 49 | } 50 | -------------------------------------------------------------------------------- /video.c: -------------------------------------------------------------------------------- 1 | /* --------------------- video.c -------------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | BOOL ClipString; 6 | static BOOL snowy; 7 | 8 | static unsigned video_address; 9 | static unsigned short near vpeek(unsigned short far *vp); 10 | static void near vpoke(unsigned short far *vp, unsigned short c); 11 | void movefromscreen(void *bf, int offset, int len); 12 | void movetoscreen(void *bf, int offset, int len); 13 | 14 | /* -- read a rectangle of video memory into a save buffer -- */ 15 | void getvideo(RECT rc, void far *bf) 16 | { 17 | int ht = RectBottom(rc)-RectTop(rc)+1; 18 | int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2; 19 | unsigned vadr = vad(RectLeft(rc), RectTop(rc)); 20 | hide_mousecursor(); 21 | while (ht--) { 22 | movefromscreen(bf, vadr, bytes_row); 23 | vadr += SCREENWIDTH*2; 24 | bf = (char far *)bf + bytes_row; 25 | } 26 | show_mousecursor(); 27 | } 28 | 29 | /* -- write a rectangle of video memory from a save buffer -- */ 30 | void storevideo(RECT rc, void far *bf) 31 | { 32 | int ht = RectBottom(rc)-RectTop(rc)+1; 33 | int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2; 34 | unsigned vadr = vad(RectLeft(rc), RectTop(rc)); 35 | hide_mousecursor(); 36 | while (ht--) { 37 | movetoscreen(bf, vadr, bytes_row); 38 | vadr += SCREENWIDTH*2; 39 | bf = (char far *)bf + bytes_row; 40 | } 41 | show_mousecursor(); 42 | } 43 | 44 | /* -------- read a character of video memory ------- */ 45 | unsigned int GetVideoChar(int x, int y) 46 | { 47 | int c; 48 | hide_mousecursor(); 49 | if (snowy) 50 | c = vpeek(MK_FP(video_address, vad(x,y))); 51 | else 52 | c = peek(video_address, vad(x,y)); 53 | show_mousecursor(); 54 | return c; 55 | } 56 | 57 | /* -------- write a character of video memory ------- */ 58 | void PutVideoChar(int x, int y, int c) 59 | { 60 | if (x < SCREENWIDTH && y < SCREENHEIGHT) { 61 | hide_mousecursor(); 62 | if (snowy) 63 | vpoke(MK_FP(video_address, vad(x,y)), c); 64 | else 65 | poke(video_address, vad(x,y), c); 66 | show_mousecursor(); 67 | } 68 | } 69 | 70 | BOOL CharInView(WINDOW wnd, int x, int y) 71 | { 72 | WINDOW nwnd = NextWindow(wnd); 73 | WINDOW pwnd; 74 | RECT rc; 75 | int x1 = GetLeft(wnd)+x; 76 | int y1 = GetTop(wnd)+y; 77 | 78 | if (!TestAttribute(wnd, VISIBLE)) 79 | return FALSE; 80 | if (!TestAttribute(wnd, NOCLIP)) { 81 | WINDOW wnd1 = GetParent(wnd); 82 | while (wnd1 != NULL) { 83 | /* --- clip character to parent's borders -- */ 84 | if (!TestAttribute(wnd1, VISIBLE)) 85 | return FALSE; 86 | if (!InsideRect(x1, y1, ClientRect(wnd1))) 87 | return FALSE; 88 | wnd1 = GetParent(wnd1); 89 | } 90 | } 91 | while (nwnd != NULL) { 92 | if (!isHidden(nwnd) /* && !isAncestor(wnd, nwnd) */ ) { 93 | rc = WindowRect(nwnd); 94 | if (TestAttribute(nwnd, SHADOW)) { 95 | RectBottom(rc)++; 96 | RectRight(rc)++; 97 | } 98 | if (!TestAttribute(nwnd, NOCLIP)) { 99 | pwnd = nwnd; 100 | while (GetParent(pwnd)) { 101 | pwnd = GetParent(pwnd); 102 | rc = subRectangle(rc, ClientRect(pwnd)); 103 | } 104 | } 105 | if (InsideRect(x1,y1,rc)) 106 | return FALSE; 107 | } 108 | nwnd = NextWindow(nwnd); 109 | } 110 | return (x1 < SCREENWIDTH && y1 < SCREENHEIGHT); 111 | } 112 | 113 | /* -------- write a character to a window ------- */ 114 | void wputch(WINDOW wnd, int c, int x, int y) 115 | { 116 | if (CharInView(wnd, x, y)) { 117 | int ch = (c & 255) | (clr(foreground, background) << 8); 118 | int xc = GetLeft(wnd)+x; 119 | int yc = GetTop(wnd)+y; 120 | hide_mousecursor(); 121 | if (snowy) 122 | vpoke(MK_FP(video_address, vad(xc, yc)), ch); 123 | else 124 | poke(video_address, vad(xc, yc), ch); 125 | show_mousecursor(); 126 | } 127 | } 128 | 129 | /* ------- write a string to a window ---------- */ 130 | void wputs(WINDOW wnd, void *s, int x, int y) 131 | { 132 | int x1 = GetLeft(wnd)+x; 133 | int x2 = x1; 134 | int y1 = GetTop(wnd)+y; 135 | if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT && isVisible(wnd)) { 136 | short ln[200]; 137 | short *cp1 = ln; 138 | unsigned char *str = s; 139 | int fg = foreground; 140 | int bg = background; 141 | int len; 142 | int off = 0; 143 | while (*str) { 144 | if (*str == CHANGECOLOR) { 145 | str++; 146 | foreground = (*str++) & 0x7f; 147 | background = (*str++) & 0x7f; 148 | continue; 149 | } 150 | if (*str == RESETCOLOR) { 151 | foreground = fg & 0x7f; 152 | background = bg & 0x7f; 153 | str++; 154 | continue; 155 | } 156 | if (*str == ('\t' | 0x80) || *str == ('\f' | 0x80)) 157 | *cp1 = ' ' | (clr(foreground, background) << 8); 158 | else 159 | *cp1 = (*str & 255) | (clr(foreground, background) << 8); 160 | if (ClipString) 161 | if (!CharInView(wnd, x, y)) 162 | *cp1 = peek(video_address, vad(x2,y1)); 163 | cp1++; 164 | str++; 165 | x++; 166 | x2++; 167 | } 168 | foreground = fg; 169 | background = bg; 170 | len = (int)(cp1-ln); 171 | if (x1+len > SCREENWIDTH) 172 | len = SCREENWIDTH-x1; 173 | 174 | if (!ClipString && !TestAttribute(wnd, NOCLIP)) { 175 | /* -- clip the line to within ancestor windows -- */ 176 | RECT rc = WindowRect(wnd); 177 | WINDOW nwnd = GetParent(wnd); 178 | while (len > 0 && nwnd != NULL) { 179 | if (!isVisible(nwnd)) { 180 | len = 0; 181 | break; 182 | } 183 | rc = subRectangle(rc, ClientRect(nwnd)); 184 | nwnd = GetParent(nwnd); 185 | } 186 | while (len > 0 && !InsideRect(x1+off,y1,rc)) { 187 | off++; 188 | --len; 189 | } 190 | if (len > 0) { 191 | x2 = x1+len-1; 192 | while (len && !InsideRect(x2,y1,rc)) { 193 | --x2; 194 | --len; 195 | } 196 | } 197 | } 198 | if (len > 0) { 199 | hide_mousecursor(); 200 | movetoscreen(ln+off, vad(x1+off,y1), len*2); 201 | show_mousecursor(); 202 | } 203 | } 204 | } 205 | 206 | /* --------- get the current video mode -------- */ 207 | void get_videomode(void) 208 | { 209 | videomode(); 210 | /* ---- Monochrome Display Adaptor or text mode ---- */ 211 | snowy = FALSE; 212 | if (ismono()) 213 | video_address = 0xb000; 214 | else { 215 | /* ------ Text mode -------- */ 216 | video_address = 0xb800 + video_page; 217 | if (!isEGA() && !isVGA()) 218 | /* -------- CGA --------- */ 219 | snowy = cfg.snowy; 220 | } 221 | } 222 | 223 | /* --------- scroll the window. d: 1 = up, 0 = dn ---------- */ 224 | void scroll_window(WINDOW wnd, RECT rc, int d) 225 | { 226 | if (RectTop(rc) != RectBottom(rc)) { 227 | union REGS regs; 228 | regs.h.cl = RectLeft(rc); 229 | regs.h.ch = RectTop(rc); 230 | regs.h.dl = RectRight(rc); 231 | regs.h.dh = RectBottom(rc); 232 | regs.h.bh = clr(WndForeground(wnd),WndBackground(wnd)); 233 | regs.h.ah = 7 - d; 234 | regs.h.al = 1; 235 | hide_mousecursor(); 236 | int86(VIDEO, ®s, ®s); 237 | show_mousecursor(); 238 | } 239 | } 240 | 241 | 242 | static void near waitforretrace(void) 243 | { 244 | #ifdef __SMALLER_C__ 245 | #else 246 | #ifndef WATCOM 247 | asm mov dx,3dah 248 | loop1: 249 | asm mov cx,6 250 | loop2: 251 | asm in al,dx 252 | asm test al,8 253 | asm jnz loop2 254 | asm test al,1 255 | asm jz loop2 256 | asm cli 257 | loop3: 258 | asm in al,dx 259 | asm test al,1 260 | asm loopnz loop3 261 | asm sti 262 | asm jz loop1 263 | #endif 264 | #endif 265 | } 266 | 267 | void movetoscreen(void *bf, int offset, int len) 268 | { 269 | if (snowy) 270 | waitforretrace(); 271 | movedata(FP_SEG(bf), FP_OFF(bf), video_address, offset, len); 272 | } 273 | 274 | void movefromscreen(void *bf, int offset, int len) 275 | { 276 | if (snowy) 277 | waitforretrace(); 278 | movedata(video_address, offset, FP_SEG(bf), FP_OFF(bf), len); 279 | } 280 | 281 | 282 | static unsigned short near vpeek(unsigned short far *vp) 283 | { 284 | unsigned short c; 285 | waitforretrace(); 286 | c = *vp; 287 | return c; 288 | } 289 | 290 | static void near vpoke(unsigned short far *vp, unsigned short c) 291 | { 292 | waitforretrace(); 293 | *vp = c; 294 | } 295 | -------------------------------------------------------------------------------- /video.h: -------------------------------------------------------------------------------- 1 | /* ---------------- video.h ----------------- */ 2 | 3 | #ifndef VIDEO_H 4 | #define VIDEO_H 5 | 6 | #include "rect.h" 7 | 8 | void getvideo(RECT, void far *); 9 | void storevideo(RECT, void far *); 10 | extern unsigned video_mode; 11 | extern unsigned video_page; 12 | void wputch(WINDOW, int, int, int); 13 | unsigned int GetVideoChar(int, int); 14 | void PutVideoChar(int, int, int); 15 | void get_videomode(void); 16 | void wputs(WINDOW, void *, int, int); 17 | void scroll_window(WINDOW, RECT, int); 18 | 19 | #define clr(fg,bg) ((fg)|((bg)<<4)) 20 | #define vad(x,y) ((y)*(SCREENWIDTH*2)+(x)*2) 21 | #define ismono() (video_mode == 7) 22 | #define istext() (video_mode < 4) 23 | #define videochar(x,y) (GetVideoChar(x,y) & 255) 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /watch.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexfru/dflat20/e440da6337e58836c09c115240d2212c7c1ec159/watch.c --------------------------------------------------------------------------------