├── bugs.txt ├── contrib.txt ├── copying ├── edit.lsm ├── readme └── source ├── applicat.c ├── asciitab.c ├── box.c ├── build.bat ├── button.c ├── calendar.c ├── checkbox.c ├── classdef.h ├── classes.h ├── clean.bat ├── clipbord.c ├── combobox.c ├── commands.h ├── config.c ├── config.h ├── console.c ├── decomp.c ├── dfalloc.c ├── dflat.bld ├── dflat.h ├── dflatmsg.h ├── dialbox.c ├── dialbox.h ├── dialogs.c ├── direct.c ├── edit.c ├── edit.txt ├── editbox.c ├── editor.c ├── fileopen.c ├── fixhelp.c ├── helpbox.c ├── helpbox.h ├── htree.c ├── htree.h ├── huffc.c ├── keys.c ├── keys.h ├── listbox.c ├── lists.c ├── log.c ├── makefile ├── menu.c ├── menu.h ├── menubar.c ├── menus.c ├── message.c ├── mouse.c ├── msgbox.c ├── normal.c ├── pictbox.c ├── popdown.c ├── radio.c ├── rect.c ├── rect.h ├── search.c ├── slidebox.c ├── spinbutt.c ├── statbar.c ├── sysmenu.c ├── system.h ├── text.c ├── textbox.c ├── video.c ├── video.h ├── watch.c └── window.c /bugs.txt: -------------------------------------------------------------------------------- 1 | FreeDOS Edit Bugs 2 | ----------------- 3 | 4 | The FreeDOS bug database is available at: 5 | 6 | http://www.freedos.org/bugs/bugzilla/ 7 | 8 | If you have a bug to report, do it there. Also, please email the maintainer, 9 | Joe Cosentino, at onehardmarine@attbi.com. Please do not fill out a bug 10 | report for one that's already been reported. 11 | 12 | Thanks, 13 | 14 | Joe Cosentino 15 | onehardmarine@attbi.com 16 | 17 | 18 | FreeDOS EDIT 0.6x / 0.7x Series Bugs 19 | ------------------------------------ 20 | 21 | Note: The official FreeDOS EDIT is available in version 0.82, maintained 22 | by Joe Cosentino. It contains many of the ideas from 0.6? and 0.7? series 23 | (where ? is a letter). However, the 0.6? and 0.7? series itself is done 24 | by Eric Auer, eric@coli.uni-sb.de, so bug reports about those versions 25 | should be sent to Eric, not to Joe. Main differences are, at the moment: 26 | 27 | The 0.6?/0.7? versions should be more compatible to country-specific 28 | settings like fonts (charsets / codepages), keyboard drivers and time 29 | format. They either display TAB as character or expand TAB to spaces at 30 | load time, while EDIT 0.82 does TAB processing on the fly, which slightly 31 | limits the support for codepages like Russian due to the internal TAB 32 | representation used by EDIT 0.82 text buffers. 33 | 34 | If you find a feature in either version of EDIT which is missing in the 35 | other version, you can try to convince the other maintainer to add that 36 | feature to the other EDIT as well :-). 37 | 38 | Happy comparing. 39 | 40 | Eric 41 | -------------------------------------------------------------------------------- /contrib.txt: -------------------------------------------------------------------------------- 1 | The following people have helped with the development of FreeDOS Editor: 2 | 3 | Dr. Dobb's Journal: Originally wrote the application, D-Flat, which Edit is 4 | based on. 5 | 6 | Shaun Raven: Fixed many bugs from D-Flat and made it more stable. 7 | 8 | Joe Cosentino: Fixed more bugs, changed the user interface around, 9 | added additional features. Maintainer of EDIT 0.6 10 | and EDIT 0.8 / 0.81 / 0.82 ... series: The 0.6x and 11 | 0.7x (x being any letter) series is Eric's spin-off. 12 | 13 | Eric Auer: Fixed many bugs including the file handling bugs and 14 | the AltGr bug. Removed irq handlers (timer, keyboard) 15 | from EDIT (0.6b, 0.6c respectively). Expanding tabs on 16 | load and tabs-as-char mode added (0.6d). Fixed shift-bs 17 | crash and drive selection, removed pTab/sTab (0.6e). 18 | Plain BIOS support for ctrl-ins, alt-backspace in 0.7, 19 | as well as ^P+char handling and time seconds display. 20 | Updates and bugfixes for 0.7a and 0.7b: Fixed tabs-as- 21 | chars loading, introduced viewer mode... 22 | Updates and bugfixes for 0.7c: swapped selection end 23 | handling, cursor range checking, improved "try again" 24 | save dialog, nonblinking clock, ctrl-f and alt-digit 25 | shortcuts (find, go to window 1..9), static window 26 | list order, int 2a.84 idle calls, ASCII table... 27 | Updates for 0.7d: upcase/downcase block, count lines 28 | words and bytes in block. 29 | 30 | Jeremy Davis: Added the Control+Break Handler, added additional video 31 | functions. 32 | 33 | Patric Rufflar: Made EDIT self-contained again by collecting all the 34 | library source files and fixed some bugs (AltGr, 0.6+). 35 | 36 | -------------------------------------------------------------------------------- /edit.lsm: -------------------------------------------------------------------------------- 1 | Begin3 2 | Title: Edit (Eric's spin-off version) 3 | Version: 0.7d (07/22/2005) 4 | Entered-date: 11/29/2002 5 | Description: FreeDOS improved clone of MS-DOS Edit 6 | Keywords: Edit Editor 7 | Author: Shaun Raven 8 | Maintained-by: Eric Auer 9 | Primary-site: http://www.coli.uni-sb.de/~eric/stuff/soft/by-others/ 10 | Alternate-site: http://www.freedos.org/ 11 | Original-site: http://freespace.virgin.net/shaun.raven/ 12 | Platforms: DOS (Turbo C/Borland C) 13 | Copying-policy: GPL 14 | End 15 | 16 | Normal-EDIT-Maintained-by: Joe Cosentino 17 | Normal-EDIT-Primary-site: http://www.geocities.com/xsaintx69/freedos/ 18 | 19 | -------------------------------------------------------------------------------- /readme: -------------------------------------------------------------------------------- 1 | FreeDOS Edit 0.7b 2 | 3 | Based on DFLAT TUI toolkit as described in Dr. Dobbs Journal (DDJ) 4 | See DFLAT.TXT for more information. 5 | 6 | Compiling: 7 | Tested with Borland's Turbo C 2.01 (TC2), Turbo C++ 1.01 (TC++1), 8 | Turbo C/C++ 3.0 (TC3), and Borland C/C++ 3.1 (TC3/BC3) 9 | Should also work with later versions. 10 | 11 | QUICKSTART: 12 | - flicker control in video.c used assembly language, removed this. 13 | TASM is no longer needed. 14 | - calendar "day of week" calculations and other mktime() things 15 | are now done by a builtin function. Turbo C 2.01 did not have 16 | mktime and you had to compile without calendar there formerly. 17 | The strftime() function is no longer necessary either. 18 | - you can now (EDIT 0.7) use either the old shift-ins/del, ctrl-ins 19 | and alt-backspace or the new ctrl-v/x, ctrl-c and ctrl-z keys. 20 | Their meanings are, respectively: paste, cut, copy, undo. The 21 | ctrl-ins and alt-backspace keys do not work on XT 84 key systems. 22 | - the /B (force monochrome) and /H (force high resolution mode) 23 | options now work (EDIT 0.7b) :-). You also have /R global read- 24 | only mode now, inspired by Joe's EDIT 0.8 / 0.81 / 0.82 version. 25 | 26 | Details: 27 | 28 | To compile, 1st edit MAKEFILE to match your compiler, followed by 29 | running 'make'. You may wish to then run clean to remove object 30 | files and lib files, the executables (*.exe) will still be available. 31 | (If compiling with TC3 or earlier? under NT, you may need to ensure 32 | your environment space is not to cluttered, i.e. unset unneeded 33 | environment variables, e.g. 'set PROCESSOR_IDENTIER=', etc. before make.) 34 | 35 | Once compiled you may wish to compress with an executable compressor 36 | such as UPX. If upx.exe is in your path, after make or instead of 37 | 'make all' you may run 'make upx' to build and then compress edit.exe 38 | 39 | 40 | Known Issues: 41 | 42 | - When reading or writing a file, tabs are converted to spaces. Since 43 | 0.6d, you can select to read and keep tabs as normal unexpanded chars. 44 | 45 | - The beep() function in console.c produces warnings with TC3 if outp 46 | macro is defined (you can #undef outp to remove them for TC3, but 47 | TC++1 does not have an outp function only the macro). Very lowlevel! 48 | 49 | - No support for Ctrl-Del in 0.6a..e series and 0.7a..b series. 50 | No support for Alt-BackSpace in 0.6a..e series and 0.7, fixed in 0.7a. 51 | Characters 0x89 and 0x8c (\t and \f | 0x80) were treated specially in 52 | the display code, a leftover from special-tab mode of Joe's EDIT 0.6- 53 | 0.8x, fixed in 0.7c (edit 0.6a..0.7c does not use special-tab mode). 54 | 55 | - See http://www.freedos.org/bugs/bugzilla/ to find or report other bugs! 56 | 57 | 20021129 (describing 0.5d) 58 | 20031118 (describing 0.6b) 59 | 20031128 (describing 0.6c) 60 | 20031129 (describing 0.6d) 61 | 20031201 (describing 0.6e) 62 | 20031202 (describing 0.7) 63 | 20042301 (describing 0.7a) 64 | 20052504 (describing 0.7b) 65 | 20051405 (describing 0.7c) 66 | -------------------------------------------------------------------------------- /source/asciitab.c: -------------------------------------------------------------------------------- 1 | /* ------------- asciitab.c ------------- */ 2 | /* Public Domain, written by Eric Auer 5/2005 for EDIT 0.7c */ 3 | #include "dflat.h" 4 | 5 | #if WITH_ASCIITAB 6 | 7 | #define ASCIIHEIGHT 20 8 | #define ASCIIWIDTH 41 /* highlights cannot be at very right edge, */ 9 | /* so ASCIIWIDTH has to be a bit too big, at least 3 chars */ 10 | /* after the last highlight, e.g. 41. */ 11 | 12 | static int ascii_highlight; 13 | static WINDOW ATwnd; 14 | 15 | 16 | static void DisplayAsciitab(WINDOW wnd) 17 | { 18 | int x, y, i, ch; 19 | char content[80]; 20 | 21 | SetStandardColor(wnd); 22 | memset(content, ' ', 80); 23 | PutWindowLine(wnd, " + 0 1 2 3 4 5 6 7 8 9 A B C D E F ", 0, 0); 24 | ch = 0; 25 | for (y = 0; y < 16; y++) { 26 | i = 0; 27 | content[i++] = ' '; 28 | content[i++] = (y < 10) ? ('0' + y) : ('A' + (y-10)); 29 | content[i++] = '0'; 30 | content[i++] = ' '; 31 | for (x = 0; x < 16; x++) { 32 | if (ascii_highlight == ch) { 33 | content[i++] = CHANGECOLOR; /* next chars must be 8x 8x */ 34 | content[i++] = SelectForeground(wnd)+0x80; 35 | content[i++] = SelectBackground(wnd)+0x80; 36 | } 37 | /* SelectBackground(wnd)+0x80 thechar ' ' RESETCOLOR now... */ 38 | content[i++] = ch; /* see video.h wputs limitations! */ 39 | if ((!content[i-1]) 40 | #if 0 /* video.c treats this as non-escape char in THIS context */ 41 | || (content[i-1] == CHANGECOLOR) 42 | #endif 43 | || (content[i-1] == RESETCOLOR) 44 | #ifdef TAB_TOGGLING /* also used in editor.c and video.c */ 45 | || (content[i-1] == ('\t' | 0x80)) 46 | || (content[i-1] == ('\f' | 0x80)) 47 | #endif 48 | ) 49 | content[i-1] = '*'; 50 | if (ascii_highlight == ch) 51 | content[i++] = RESETCOLOR; 52 | content[i++] = ' '; 53 | ch++; 54 | } /* x loop */ 55 | #if ASCIIWIDTH > 40 56 | content[i++] = (y < 10) ? ('0' + y) : ('A' + (y-10)); 57 | content[i++] = '0'; 58 | content[i++] = ' '; 59 | #endif 60 | content[i++] = 0; 61 | PutWindowLine(wnd, content, 0, y+1); 62 | } /* y loop */ 63 | content[0] = 0; 64 | i = ascii_highlight; 65 | if ((!i) 66 | #if 0 /* video.c treats this as non-escape char in THIS context */ 67 | || (i == CHANGECOLOR) 68 | #endif 69 | || (i == RESETCOLOR) 70 | #ifdef TAB_TOGGLING 71 | || (i == ('\t' | 0x80)) || (i == ('\f' | 0x80)) 72 | #endif 73 | ) i = '*'; 74 | sprintf(content," Character: Alt-%d (0x%02x) (\\%03o) '%c' ", 75 | ascii_highlight, ascii_highlight, ascii_highlight, (char)i); 76 | PutWindowLine(wnd, content, 0, 17); 77 | } 78 | 79 | 80 | static void CreateWindowMsg(WINDOW wnd) 81 | { 82 | ascii_highlight = 0; 83 | DisplayAsciitab(wnd); 84 | } 85 | 86 | 87 | static int KeyboardMsg(WINDOW wnd, PARAM p1) 88 | { 89 | switch ((int)p1) { 90 | case UP: 91 | case PGUP: 92 | ascii_highlight -= 16; 93 | break; 94 | case DN: 95 | case PGDN: 96 | ascii_highlight += 16; 97 | break; 98 | case LARROW: 99 | ascii_highlight--; 100 | break; 101 | case RARROW: 102 | ascii_highlight++; 103 | break; 104 | default: 105 | return FALSE; 106 | } 107 | #if ASCIIWIDTH < 41 108 | if ( ((ascii_highlight & 15) == 14) && (p1 == LARROW)) { 109 | ascii_highlight += 16; 110 | DisplayAsciitab(wnd); 111 | ascii_highlight -= 16; 112 | } /* kludge to properly reset the highlight */ 113 | #endif 114 | if (ascii_highlight < 0) ascii_highlight += 256; 115 | if (ascii_highlight > 255) ascii_highlight -= 256; 116 | DisplayAsciitab(wnd); 117 | return TRUE; 118 | } 119 | 120 | 121 | static int AsciitabProc(WINDOW wnd,MESSAGE msg, PARAM p1,PARAM p2) 122 | { 123 | switch (msg) { 124 | case CREATE_WINDOW: 125 | DefaultWndProc(wnd, msg, p1, p2); 126 | CreateWindowMsg(wnd); 127 | return TRUE; 128 | case KEYBOARD: 129 | if (KeyboardMsg(wnd, p1)) 130 | return TRUE; 131 | break; 132 | case PAINT: 133 | DefaultWndProc(wnd, msg, p1, p2); 134 | DisplayAsciitab(wnd); 135 | return TRUE; 136 | case COMMAND: 137 | if ((int)p1 == ID_HELP) { 138 | DisplayHelp(wnd, "ASCII Table"); 139 | return TRUE; 140 | } 141 | break; 142 | case CLOSE_WINDOW: 143 | ATwnd = NULL; 144 | break; 145 | default: 146 | break; 147 | } 148 | return DefaultWndProc(wnd, msg, p1, p2); 149 | } 150 | 151 | 152 | void Asciitable(WINDOW pwnd) 153 | { 154 | if (ATwnd == NULL) { 155 | ATwnd = CreateWindow(PICTUREBOX, 156 | "ASCII Table (close: ctrl-F4)", 157 | -1, -1, ASCIIHEIGHT, ASCIIWIDTH, 158 | NULL, pwnd, AsciitabProc, 159 | SHADOW | MINMAXBOX | CONTROLBOX | MOVEABLE | HASBORDER 160 | ); 161 | } 162 | SendMessage(ATwnd, SETFOCUS, TRUE, 0); 163 | } 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /source/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 | 29 | -------------------------------------------------------------------------------- /source/build.bat: -------------------------------------------------------------------------------- 1 | make 2 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/calendar.c: -------------------------------------------------------------------------------- 1 | /* ------------- calendar.c ------------- */ 2 | #include "dflat.h" 3 | 4 | /* #ifndef TURBOC */ 5 | #ifndef NOCALENDAR 6 | 7 | #define CALHEIGHT 17 8 | #define CALWIDTH 33 9 | 10 | static int DyMo[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 11 | static struct tm ttm, ctm; 12 | static int dys[42]; 13 | static WINDOW Cwnd; 14 | 15 | #ifndef strftime 16 | static char * nameOfMonth[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 17 | #endif 18 | 19 | /* returns 1 if year (0-based, not 1900-based) is a leap year (longer) */ 20 | /* -ea */ 21 | int isLeapYear(int year) 22 | { 23 | if (!(year % 400)) 24 | return 1; /* e.g. 2000 is a leap year */ 25 | if (!(year % 100)) 26 | return 0; /* e.g. 1900 and 2100 are not */ 27 | if (!(year % 4)) 28 | return 1; /* multiple of 4? Then it is a leap year */ 29 | return 0; /* default: not a leap year */ 30 | } 31 | 32 | /* Fixes ttm.tm_mday for a given month and year, 33 | * and recomputes the day of week and day of year 34 | * values, as ANSI C mktime() does. Turbo C 2.01 35 | * has no mktime(), so... 36 | * (tm_mday, tm_mon, tm_year -> tm_wday, tm_yday). 37 | * wday 0: Sunday. yday 0: Jan 1st. year 0: 1900. 38 | * mon 0: Jan. Contributed by Eric Auer. 39 | */ 40 | static void FixDate(void) 41 | { 42 | int i,j; 43 | /* ---- adjust Feb for leap year ---- */ 44 | DyMo[1] = isLeapYear(1900 + ttm.tm_year) ? 29 : 28; 45 | 46 | /* enforce ranges: 1..?? for mday, 0..11 for mon */ 47 | /* (old version just clipped mday value...) -ea */ 48 | while (ttm.tm_mday > DyMo[ttm.tm_mon]) { 49 | ttm.tm_mday -= DyMo[ttm.tm_mon]; 50 | ttm.tm_mon++; 51 | if (ttm.tm_mon > 11) { 52 | ttm.tm_mon = 0; 53 | ttm.tm_year++; 54 | } 55 | } 56 | 57 | /* re-calculate yday in 0..??? range */ 58 | ttm.tm_yday = 0; 59 | i = 0; 60 | while (i < ttm.tm_mon) { 61 | ttm.tm_yday += DyMo[i]; 62 | i++; 63 | } 64 | ttm.tm_yday += ttm.tm_mday - 1; /* mday is 1 based! */ 65 | 66 | /* 1st of January of 1900 (tm_year base) was a Monday (wday = 1) */ 67 | i = 0; /* year-1900 */ 68 | j = 1; /* wday of Jan 1 1900: Monday */ 69 | if (ttm.tm_year >= 1980) { /* leap closer: DOS epoch shortcut */ 70 | i = 80; /* start scanning from 1980 */ 71 | j = 2; /* Jan 1 1980 was a Tuesday */ 72 | } 73 | while (i < ttm.tm_year) { 74 | j += isLeapYear(i+1900) ? 2 : 1; /* shift 1 or 2 days each year */ 75 | if (j>6) 76 | j -= 7; /* wrap back in range */ 77 | i++; 78 | } 79 | ttm.tm_wday = (j + ttm.tm_yday) % 7; /* "day of year" helps us! */ 80 | } 81 | 82 | /* ---- build calendar dates array ---- */ 83 | static void BuildDateArray(void) 84 | { 85 | int offset, dy = 0; 86 | memset(dys, 0, sizeof dys); 87 | FixDate(); 88 | /* ----- compute the weekday for the 1st ----- */ 89 | offset = ((ttm.tm_mday-1) - ttm.tm_wday) % 7; 90 | if (offset < 0) 91 | offset += 7; 92 | if (offset) 93 | offset = (offset - 7) * -1; 94 | /* ----- build the dates into the array ---- */ 95 | for (dy = 1; dy <= DyMo[ttm.tm_mon]; dy++) 96 | dys[offset++] = dy; 97 | } 98 | 99 | static void CreateWindowMsg(WINDOW wnd) 100 | { 101 | int x, y; 102 | DrawBox(wnd, 1, 2, CALHEIGHT-4, CALWIDTH-4); 103 | for (x = 5; x < CALWIDTH-4; x += 4) 104 | DrawVector(wnd, x, 2, CALHEIGHT-4, FALSE); 105 | for (y = 4; y < CALHEIGHT-3; y+=2) 106 | DrawVector(wnd, 1, y, CALWIDTH-4, TRUE); 107 | } 108 | 109 | static void DisplayDates(WINDOW wnd) 110 | { 111 | int week, day; 112 | char dyln[10]; 113 | int offset; 114 | char banner[CALWIDTH-1]; 115 | char banner1[30]; 116 | 117 | SetStandardColor(wnd); 118 | PutWindowLine(wnd, "Sun Mon Tue Wed Thu Fri Sat", 2, 1); 119 | memset(banner, ' ', CALWIDTH-2); 120 | 121 | #ifndef strftime /* why was this disabled? */ 122 | sprintf(banner1, "%s, %i", nameOfMonth[ttm.tm_mon], 1900+ttm.tm_year); 123 | #else 124 | strftime(banner1, 16, "%B, %Y", &ttm); 125 | #endif 126 | 127 | offset = (CALWIDTH-2 - strlen(banner1)) / 2; 128 | strcpy(banner+offset, banner1); 129 | strcat(banner, " "); 130 | PutWindowLine(wnd, banner, 0, 0); 131 | BuildDateArray(); 132 | for (week = 0; week < 6; week++) { 133 | for (day = 0; day < 7; day++) { 134 | int dy = dys[week*7+day]; 135 | if (dy == 0) 136 | strcpy(dyln, " "); 137 | else { 138 | /* if current day of current month then highlight */ 139 | if ( (dy == ctm.tm_mday) && (ctm.tm_mon == ttm.tm_mon) ) 140 | sprintf(dyln, "%c%c%c%2d %c", 141 | CHANGECOLOR, 142 | SelectForeground(wnd)+0x80, 143 | SelectBackground(wnd)+0x80, 144 | dy, RESETCOLOR); 145 | else 146 | sprintf(dyln, "%2d ", dy); 147 | } 148 | SetStandardColor(wnd); 149 | PutWindowLine(wnd, dyln, 2 + day * 4, 3 + week*2); 150 | } 151 | } 152 | } 153 | 154 | static int KeyboardMsg(WINDOW wnd, PARAM p1) 155 | { 156 | switch ((int)p1) { 157 | case PGUP: 158 | if (ttm.tm_mon == 0) { 159 | ttm.tm_mon = 12; 160 | ttm.tm_year--; 161 | } 162 | ttm.tm_mon--; 163 | FixDate(); 164 | DisplayDates(wnd); 165 | return TRUE; 166 | case PGDN: 167 | ttm.tm_mon++; 168 | if (ttm.tm_mon == 12) { 169 | ttm.tm_mon = 0; 170 | ttm.tm_year++; 171 | } 172 | FixDate(); 173 | DisplayDates(wnd); 174 | return TRUE; 175 | default: 176 | break; 177 | } 178 | return FALSE; 179 | } 180 | 181 | static int CalendarProc(WINDOW wnd,MESSAGE msg, 182 | PARAM p1,PARAM p2) 183 | { 184 | switch (msg) { 185 | case CREATE_WINDOW: 186 | DefaultWndProc(wnd, msg, p1, p2); 187 | CreateWindowMsg(wnd); 188 | return TRUE; 189 | case KEYBOARD: 190 | if (KeyboardMsg(wnd, p1)) 191 | return TRUE; 192 | break; 193 | case PAINT: 194 | DefaultWndProc(wnd, msg, p1, p2); 195 | DisplayDates(wnd); 196 | return TRUE; 197 | case COMMAND: 198 | if ((int)p1 == ID_HELP) { 199 | DisplayHelp(wnd, "Calendar"); 200 | return TRUE; 201 | } 202 | break; 203 | case CLOSE_WINDOW: 204 | Cwnd = NULL; 205 | break; 206 | default: 207 | break; 208 | } 209 | return DefaultWndProc(wnd, msg, p1, p2); 210 | } 211 | 212 | void Calendar(WINDOW pwnd) 213 | { 214 | if (Cwnd == NULL) { 215 | time_t tim = time(NULL); 216 | ttm = *localtime(&tim); 217 | ctm = ttm; /* store current calendar day and month */ 218 | Cwnd = CreateWindow(PICTUREBOX, 219 | "Calendar (close: ctrl-F4)", 220 | -1, -1, CALHEIGHT, CALWIDTH, 221 | NULL, pwnd, CalendarProc, 222 | SHADOW | 223 | MINMAXBOX | 224 | CONTROLBOX | 225 | MOVEABLE | 226 | HASBORDER 227 | ); 228 | } 229 | SendMessage(Cwnd, SETFOCUS, TRUE, 0); 230 | } 231 | 232 | #endif 233 | -------------------------------------------------------------------------------- /source/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 | 47 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo Cleaning: deleting *.obj *.map and *.lib ... 3 | del *.obj 4 | del *.map 5 | del *.lib 6 | -------------------------------------------------------------------------------- /source/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 *bb = TextBlockBegin(wnd); /* near pointers */ 18 | char *be = TextBlockEnd(wnd); /* near pointers */ 19 | if (bb >= be) { /* *** 0.6e extra check *** */ 20 | bb = TextBlockEnd(wnd); /* sic! */ 21 | be = TextBlockBegin(wnd); /* sic! */ 22 | } 23 | ClipboardLength = (unsigned) (be - bb); /* *** unsigned *** */ 24 | Clipboard = DFrealloc(Clipboard, ClipboardLength); 25 | memmove(Clipboard, bb, ClipboardLength); 26 | } 27 | } 28 | 29 | void ClearClipboard(void) 30 | { 31 | if (Clipboard != NULL) { 32 | free(Clipboard); 33 | Clipboard = NULL; 34 | } 35 | } 36 | 37 | 38 | BOOL PasteText(WINDOW wnd, char *SaveTo, unsigned len) 39 | { 40 | if (SaveTo != NULL && len > 0) { 41 | unsigned plen = strlen(wnd->text) + len; 42 | 43 | if (plen <= wnd->MaxTextLength) { 44 | if (plen+1 > wnd->textlen) { 45 | wnd->text = DFrealloc(wnd->text, plen+3); 46 | wnd->textlen = plen+1; 47 | } 48 | memmove(CurrChar+len, CurrChar, strlen(CurrChar)+1); 49 | memmove(CurrChar, SaveTo, len); 50 | BuildTextPointers(wnd); 51 | wnd->TextChanged = TRUE; 52 | return TRUE; 53 | } 54 | } 55 | return FALSE; 56 | } 57 | 58 | /* NEW 7/2005 - not actually clipboard related but editbox.c is */ 59 | /* already tooo long anyway ;-) In-place text section stuff... */ 60 | /* toupper/tolower: see ctype.h - do they support COUNTRY...? */ 61 | 62 | void UpCaseMarked(WINDOW wnd) 63 | { 64 | if (TextBlockMarked(wnd)) { 65 | char *bb = TextBlockBegin(wnd); /* near pointers */ 66 | char *be = TextBlockEnd(wnd); /* near pointers */ 67 | if (bb >= be) { 68 | bb = TextBlockEnd(wnd); /* sic! */ 69 | be = TextBlockBegin(wnd); /* sic! */ 70 | } 71 | while (bb < be) { 72 | bb[0] = toupper(bb[0]); 73 | bb++; 74 | } 75 | } 76 | } 77 | 78 | void DownCaseMarked(WINDOW wnd) 79 | { 80 | if (TextBlockMarked(wnd)) { 81 | char *bb = TextBlockBegin(wnd); /* near pointers */ 82 | char *be = TextBlockEnd(wnd); /* near pointers */ 83 | if (bb >= be) { 84 | bb = TextBlockEnd(wnd); /* sic! */ 85 | be = TextBlockBegin(wnd); /* sic! */ 86 | } 87 | while (bb < be) { 88 | bb[0] = tolower(bb[0]); 89 | bb++; 90 | } 91 | } 92 | } 93 | 94 | void StatsForMarked(WINDOW wnd, unsigned *bytes, unsigned *words, unsigned *lines) 95 | { 96 | bytes[0] = words[0] = lines[0] = 0; 97 | if (TextBlockMarked(wnd)) { 98 | int inWord = 0; 99 | char *bb = TextBlockBegin(wnd); /* near pointers */ 100 | char *be = TextBlockEnd(wnd); /* near pointers */ 101 | if (bb >= be) { 102 | bb = TextBlockEnd(wnd); /* sic! */ 103 | be = TextBlockBegin(wnd); /* sic! */ 104 | } 105 | while (bb < be) { 106 | char c = bb[0]; 107 | if (c == '\n') lines[0]++; 108 | if (isspace(c)) { 109 | if (inWord) words[0]++; 110 | inWord = 0; 111 | } else { 112 | inWord = 1; 113 | } 114 | bytes[0]++; 115 | bb++; 116 | } 117 | if (inWord) words[0]++; 118 | } 119 | } 120 | 121 | -------------------------------------------------------------------------------- /source/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 | #ifdef HOOKKEYB 99 | case FWD: /* right arrow */ 100 | #else 101 | case RARROW: /* formerly called FWD */ 102 | #endif 103 | case BS: 104 | SendMessage(cwnd, SETFOCUS, TRUE, 0); 105 | return TRUE; 106 | default: 107 | break; 108 | } 109 | break; 110 | case LB_CHOOSE: 111 | SendMessage(cwnd, SETFOCUS, TRUE, 0); 112 | return TRUE; 113 | case CLOSE_WINDOW: 114 | if (wnd->ct != NULL) 115 | free(wnd->ct); 116 | wnd->ct = NULL; 117 | break; 118 | default: 119 | break; 120 | } 121 | return DefaultWndProc(wnd, msg, p1, p2); 122 | } 123 | 124 | void PutComboListText(WINDOW wnd, enum commands cmd, char *text) 125 | { 126 | CTLWINDOW *ct = FindCommand(wnd->extension, cmd, COMBOBOX); 127 | if (ct != NULL) { 128 | WINDOW lwnd = ((WINDOW)(ct->wnd))->extension; 129 | SendMessage(lwnd, ADDTEXT, (PARAM) text, 0); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /source/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_CLOSE, 20 | ID_DELETEFILE, 21 | ID_PRINT, 22 | ID_PRINTSETUP, 23 | ID_DOS, 24 | ID_EXIT, 25 | /* --------------- Edit menu ---------------- */ 26 | ID_UNDO, 27 | ID_CUT, 28 | ID_COPY, 29 | ID_PASTE, 30 | ID_PARAGRAPH, 31 | ID_CLEAR, 32 | ID_DELETETEXT, 33 | /* 0.7d additions for edit menu: */ 34 | ID_UPCASE, 35 | ID_DOWNCASE, 36 | ID_WORDCOUNT, 37 | /* --------------- Search Menu -------------- */ 38 | ID_SEARCH, 39 | ID_REPLACE, 40 | ID_SEARCHNEXT, 41 | /* --------------- Utilities Menu ------------- */ 42 | #ifndef NOCALENDAR 43 | ID_CALENDAR, 44 | #endif 45 | #if WITH_ASCIITAB 46 | ID_ASCIITAB, /* new 0.7c */ 47 | #endif 48 | /* -------------- Options menu -------------- */ 49 | ID_INSERT, 50 | ID_WRAP, 51 | ID_LOG, 52 | ID_TABS, 53 | ID_DISPLAY, 54 | ID_SAVEOPTIONS, 55 | /* --------------- Window menu -------------- */ 56 | ID_CLOSEALL, 57 | ID_WINDOW, 58 | ID_MOREWINDOWS, 59 | /* --------------- Help menu ---------------- */ 60 | ID_HELPHELP, 61 | ID_EXTHELP, 62 | ID_KEYSHELP, 63 | ID_HELPINDEX, 64 | ID_ABOUT, 65 | /* --------------- System menu -------------- */ 66 | #ifdef INCLUDE_RESTORE 67 | ID_SYSRESTORE, 68 | #endif 69 | ID_SYSMOVE, 70 | ID_SYSSIZE, 71 | #ifdef INCLUDE_MINIMIZE 72 | ID_SYSMINIMIZE, 73 | #endif 74 | #ifdef INCLUDE_MAXIMIZE 75 | ID_SYSMAXIMIZE, 76 | #endif 77 | ID_SYSCLOSE, 78 | /* ---- FileOpen and SaveAs dialog boxes ---- */ 79 | ID_FILENAME, 80 | ID_FILES, 81 | ID_DIRECTORY, 82 | ID_DRIVE, 83 | ID_PATH, 84 | /* ----- Search and Replace dialog boxes ---- */ 85 | ID_SEARCHFOR, 86 | ID_REPLACEWITH, 87 | ID_MATCHCASE, 88 | ID_REPLACEALL, 89 | /* ----------- Windows dialog box ----------- */ 90 | ID_WINDOWLIST, 91 | /* --------- generic command buttons -------- */ 92 | ID_OK, 93 | ID_CANCEL, 94 | ID_HELP, 95 | /* -------------- TabStops menu ------------- */ 96 | ID_TAB0, /* tab-as-char mode -ea */ 97 | ID_TAB2, 98 | ID_TAB4, 99 | ID_TAB6, 100 | ID_TAB8, 101 | /* ------------ Display dialog box ---------- */ 102 | ID_BORDER, 103 | ID_TITLE, 104 | ID_STATUSBAR, 105 | ID_TEXTURE, 106 | ID_SNOWY, 107 | ID_COLOR, 108 | ID_MONO, 109 | ID_REVERSE, 110 | ID_25LINES, 111 | ID_43LINES, 112 | ID_50LINES, 113 | /* ------------- Log dialog box ------------- */ 114 | ID_LOGLIST, 115 | ID_LOGGING, 116 | /* ------------ HelpBox dialog box ---------- */ 117 | ID_HELPTEXT, 118 | ID_BACK, 119 | ID_PREV, 120 | ID_NEXT, 121 | /* ---------- Print Select dialog box --------- */ 122 | ID_PRINTERPORT, 123 | ID_LEFTMARGIN, 124 | ID_RIGHTMARGIN, 125 | ID_TOPMARGIN, 126 | ID_BOTTOMMARGIN, 127 | /* ----------- InputBox dialog box ------------ */ 128 | ID_INPUTTEXT 129 | }; 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /source/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 | BOOL ReadOnlyMode; /* added in EDIT 0.7b */ 38 | unsigned char clr[CLASSCOUNT] [4] [2]; /* Colors */ 39 | } CONFIG; 40 | 41 | extern CONFIG cfg; 42 | extern unsigned char color[CLASSCOUNT] [4] [2]; 43 | extern unsigned char bw[CLASSCOUNT] [4] [2]; 44 | extern unsigned char reverse[CLASSCOUNT] [4] [2]; 45 | 46 | BOOL LoadConfig(void); 47 | void SaveConfig(void); 48 | FILE *OpenConfig(char *); 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /source/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 | /* ---- BIOS keyboard routines with 84 and 102 key keyboard support ---- */ 45 | /* (EDIT 0.7 -ea) */ 46 | int Xbioskey(int cmd) 47 | { 48 | static int keybase = -1; 49 | union REGS kregs; 50 | if (keybase < 0) { 51 | volatile char far *kbtype = MK_FP(0x40,0x96); /* BIOS data flag */ 52 | keybase = ( ((*kbtype) & 0x10) != 0 ) ? 0x10 : 0; 53 | /* 0 for 84 key XT mode, 0x10 for 102 key AT mode. */ 54 | /* (0x20 for 122 key mode, which is not used here) */ 55 | } 56 | kregs.h.ah = (char) (keybase + cmd); 57 | kregs.h.al = 0; 58 | int86(0x16, &kregs, &kregs); 59 | if ( (cmd == 1) && (kregs.x.flags & 0x40 /* zero flag */) ) 60 | return 0; 61 | return kregs.x.ax; 62 | } 63 | 64 | /* ---- Test for keystroke ---- */ 65 | BOOL keyhit(void) 66 | { 67 | #if MSC | WATCOM 68 | return (kbhit() ? TRUE : FALSE); 69 | #else 70 | return (Xbioskey(1) != 0) ? TRUE : FALSE; 71 | #endif 72 | } 73 | 74 | /* ---- Read a keystroke ---- */ 75 | int getkey(void) 76 | { 77 | unsigned int c; 78 | #ifndef HOOKKEYB 79 | unsigned int theShift; 80 | unsigned int theScan; 81 | #endif 82 | #if 0 /* removed pointless polling loop in 0.7c */ 83 | ! while (keyhit() == FALSE); /* wait for a key */ 84 | #endif 85 | #ifdef HOOKKEYB 86 | if (((c = bioskey(0)) & 0xff) == 0) 87 | c = (c >> 8) | 0x1080; 88 | else 89 | c &= 0xff; 90 | return c & 0x10ff; 91 | #else 92 | 93 | c = Xbioskey(0); /* fetch key */ 94 | theShift = getshift(); 95 | theScan = c >> 8; /* scan code */ 96 | c = c & 0xff; /* ASCII code or 0 of 0xe0 */ 97 | 98 | if ( theShift & (LEFTSHIFT|RIGHTSHIFT) ) { 99 | /* BIOS normally calls shift-ins "ins" and shift-del "del" */ 100 | if (theScan == 0x52) /* INS */ 101 | return CTRL_V; /* SHIFT_INS; */ /* shift-ins is paste, ctrl-v */ 102 | if (theScan == 0x53) /* DEL */ 103 | return CTRL_X; /* SHIFT_DEL; */ /* shift-del is cut, ctrl-x */ 104 | } /* special SHIFT cases */ 105 | 106 | if ( (theShift & ALTKEY) && (theScan == 0x0e) ) /* Alt-BS */ 107 | return CTRL_Z; /* ALT_BS; */ /* alt-backspace is undo, ctrl-z */ 108 | 109 | if (theShift & CTRLKEY) { 110 | if (theScan == 0x92) { /* ^ins / ^-numpad-Ins */ 111 | return CTRL_C; /* CTRL_INS; */ /* ctrl-ins is copy, ctrl-c */ 112 | } 113 | } /* special CTRL cases */ 114 | 115 | if ( (c != 0) && (c != 0xe0) ) /* nonzero / nonnumpad ASCII part? */ 116 | return c; /* then return only the ASCII part */ 117 | 118 | /* Watch out: special case for Russian non-numpad "0xe0 ASCII" */ 119 | if ( (c == 0xe0) && (theScan == 0) ) 120 | return 0xe0; 121 | 122 | return (FKEY | theScan); /* else return scancode and a flag */ 123 | 124 | #endif 125 | } 126 | 127 | /* ---------- read the keyboard shift status --------- */ 128 | int getshift(void) 129 | { 130 | static int enhkeyb = -1; /* 1 for an enhanced keyboard */ 131 | static char far *kbtype = MK_FP(0x40,0x96); 132 | /* new check method (10/2003) */ 133 | if (enhkeyb == -1) { /* if we do not yet know... */ 134 | enhkeyb = (((*kbtype) & 0x10) != 0) ? 1 : 0; /* read BIOS data flag! */ 135 | } /* now enhkeyb is either 0 or 1 - Eric */ 136 | 137 | if (!enhkeyb) { /* old/new by Eric */ 138 | 139 | regs.h.ah = 2; 140 | int86(KEYBRD, ®s, ®s); 141 | return regs.h.al; 142 | } else { /* new by Eric 11/2002 */ 143 | 144 | regs.h.ah = 0x12; /* extended shift: AL as above... */ 145 | int86(KEYBRD, ®s, ®s); 146 | /* ignore SysRQ (Alt-PrtScr) and shift lock presses */ 147 | regs.x.ax &= 0x0fff; 148 | /* treat RALT as NO ALT (but as AltGr): */ 149 | if (regs.x.ax & RALTKEY) 150 | regs.x.ax &= ~ALTKEY; 151 | return regs.x.ax; 152 | } 153 | } 154 | 155 | static int far *clk = MK_FP(0x40,0x6c); 156 | /* ------- macro to wait one clock tick -------- */ 157 | #define wait() \ 158 | { \ 159 | int now = *clk; \ 160 | while (now == *clk) \ 161 | ; \ 162 | } 163 | 164 | /* -------- sound a buzz tone, using hardware directly ---------- */ 165 | void beep(void) 166 | { 167 | wait(); 168 | outp(0x43, 0xb6); /* program the frequency */ 169 | outp(0x42, (int) (COUNT % 256)); 170 | outp(0x42, (int) (COUNT / 256)); 171 | outp(0x61, inp(0x61) | 3); /* start the sound */ 172 | wait(); 173 | outp(0x61, inp(0x61) & ~3); /* stop the sound */ 174 | } 175 | 176 | /* -------- get the video mode and page from BIOS -------- */ 177 | void videomode(void) 178 | { 179 | regs.h.ah = 15; 180 | int86(VIDEO, ®s, ®s); 181 | video_mode = regs.h.al; 182 | video_page = regs.x.bx; 183 | video_page &= 0xff00; 184 | video_mode &= 0x7f; 185 | } 186 | 187 | /* ------ position the cursor ------ */ 188 | void cursor(int x, int y) 189 | { 190 | videomode(); 191 | if (y >= SCREENHEIGHT) y = SCREENHEIGHT - 1; /* 0.7c */ 192 | regs.x.dx = ((y << 8) & 0xff00) + x; 193 | regs.h.ah = SETCURSOR; 194 | regs.x.bx = video_page; 195 | int86(VIDEO, ®s, ®s); 196 | } 197 | 198 | /* ------ get cursor shape and position ------ */ 199 | static void near getcursor(void) 200 | { 201 | videomode(); 202 | regs.h.ah = READCURSOR; 203 | regs.x.bx = video_page; 204 | int86(VIDEO, ®s, ®s); 205 | } 206 | 207 | /* ------- get the current cursor position ------- */ 208 | void curr_cursor(int *x, int *y) 209 | { 210 | getcursor(); 211 | *x = regs.h.dl; 212 | *y = regs.h.dh; 213 | } 214 | 215 | /* ------ save the current cursor configuration ------ */ 216 | void savecursor(void) 217 | { 218 | if (cs < MAXSAVES) { 219 | getcursor(); 220 | cursorshape[cs] = regs.x.cx; 221 | cursorpos[cs] = regs.x.dx; 222 | cs++; 223 | } 224 | } 225 | 226 | /* ---- restore the saved cursor configuration ---- */ 227 | void restorecursor(void) 228 | { 229 | if (cs) { 230 | --cs; 231 | videomode(); 232 | regs.x.dx = cursorpos[cs]; 233 | if (regs.h.dh >= SCREENHEIGHT) 234 | regs.h.dh = SCREENHEIGHT - 1; /* 0.7c */ 235 | regs.h.ah = SETCURSOR; 236 | regs.x.bx = video_page; 237 | int86(VIDEO, ®s, ®s); 238 | set_cursor_type(cursorshape[cs]); 239 | } 240 | } 241 | 242 | /* ------ make a normal cursor ------ */ 243 | void normalcursor(void) 244 | { 245 | set_cursor_type(0x0106); 246 | } 247 | 248 | /* ------ hide the cursor ------ */ 249 | void hidecursor(void) 250 | { 251 | getcursor(); 252 | regs.h.ch |= HIDECURSOR; 253 | regs.h.ah = SETCURSORTYPE; 254 | int86(VIDEO, ®s, ®s); 255 | } 256 | 257 | /* ------ unhide the cursor ------ */ 258 | void unhidecursor(void) 259 | { 260 | getcursor(); 261 | regs.h.ch &= ~HIDECURSOR; 262 | regs.h.ah = SETCURSORTYPE; 263 | int86(VIDEO, ®s, ®s); 264 | } 265 | 266 | /* ---- use BIOS to set the cursor type ---- */ 267 | void set_cursor_type(unsigned t) 268 | { 269 | videomode(); 270 | regs.h.ah = SETCURSORTYPE; 271 | regs.x.bx = video_page; 272 | regs.x.cx = t; 273 | int86(VIDEO, ®s, ®s); 274 | } 275 | 276 | /* ---- test for EGA -------- */ 277 | BOOL isEGA(void) 278 | { 279 | if (isVGA()) 280 | return FALSE; 281 | regs.h.ah = 0x12; 282 | regs.h.bl = 0x10; 283 | int86(VIDEO, ®s, ®s); 284 | return regs.h.bl != 0x10; 285 | } 286 | 287 | /* ---- test for VGA -------- */ 288 | BOOL isVGA(void) 289 | { 290 | regs.x.ax = 0x1a00; 291 | int86(VIDEO, ®s, ®s); 292 | return regs.h.al == 0x1a && regs.h.bl > 6; 293 | } 294 | 295 | static void Scan350(void) 296 | { 297 | regs.x.ax = 0x1201; 298 | regs.h.bl = 0x30; 299 | int86(VIDEO, ®s, ®s); 300 | regs.h.ah = 0x0f; 301 | int86(VIDEO, ®s, ®s); 302 | regs.h.ah = 0x00; 303 | int86(VIDEO, ®s, ®s); 304 | } 305 | 306 | static void Scan400(void) 307 | { 308 | regs.x.ax = 0x1202; 309 | regs.h.bl = 0x30; 310 | int86(VIDEO, ®s, ®s); 311 | regs.h.ah = 0x0f; 312 | int86(VIDEO, ®s, ®s); 313 | regs.h.ah = 0x00; 314 | int86(VIDEO, ®s, ®s); 315 | } 316 | 317 | /* ---------- set 25 line mode ------- */ 318 | void Set25(void) 319 | { 320 | if (isVGA()) { 321 | Scan400(); 322 | regs.x.ax = 0x1114; 323 | } 324 | else 325 | regs.x.ax = 0x1111; 326 | regs.h.bl = 0; 327 | int86(VIDEO, ®s, ®s); 328 | } 329 | 330 | /* ---------- set 43 line mode ------- */ 331 | void Set43(void) 332 | { 333 | if (isVGA()) 334 | Scan350(); 335 | regs.x.ax = 0x1112; 336 | regs.h.bl = 0; 337 | int86(VIDEO, ®s, ®s); 338 | } 339 | 340 | /* ---------- set 50 line mode ------- */ 341 | void Set50(void) 342 | { 343 | if (isVGA()) 344 | Scan400(); 345 | regs.x.ax = 0x1112; 346 | regs.h.bl = 0; 347 | int86(VIDEO, ®s, ®s); 348 | } 349 | 350 | /* ------ convert an Alt+ key to its letter equivalent ----- */ 351 | int AltConvert(int c) 352 | { 353 | int i, a = 0; 354 | for (i = 0; i < 36; i++) 355 | if (c == altconvert[i]) 356 | break; 357 | if (i < 26) 358 | a = 'a' + i; 359 | else if (i < 36) 360 | a = '0' + i - 26; 361 | return a; 362 | } 363 | 364 | #if MSC | WATCOM 365 | int getdisk(void) 366 | { 367 | unsigned int cd; 368 | _dos_getdrive(&cd); 369 | cd -= 1; 370 | return cd; 371 | } 372 | #endif 373 | 374 | -------------------------------------------------------------------------------- /source/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 | 112 | -------------------------------------------------------------------------------- /source/dfalloc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/edit/4ed5d50a4d2d516e857478ab437985d1e07b9eb3/source/dfalloc.c -------------------------------------------------------------------------------- /source/dflat.bld: -------------------------------------------------------------------------------- 1 | +WINDOW.OBJ & 2 | +VIDEO.OBJ & 3 | +MESSAGE.OBJ & 4 | +MOUSE.OBJ & 5 | +CONSOLE.OBJ & 6 | +TEXTBOX.OBJ & 7 | +LISTBOX.OBJ & 8 | +NORMAL.OBJ & 9 | +CONFIG.OBJ & 10 | +MENU.OBJ & 11 | +MENUBAR.OBJ & 12 | +POPDOWN.OBJ & 13 | +RECT.OBJ & 14 | +APPLICAT.OBJ & 15 | +KEYS.OBJ & 16 | +SYSMENU.OBJ & 17 | +EDITBOX.OBJ & 18 | +DIALBOX.OBJ & 19 | +BUTTON.OBJ & 20 | +FILEOPEN.OBJ & 21 | +MSGBOX.OBJ & 22 | +HELPBOX.OBJ & 23 | +LOG.OBJ & 24 | +LISTS.OBJ & 25 | +STATBAR.OBJ & 26 | +DECOMP.OBJ & 27 | +COMBOBOX.OBJ & 28 | +PICTBOX.OBJ & 29 | +CLIPBORD.OBJ & 30 | +SEARCH.OBJ & 31 | +DFALLOC.OBJ & 32 | +CHECKBOX.OBJ & 33 | +TEXT.OBJ & 34 | +RADIO.OBJ & 35 | +BOX.OBJ & 36 | +SPINBUTT.OBJ & 37 | +WATCH.OBJ & 38 | +SLIDEBOX.OBJ & 39 | +DIRECT.OBJ & 40 | +EDITOR.OBJ & 41 | +CALENDAR.OBJ & 42 | +ASCIITAB.OBJ 43 | -------------------------------------------------------------------------------- /source/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 | 106 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/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, "File ~Name:", 3, 1, 1,10, ID_FILENAME) 9 | CONTROL(EDITBOX, NULL, 14, 1, 1,40, ID_FILENAME) 10 | CONTROL(TEXT, NULL, 3, 3, 1,50, ID_PATH) 11 | CONTROL(TEXT, "~Files:", 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, "File ~Name:", 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, "~Files:", 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("Print 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("Find",-1,-1,9,48) 61 | CONTROL(TEXT, "~Find What:", 2, 1, 1, 11, ID_SEARCHFOR) 62 | CONTROL(EDITBOX, NULL, 14, 1, 1, 29, ID_SEARCHFOR) 63 | CONTROL(TEXT, "Match ~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",-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 ~Case:", 2, 5, 1, 23, ID_MATCHCASE) 78 | CONTROL(CHECKBOX, NULL, 26, 5, 1, 3, ID_MATCHCASE) 79 | CONTROL(TEXT, "Replace ~All:", 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("Edit 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 | -------------------------------------------------------------------------------- /source/direct.c: -------------------------------------------------------------------------------- 1 | /* ---------- direct.c --------- */ 2 | 3 | #include "dflat.h" 4 | 5 | #ifndef FA_DIREC 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) { /* backup if not to be changed */ 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 == '\\') && (strlen(dir) > 1)) /* save "\\" - Eric */ 32 | *cp = '\0'; 33 | } 34 | *drive = *dir = *name = *ext = '\0'; 35 | 36 | fnsplit(fspec, drive, dir, name, ext); 37 | 38 | if (!InclName) 39 | *name = *ext = '\0'; 40 | *drive = toupper(*drive); 41 | if (*ext) 42 | cm |= EXTENSION; 43 | if (InclName && *name) 44 | cm |= FILENAME; 45 | if (*dir) 46 | cm |= DIRECTORY; 47 | 48 | if (*drive) 49 | cm |= DRIVE; 50 | if (cm & DRIVE) 51 | setdisk(*drive - 'A'); 52 | else { 53 | *drive = getdisk(); 54 | *drive += 'A'; 55 | } 56 | 57 | if (cm & DIRECTORY) { 58 | cp = dir+strlen(dir)-1; 59 | if ((*cp == '\\') && (strlen(dir) > 1)) 60 | /* save "\\" if it is the only dirspec - Eric */ 61 | *cp = '\0'; /* remove trailing backslash if not needed */ 62 | chdir(dir); 63 | } 64 | getcwd(dir, sizeof dir); 65 | memmove(dir, dir+2, strlen(dir+1)); 66 | 67 | if (InclName) { /* unless only drive / directory wanted */ 68 | if (!(cm & FILENAME)) 69 | strcpy(name, "*"); 70 | if (!(cm & EXTENSION) && strchr(fspec, '.') != NULL) 71 | strcpy(ext, ".*"); 72 | } 73 | else 74 | *name = *ext = '\0'; 75 | 76 | if (dir[strlen(dir)-1] != '\\') 77 | strcat(dir, "\\"); /* supply a trailing backslash */ 78 | 79 | if (spath != NULL) 80 | fnmerge(spath, drive, dir, name, ext); 81 | 82 | if (!Change) { /* restore if not to be changed */ 83 | setdisk(currdrive); 84 | chdir(currdir); 85 | } 86 | } 87 | 88 | static int dircmp(const void *c1, const void *c2) 89 | { 90 | return stricmp(*(char **)c1, *(char **)c2); 91 | } 92 | 93 | static BOOL BuildList(WINDOW wnd, char *fspec, BOOL dirs) 94 | { 95 | int ax, i = 0, criterr = 1; 96 | struct ffblk ff; 97 | CTLWINDOW *ct = FindCommand(wnd->extension, 98 | dirs ? ID_DIRECTORY : ID_FILES,LISTBOX); 99 | WINDOW lwnd; 100 | char **dirlist = NULL; 101 | 102 | if (ct != NULL) { 103 | lwnd = ct->wnd; 104 | SendMessage(lwnd, CLEARTEXT, 0, 0); 105 | 106 | while (criterr == 1) { 107 | ax = findfirst(fspec, &ff, dirs ? FA_DIREC: 0); 108 | criterr = TestCriticalError(); 109 | } 110 | if (criterr) 111 | return FALSE; 112 | while (ax == 0) { 113 | if (!dirs || (ff.ff_attrib & FA_DIREC) && strcmp(ff.ff_name, ".")) { 114 | dirlist = DFrealloc(dirlist, sizeof(char *)*(i+1)); 115 | dirlist[i] = DFmalloc(strlen(ff.ff_name)+1); 116 | strcpy(dirlist[i++], ff.ff_name); 117 | } 118 | ax = findnext(&ff); 119 | } 120 | if (dirlist != NULL) { 121 | int j; 122 | /* -- sort file or directory list box data -- */ 123 | qsort(dirlist, i, sizeof(void *), dircmp); 124 | /* ---- send sorted list to list box ---- */ 125 | for (j = 0; j < i; j++) { 126 | SendMessage(lwnd,ADDTEXT,(PARAM)dirlist[j],0); 127 | free(dirlist[j]); 128 | } 129 | free(dirlist); 130 | } 131 | SendMessage(lwnd, SHOW_WINDOW, 0, 0); 132 | } 133 | return TRUE; 134 | } 135 | 136 | BOOL BuildFileList(WINDOW wnd, char *fspec) 137 | { 138 | return BuildList(wnd, fspec, FALSE); 139 | } 140 | 141 | void BuildDirectoryList(WINDOW wnd) 142 | { 143 | BuildList(wnd, "*.*", TRUE); 144 | } 145 | 146 | void BuildDriveList(WINDOW wnd) 147 | { 148 | CTLWINDOW *ct = FindCommand(wnd->extension, ID_DRIVE,LISTBOX); 149 | if (ct != NULL) 150 | { 151 | union REGS regs; 152 | char drname[15]; 153 | unsigned int cd, dr; 154 | WINDOW lwnd = ct->wnd; 155 | 156 | SendMessage(lwnd, CLEARTEXT, 0, 0); 157 | cd = getdisk(); 158 | for (dr = 0; dr < 26; dr++) /* would be better to use LASTDRIVE */ 159 | { 160 | unsigned ndr; 161 | 162 | setdisk(dr); 163 | ndr = getdisk(); /* drive really accessible? */ 164 | if (ndr == dr) 165 | { 166 | /* ----- test for remapped B drive ----- */ 167 | if (dr == 1) 168 | { 169 | regs.x.ax = 0x440e; /* IOCTL func 14 */ 170 | regs.h.bl = dr+1; 171 | int86(DOS, ®s, ®s); 172 | if (regs.h.al != 0) 173 | continue; 174 | 175 | } 176 | 177 | sprintf(drname, "[-%c-]", dr+'A'); 178 | 179 | #ifndef JOEDISK /* Test for network or RAM disk */ 180 | /* 181 | -- Commented out for now...don't really like or need this 182 | as of right now -- Joe 183 | */ 184 | regs.x.ax = 0x4409; /* IOCTL func 9: check for subst/net */ 185 | regs.h.bl = dr+1; 186 | int86(DOS, ®s, ®s); 187 | if (!regs.x.cflag) 188 | { 189 | if (regs.x.dx & 0x1000) 190 | #if 0 /* only for MS ramdisks (0x4800 or 0x0800). Other signs: */ 191 | /* Ramdisks often have only 1 FAT and 1 "head". Other flags: */ 192 | /* test bit 0x8000 for SUBST. (and: 0x200: "no sector I/O"). */ 193 | strcat(drname, " (Net)"); 194 | else if (regs.x.dx == 0x0800) 195 | strcat(drname, " (RAM)"); 196 | #else 197 | { /* design by -ea ;-) */ 198 | drname[0] = '<'; 199 | drname[4] = '>'; 200 | }; /* "<-X->" for network, "[-X-]" for normal */ 201 | /* CD-ROM counts as network. Add CD-checking? */ 202 | #endif 203 | } 204 | SendMessage(lwnd,ADDTEXT,(PARAM)drname,0); 205 | #endif 206 | } 207 | 208 | } 209 | 210 | SendMessage(lwnd, SHOW_WINDOW, 0, 0); 211 | setdisk(cd); 212 | } 213 | } 214 | 215 | void BuildPathDisplay(WINDOW wnd) 216 | { 217 | CTLWINDOW *ct = FindCommand(wnd->extension, ID_PATH,TEXT); 218 | if (ct != NULL) 219 | { 220 | int len; 221 | WINDOW lwnd = ct->wnd; 222 | 223 | CreatePath(path, "*.*", FALSE, FALSE); 224 | len = strlen(path); 225 | if ( (path[len-1] == '\\') && (len > 3) ) 226 | path[len-1] = '\0'; /* strip final backslash IF dirname given */ 227 | 228 | SendMessage(lwnd,SETTEXT,(PARAM)path,0); 229 | SendMessage(lwnd, PAINT, 0, 0); 230 | } 231 | 232 | } 233 | -------------------------------------------------------------------------------- /source/edit.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/edit/4ed5d50a4d2d516e857478ab437985d1e07b9eb3/source/edit.c -------------------------------------------------------------------------------- /source/edit.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/edit/4ed5d50a4d2d516e857478ab437985d1e07b9eb3/source/edit.txt -------------------------------------------------------------------------------- /source/editor.c: -------------------------------------------------------------------------------- 1 | /* ------------- editor.c ------------ */ 2 | #include "dflat.h" 3 | 4 | /* 5 | * Hint: TAB_TOGGLING mode is not used in EDIT 0.6* anyway, 6 | * but if it is on, char values 0x89 and 0x8c have special 7 | * meanings. They and 0x8d and 0xa0 are called whitespace 8 | * in this mode! To use, hook functions to expand and 9 | * collapse tabs in the tab size selection and in load/save!? 10 | */ 11 | 12 | #ifdef TAB_TOGGLING 13 | #define pTab ('\t' + 0x80) /* the tab itself plus a special flag */ 14 | #define sTab ('\f' + 0x80) /* space padding for the tabby looks */ 15 | #endif 16 | 17 | /* ---------- SETTEXT Message ------------ */ 18 | static int SetTextMsg(WINDOW wnd, char *Buf) 19 | { 20 | unsigned char *tp, *ep, *ttp; 21 | unsigned int x = 0; /* column */ 22 | unsigned int sz = 0; /* buffer size */ 23 | int rtn; 24 | 25 | tp = Buf; 26 | /* --- compute the buffer size based on tabs in the text --- */ 27 | while (*tp) 28 | { 29 | if (*tp == '\t') 30 | { 31 | /* --- tab, adjust the buffer length --- */ 32 | int sps = cfg.Tabs - (x % cfg.Tabs); /* even valid in non-tab mode */ 33 | sz += sps; 34 | x += sps; 35 | } 36 | else 37 | { 38 | /* --- not a tab, count the character --- */ 39 | sz++; 40 | x++; 41 | } 42 | 43 | if (*tp == '\n') 44 | x = 0; /* newline, reset x --- */ 45 | 46 | tp++; 47 | } /* while */ 48 | 49 | ep = DFcalloc(1, sz+1); /* allocate a buffer */ 50 | /* --- detab the input file --- */ 51 | tp = Buf; 52 | ttp = ep; 53 | x = 0; 54 | while (*tp) 55 | { 56 | /* --- put the character (\t, too) into the buffer --- */ 57 | x++; 58 | /* --- expand tab into subst tab (\f + 0x80) 59 | and expansions (\t + 0x80) --- */ 60 | if (*tp == '\t') 61 | { 62 | if (cfg.Tabs > 1) /* normal tab-expansion mode */ 63 | { 64 | #ifdef TAB_TOGGLING 65 | *ttp++ = sTab; /* --- substitute tab character --- */ 66 | #else 67 | *ttp++ = ' '; 68 | #endif 69 | while ((x % cfg.Tabs) != 0) 70 | { 71 | #ifdef TAB_TOGGLING 72 | *ttp++ = pTab; 73 | #else 74 | *ttp++ = ' '; 75 | #endif 76 | x++; 77 | } 78 | } 79 | else 80 | *ttp++ = '\t'; /* leave-tab-as-char mode -ea */ 81 | } 82 | else 83 | { 84 | *ttp++ = *tp; 85 | if (*tp == '\n') 86 | x = 0; 87 | } 88 | 89 | tp++; 90 | } /* while *tp */ 91 | 92 | *ttp = '\0'; 93 | rtn = BaseWndProc(EDITOR, wnd, SETTEXT, (PARAM) ep, 0); 94 | free(ep); 95 | return rtn; 96 | } 97 | 98 | #ifdef TAB_TOGGLING /* currently (0.6*) unused. Interesting to know... */ 99 | void CollapseTabs(WINDOW wnd) 100 | { 101 | unsigned char *cp = wnd->text; 102 | unsigned char *cp2; 103 | 104 | while (*cp) 105 | { 106 | if (*cp == pTab) /* substituted tab -> tab again */ 107 | { 108 | *cp = '\t'; 109 | cp2 = cp; 110 | while (*++cp2 == sTab); /* space padding after tab -> zap */ 111 | memmove(cp+1, cp2, strlen(cp2)+1); 112 | } 113 | cp++; 114 | } 115 | 116 | } 117 | #endif 118 | 119 | #ifdef TAB_TOGGLING /* currently (0.6*) unused. Interesting to know... */ 120 | void ExpandTabs(WINDOW wnd) 121 | { 122 | int Holdwtop = wnd->wtop; 123 | int Holdwleft = wnd->wleft; 124 | int HoldRow = wnd->CurrLine; 125 | int HoldCol = wnd->CurrCol; 126 | int HoldwRow = wnd->WndRow; 127 | 128 | SendMessage(wnd, SETTEXT, (PARAM) wnd->text, 0); 129 | wnd->wtop = Holdwtop; 130 | wnd->wleft = Holdwleft; 131 | wnd->CurrLine = HoldRow; 132 | wnd->CurrCol = HoldCol; 133 | wnd->WndRow = HoldwRow; 134 | SendMessage(wnd, PAINT, 0, 0); 135 | SendMessage(wnd, KEYBOARD_CURSOR, 0, wnd->WndRow); 136 | } 137 | #endif /* TAB_TOGGLING */ 138 | 139 | /* --- When inserting or deleting, adjust next following tab, same line --- */ 140 | /* updates current TAB expansion lengths */ 141 | #ifdef TAB_TOGGLING 142 | static void AdjustTab(WINDOW wnd) 143 | { 144 | int col = wnd->CurrCol; 145 | 146 | while (*CurrChar && *CurrChar != '\n') 147 | { 148 | if (*CurrChar == sTab) 149 | { 150 | int exp = (cfg.Tabs - 1) - (wnd->CurrCol % cfg.Tabs); 151 | 152 | wnd->CurrCol++; 153 | while (*CurrChar == pTab) 154 | BaseWndProc(EDITOR, wnd, KEYBOARD, DEL, 0); 155 | 156 | while (exp--) 157 | BaseWndProc(EDITOR, wnd, KEYBOARD, pTab, 0); 158 | 159 | break; 160 | } 161 | wnd->CurrCol++; 162 | } 163 | wnd->CurrCol = col; 164 | } 165 | #endif 166 | 167 | static void TurnOffDisplay(WINDOW wnd) 168 | { 169 | SendMessage(NULL, HIDE_CURSOR, 0, 0); 170 | ClearVisible(wnd); 171 | } 172 | 173 | static void TurnOnDisplay(WINDOW wnd) 174 | { 175 | SetVisible(wnd); 176 | SendMessage(NULL, SHOW_CURSOR, 0, 0); 177 | } 178 | 179 | static void RepaintLine(WINDOW wnd) 180 | { 181 | SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); 182 | WriteTextLine(wnd, NULL, wnd->CurrLine, FALSE); 183 | } 184 | 185 | /* --------- KEYBOARD Message ---------- */ 186 | static int KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2) 187 | { 188 | int c = (int) p1; 189 | BOOL delnl; 190 | #ifdef TAB_TOGGLING 191 | PARAM pn = p1; 192 | #endif 193 | if (WindowMoving || WindowSizing || ((int)p2 & ALTKEY)) 194 | return FALSE; 195 | switch (c) { 196 | case PGUP: 197 | case PGDN: 198 | case UP: 199 | case DN: 200 | #ifdef TAB_TOGGLING 201 | pn = (PARAM) BS; /* !?!? */ 202 | #endif 203 | #ifdef HOOKKEYB 204 | case FWD: /* right arrow */ 205 | #else 206 | case LARROW: /* hope this makes sense */ 207 | case RARROW: /* formerly called FWD */ 208 | #endif 209 | case BS: 210 | TurnOffDisplay(wnd); 211 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 212 | #ifdef TAB_TOGGLING 213 | while (*CurrChar == pTab) /* zap adjacent tabby-spaces */ 214 | BaseWndProc(EDITOR, wnd, KEYBOARD, pn, p2); 215 | #endif 216 | TurnOnDisplay(wnd); 217 | return TRUE; 218 | case DEL: 219 | TurnOffDisplay(wnd); 220 | delnl = *CurrChar == '\n' || TextBlockMarked(wnd); 221 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 222 | #ifdef TAB_TOGGLING 223 | while (*CurrChar == pTab) /* zap adjacent tabby-spaces */ 224 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 225 | AdjustTab(wnd); 226 | #endif 227 | TurnOnDisplay(wnd); 228 | RepaintLine(wnd); 229 | if (delnl) 230 | SendMessage(wnd, PAINT, 0, 0); 231 | return TRUE; 232 | case '\t': /* type tab as tab-substitute plus tabby-space-substitutes */ 233 | if (cfg.Tabs > 1) /* unless in tab-type through mode -ea */ 234 | { 235 | TurnOffDisplay(wnd); 236 | #ifdef TAB_TOGGLING 237 | BaseWndProc(EDITOR, wnd, KEYBOARD, (PARAM) sTab, p2); 238 | while ((wnd->CurrCol % cfg.Tabs) != 0) 239 | BaseWndProc(EDITOR, wnd, KEYBOARD, pTab, p2); 240 | #else 241 | BaseWndProc(EDITOR, wnd, KEYBOARD, (PARAM) ' ', p2); 242 | while ((wnd->CurrCol % cfg.Tabs) != 0) 243 | BaseWndProc(EDITOR, wnd, KEYBOARD, ' ', p2); 244 | #endif 245 | TurnOnDisplay(wnd); 246 | RepaintLine(wnd); 247 | return TRUE; 248 | } /* else fall through to default! */ 249 | default: /* simply a typed char */ 250 | if ( (c < 256) /* *** && ( isprint(c) || c == '\r' ) *** */ 251 | ) 252 | { 253 | TurnOffDisplay(wnd); 254 | BaseWndProc(EDITOR, wnd, KEYBOARD, p1, p2); 255 | #ifdef TAB_TOGGLING 256 | AdjustTab(wnd); 257 | #endif 258 | TurnOnDisplay(wnd); 259 | RepaintLine(wnd); 260 | if (c == '\r') 261 | SendMessage(wnd, PAINT, 0, 0); 262 | return TRUE; 263 | } 264 | break; 265 | } 266 | return FALSE; 267 | } 268 | 269 | /* ------- Window processing module for EDITBOX class ------ */ 270 | int EditorProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 271 | { 272 | switch (msg) { 273 | case KEYBOARD: 274 | if (KeyboardMsg(wnd, p1, p2)) 275 | return TRUE; 276 | break; 277 | case SETTEXT: 278 | return SetTextMsg(wnd, (char *) p1); 279 | default: 280 | break; 281 | } 282 | return BaseWndProc(EDITOR, wnd, msg, p1, p2); 283 | } 284 | 285 | -------------------------------------------------------------------------------- /source/fileopen.c: -------------------------------------------------------------------------------- 1 | /* File-Open Dialog Box 2 | 3 | Part of FreeDOS Edit 4 | 5 | */ 6 | 7 | /* I N C L U D E S /////////////////////////////////////////////////////// */ 8 | 9 | #include "dflat.h" 10 | 11 | /* G L O B A L S ///////////////////////////////////////////////////////// */ 12 | 13 | static char FileSpec[15], SrchSpec[15], FileName[15]; 14 | extern DBOX FileOpen, SaveAs; 15 | 16 | /* P R O T O T Y P E S /////////////////////////////////////////////////// */ 17 | 18 | static BOOL DlgFileOpen(char *, char *, char *, DBOX *); 19 | static int DlgFnOpen(WINDOW, MESSAGE, PARAM, PARAM); 20 | static void InitDlgBox(WINDOW); 21 | #ifdef STRIPPATH 22 | static void StripPath(char *); 23 | #endif 24 | static BOOL IncompleteFilename(char *); 25 | BOOL BuildFileList(WINDOW, char *); 26 | void BuildDirectoryList(WINDOW); 27 | void BuildDriveList(WINDOW); 28 | void BuildPathDisplay(WINDOW); 29 | 30 | /* F U N C T I O N S ///////////////////////////////////////////////////// */ 31 | 32 | BOOL OpenFileDialogBox(char *Fspec, char *Fname) 33 | { 34 | return DlgFileOpen(Fspec, Fspec, Fname, &FileOpen); 35 | } 36 | 37 | /* Save as Dialog Box */ 38 | BOOL SaveAsDialogBox(char *Fspec, char *Sspec, char *Fname) 39 | { 40 | return DlgFileOpen(Fspec, Sspec ? Sspec : Fspec, Fname, &SaveAs); 41 | } 42 | 43 | /* Generic File Open */ 44 | static BOOL DlgFileOpen(char *Fspec, char *Sspec, char *Fname, DBOX *db) 45 | { 46 | BOOL rtn; 47 | 48 | strncpy(FileSpec, Fspec, 15); 49 | strncpy(SrchSpec, Sspec, 15); 50 | if ((rtn = DialogBox(NULL, db, TRUE, DlgFnOpen)) != FALSE) 51 | strcpy(Fname, FileName); 52 | 53 | return rtn; 54 | 55 | } 56 | 57 | /* Process dialog box messages */ 58 | static int DlgFnOpen(WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2) 59 | { 60 | switch (msg) 61 | { 62 | case CREATE_WINDOW: 63 | { 64 | int rtn = DefaultWndProc(wnd, msg, p1, p2); 65 | DBOX *db = wnd->extension; 66 | WINDOW cwnd = ControlWindow(db, ID_FILENAME); 67 | SendMessage(cwnd, SETTEXTLENGTH, 64, 0); 68 | return rtn; 69 | } 70 | case INITIATE_DIALOG: 71 | InitDlgBox(wnd); 72 | break; 73 | case COMMAND: 74 | switch ((int) p1) 75 | { 76 | case ID_OK: 77 | { 78 | if ((int)p2 == 0) 79 | { 80 | char fn[MAXPATH+1], nm[MAXFILE], ext[MAXEXT]; 81 | 82 | GetItemText(wnd, ID_FILENAME, fn, MAXPATH); 83 | fnsplit(fn, NULL, NULL, nm, ext); 84 | strcpy(FileName, nm); 85 | strcat(FileName, ext); 86 | CreatePath(NULL, fn, FALSE, TRUE); 87 | if (IncompleteFilename(FileName)) 88 | { 89 | /* --- no file name yet --- */ 90 | DBOX *db = wnd->extension; 91 | WINDOW cwnd = ControlWindow(db, ID_FILENAME); 92 | 93 | strcpy(FileSpec, FileName); 94 | strcpy(SrchSpec, FileName); 95 | InitDlgBox(wnd); 96 | SendMessage(cwnd, SETFOCUS, TRUE, 0); 97 | return TRUE; 98 | } 99 | 100 | } 101 | 102 | break; 103 | } 104 | case ID_FILES: 105 | switch ((int) p2) 106 | { 107 | case ENTERFOCUS: 108 | case LB_SELECTION: 109 | /* Selected a different filename */ 110 | GetDlgListText(wnd, FileName, ID_FILES); 111 | PutItemText(wnd, ID_FILENAME, FileName); 112 | break; 113 | case LB_CHOOSE: 114 | /* Choose a file name */ 115 | GetDlgListText(wnd, FileName, ID_FILES); 116 | SendMessage(wnd, COMMAND, ID_OK, 0); 117 | break; 118 | default: 119 | break; 120 | 121 | } 122 | return TRUE; 123 | case ID_DIRECTORY: 124 | switch ((int) p2) 125 | { 126 | case ENTERFOCUS: 127 | PutItemText(wnd, ID_FILENAME, FileSpec); 128 | break; 129 | case LB_CHOOSE: 130 | { 131 | /* Choose dir */ 132 | char dd[15]; 133 | 134 | GetDlgListText(wnd, dd, ID_DIRECTORY); 135 | chdir(dd); 136 | InitDlgBox(wnd); 137 | SendMessage(wnd, COMMAND, ID_OK, 0); 138 | break; 139 | } 140 | 141 | default: 142 | break; 143 | 144 | } 145 | return TRUE; 146 | 147 | case ID_DRIVE: 148 | switch ((int) p2) 149 | { 150 | case ENTERFOCUS: 151 | PutItemText(wnd, ID_FILENAME, FileSpec); 152 | break; 153 | case LB_CHOOSE: 154 | { 155 | /* Choose dir */ 156 | char dr[15]; 157 | GetDlgListText(wnd, dr, ID_DRIVE); 158 | /* *** 0.6e: string has form "[-X-]" *** */ 159 | setdisk(dr[2] - 'A'); /* fixed 0.6e: must use [2] */ 160 | InitDlgBox(wnd); 161 | SendMessage(wnd, COMMAND, ID_OK, 0); 162 | } 163 | default: 164 | break; 165 | 166 | } 167 | return TRUE; 168 | 169 | default: 170 | break; 171 | } 172 | default: 173 | break; 174 | 175 | } 176 | 177 | return DefaultWndProc(wnd, msg, p1, p2); 178 | 179 | } 180 | 181 | /* Initialize the dialog box */ 182 | static void InitDlgBox(WINDOW wnd) 183 | { 184 | if (*FileSpec) 185 | PutItemText(wnd, ID_FILENAME, FileSpec); 186 | 187 | BuildPathDisplay(wnd); 188 | if (BuildFileList(wnd, SrchSpec)) 189 | BuildDirectoryList(wnd); 190 | 191 | BuildDriveList(wnd); 192 | } 193 | 194 | /* Strip the drive and path information from a file spec */ 195 | #ifdef STRIPPATH /* normally not used... */ 196 | static void StripPath(char *filespec) 197 | { 198 | char *cp, *cp1; 199 | 200 | cp = strchr(filespec, ':'); 201 | if (cp != NULL) 202 | cp++; 203 | else 204 | cp = filespec; 205 | 206 | while (TRUE) 207 | { 208 | cp1 = strchr(cp, '\\'); 209 | if (cp1 == NULL) 210 | break; 211 | 212 | cp = cp1+1; 213 | } 214 | 215 | strcpy(filespec, cp); 216 | 217 | } 218 | #endif 219 | 220 | static BOOL IncompleteFilename(char *s) 221 | { 222 | int lc = strlen(s)-1; 223 | 224 | if (strchr(s, '?') || strchr(s, '*') || !*s) 225 | return TRUE; 226 | 227 | if (*(s+lc) == ':' || *(s+lc) == '\\') 228 | return TRUE; 229 | 230 | return FALSE; 231 | } 232 | -------------------------------------------------------------------------------- /source/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 | static FILE *helpfp; 11 | static char hline [160]; 12 | 13 | static struct helps *FirstHelp; 14 | static struct helps *LastHelp; 15 | static struct helps *ThisHelp; 16 | 17 | static void WriteText(char *); 18 | 19 | /* ---- compute the displayed length of a help text line --- */ 20 | static int HelpLength(char *s) 21 | { 22 | int len = strlen(s); 23 | char *cp = strchr(s, '['); 24 | while (cp != NULL) { 25 | len -= 4; 26 | cp = strchr(cp+1, '['); 27 | } 28 | cp = strchr(s, '<'); 29 | while (cp != NULL) { 30 | char *cp1 = strchr(cp, '>'); 31 | if (cp1 != NULL) 32 | len -= (int) (cp1-cp)+1; 33 | cp = strchr(cp1, '<'); 34 | } 35 | return len; 36 | } 37 | 38 | int FindHelp(char *nm) 39 | { 40 | int hlp = 0; 41 | struct helps *thishelp = FirstHelp; 42 | while (thishelp != NULL) { 43 | if (strcmp(nm, thishelp->hname) == 0) 44 | break; 45 | hlp++; 46 | thishelp = thishelp->NextHelp; 47 | } 48 | return thishelp ? hlp : -1; 49 | } 50 | 51 | main(int argc, char *argv[]) 52 | { 53 | char *cp; 54 | int HelpCount = 0; 55 | long where; 56 | 57 | if (argc < 2) 58 | return -1; 59 | 60 | if ((helpfp = OpenHelpFile(argv[1], "r+b")) == NULL) 61 | return -1; 62 | 63 | 64 | *hline = '\0'; 65 | while (*hline != '<') { 66 | if (GetHelpLine(hline) == NULL) { 67 | fclose(helpfp); 68 | return -1; 69 | } 70 | } 71 | while (*hline == '<') { 72 | if (strncmp(hline, "", 5) == 0) 73 | break; 74 | 75 | /* -------- parse the help window's text name ----- */ 76 | if ((cp = strchr(hline, '>')) != NULL) { 77 | ThisHelp = calloc(1, sizeof(struct helps)); 78 | if (FirstHelp == NULL) 79 | FirstHelp = ThisHelp; 80 | *cp = '\0'; 81 | ThisHelp->hname=malloc(strlen(hline+1)+1); 82 | strcpy(ThisHelp->hname, hline+1); 83 | 84 | HelpFilePosition(&ThisHelp->hptr, &ThisHelp->bit); 85 | 86 | if (GetHelpLine(hline) == NULL) 87 | break; 88 | 89 | /* ------- build the help linked list entry --- */ 90 | while (*hline == '[') { 91 | HelpFilePosition(&ThisHelp->hptr, 92 | &ThisHelp->bit); 93 | /* ------ parse a comment ----- */ 94 | if (strncmp(hline, "[*]", 3) == 0) { 95 | ThisHelp->comment=malloc(strlen(hline+3)+1); 96 | strcpy(ThisHelp->comment, hline+3); 97 | if (GetHelpLine(hline) == NULL) 98 | break; 99 | continue; 100 | } 101 | /* ---- parse the <'); 106 | if (cp1 != NULL) { 107 | int len = (int) (cp1-cp); 108 | ThisHelp->PrevName=calloc(1,len); 109 | strncpy(ThisHelp->PrevName, 110 | cp+1,len-1); 111 | } 112 | } 113 | if (GetHelpLine(hline) == NULL) 114 | break; 115 | continue; 116 | } 117 | /* ---- parse the next>> button pointer ---- */ 118 | else if (strncmp(hline, "[>>]", 4) == 0) { 119 | char *cp = strchr(hline+4, '<'); 120 | if (cp != NULL) { 121 | char *cp1 = strchr(cp, '>'); 122 | if (cp1 != NULL) { 123 | int len = (int) (cp1-cp); 124 | ThisHelp->NextName=calloc(1,len); 125 | strncpy(ThisHelp->NextName, 126 | cp+1,len-1); 127 | } 128 | } 129 | if (GetHelpLine(hline) == NULL) 130 | break; 131 | continue; 132 | } 133 | else 134 | break; 135 | } 136 | ThisHelp->hheight = 0; 137 | ThisHelp->hwidth = 0; 138 | ThisHelp->NextHelp = NULL; 139 | 140 | /* ------ append entry to the linked list ------ */ 141 | if (LastHelp != NULL) 142 | LastHelp->NextHelp = ThisHelp; 143 | LastHelp = ThisHelp; 144 | HelpCount++; 145 | } 146 | /* -------- move to the next token ------ */ 147 | if (GetHelpLine(hline) == NULL) 148 | strcpy(hline, ""); 149 | while (*hline != '<') { 150 | ThisHelp->hwidth = 151 | max(ThisHelp->hwidth, HelpLength(hline)); 152 | ThisHelp->hheight++; 153 | if (GetHelpLine(hline) == NULL) 154 | strcpy(hline, ""); 155 | } 156 | } 157 | /* --- append the help structures to the file --- */ 158 | fseek(helpfp, 0L, SEEK_END); 159 | where = ftell(helpfp); 160 | ThisHelp = FirstHelp; 161 | fwrite(&HelpCount, sizeof(int), 1, helpfp); 162 | while (ThisHelp != NULL) { 163 | ThisHelp->nexthlp = FindHelp(ThisHelp->NextName); 164 | ThisHelp->prevhlp = FindHelp(ThisHelp->PrevName); 165 | WriteText(ThisHelp->hname); 166 | WriteText(ThisHelp->comment); 167 | fwrite(&ThisHelp->hptr, sizeof(int)*5+sizeof(long), 1, helpfp); 168 | ThisHelp = ThisHelp->NextHelp; 169 | } 170 | fwrite(&where, sizeof(long), 1, helpfp); 171 | fclose(helpfp); 172 | return 0; 173 | } 174 | 175 | void BuildFileName(char *fn, const char *fname, const char *ext) 176 | { 177 | strcpy(fn, fname); 178 | strcat(fn, ext); 179 | } 180 | 181 | static void WriteText(char *text) 182 | { 183 | char *np = text ? text : ""; 184 | int len = strlen(np); 185 | fwrite(&len, sizeof(int), 1, helpfp); 186 | if (len) 187 | fwrite(np, len+1, 1, helpfp); 188 | } 189 | -------------------------------------------------------------------------------- /source/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 | 26 | -------------------------------------------------------------------------------- /source/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 | 65 | -------------------------------------------------------------------------------- /source/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 | 32 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/keys.c: -------------------------------------------------------------------------------- 1 | /* Key combinations 2 | 3 | Part of the FreeDOS Editor 4 | 5 | */ 6 | 7 | #include 8 | #include "keys.h" 9 | 10 | struct keys keys[] = { 11 | {F1, "F1"}, 12 | {F2, "F2"}, 13 | {F3, "F3"}, 14 | {F4, "F4"}, 15 | {F5, "F5"}, 16 | {F6, "F6"}, 17 | {F7, "F7"}, 18 | {F8, "F8"}, 19 | {F9, "F9"}, 20 | {F10, "F10"}, 21 | {CTRL_F1, "Ctrl+F1"}, 22 | {CTRL_F2, "Ctrl+F2"}, 23 | {CTRL_F3, "Ctrl+F3"}, 24 | {CTRL_F4, "Ctrl+F4"}, 25 | {CTRL_F5, "Ctrl+F5"}, 26 | {CTRL_F6, "Ctrl+F6"}, 27 | {CTRL_F7, "Ctrl+F7"}, 28 | {CTRL_F8, "Ctrl+F8"}, 29 | {CTRL_F9, "Ctrl+F9"}, 30 | {CTRL_F10, "Ctrl+F10"}, 31 | {ALT_F1, "Alt+F1"}, 32 | {ALT_F2, "Alt+F2"}, 33 | {ALT_F3, "Alt+F3"}, 34 | {ALT_F4, "Alt+F4"}, 35 | {ALT_F5, "Alt+F5"}, 36 | {ALT_F6, "Alt+F6"}, 37 | {ALT_F7, "Alt+F7"}, 38 | {ALT_F8, "Alt+F8"}, 39 | {ALT_F9, "Alt+F9"}, 40 | {ALT_F10, "Alt+F10"}, 41 | {HOME, "Home"}, 42 | {UP, "Up"}, 43 | {PGUP, "PgUp"}, 44 | {BS, "BS"}, 45 | {END, "End"}, 46 | {DN, "Dn"}, 47 | {PGDN, "PgDn"}, 48 | {INS, "Ins"}, 49 | {DEL, "Del"}, 50 | {CTRL_HOME, "Ctrl+Home"}, 51 | {CTRL_PGUP, "Ctrl+PgUp"}, 52 | {CTRL_BS, "Ctrl+BS"}, 53 | {CTRL_END, "Ctrl+End"}, 54 | {CTRL_PGDN, "Ctrl+PgDn"}, 55 | {SHIFT_HT, "Shift+Tab"}, 56 | #ifdef HOOKKEYB 57 | {ALT_BS, "Alt+BS"}, 58 | {ALT_DEL, "Alt+Del"}, 59 | {SHIFT_DEL, "Shift+Del"}, 60 | {SHIFT_INS, "Shift+Ins"}, 61 | {CTRL_INS, "Ctrl+Ins"}, 62 | #endif 63 | {ALT_A, "Alt+A"}, 64 | {ALT_B, "Alt+B"}, 65 | {ALT_C, "Alt+C"}, 66 | {ALT_D, "Alt+D"}, 67 | {ALT_E, "Alt+E"}, 68 | {ALT_F, "Alt+F"}, 69 | {ALT_G, "Alt+G"}, 70 | {ALT_H, "Alt+H"}, 71 | {ALT_I, "Alt+I"}, 72 | {ALT_J, "Alt+J"}, 73 | {ALT_K, "Alt+K"}, 74 | {ALT_L, "Alt+L"}, 75 | {ALT_M, "Alt+M"}, 76 | {ALT_N, "Alt+N"}, 77 | {ALT_O, "Alt+O"}, 78 | {ALT_P, "Alt+P"}, 79 | {ALT_Q, "Alt+Q"}, 80 | {ALT_R, "Alt+R"}, 81 | {ALT_S, "Alt+S"}, 82 | {ALT_T, "Alt+T"}, 83 | {ALT_U, "Alt+U"}, 84 | {ALT_V, "Alt+V"}, 85 | {ALT_W, "Alt+W"}, 86 | {ALT_X, "Alt+X"}, 87 | {ALT_Y, "Alt+Y"}, 88 | {ALT_Z, "Alt+Z"}, 89 | {CTRL_C, "Ctrl+C"}, 90 | {CTRL_V, "Ctrl+V"}, 91 | {CTRL_X, "Ctrl+X"}, 92 | /* new 0.7c - note that this has to be the non-numpad style alt-digit... */ 93 | /* otherwise you have problems to distinguish alt-digit from ctrl-letter */ 94 | {ALT_1, "Alt+1"}, 95 | {ALT_2, "Alt+2"}, 96 | {ALT_3, "Alt+3"}, 97 | {ALT_4, "Alt+4"}, 98 | {ALT_5, "Alt+5"}, 99 | {ALT_6, "Alt+6"}, 100 | {ALT_7, "Alt+7"}, 101 | {ALT_8, "Alt+8"}, 102 | {ALT_9, "Alt+9"}, 103 | {-1, NULL} 104 | }; 105 | -------------------------------------------------------------------------------- /source/keys.h: -------------------------------------------------------------------------------- 1 | /* ----------- keys.h ------------ */ 2 | 3 | #ifndef KEYS_H 4 | #define KEYS_H 5 | 6 | #ifdef HOOKKEYB 7 | #define OFFSET 0x1000 8 | #error You have to restore keys.h to EDIT 0.6 state to re-enable int 9 handling! 9 | #else 10 | #define FKEY 0x1000 /* offset for non-ASCII keys */ 11 | #endif 12 | 13 | #define BELL 7 /* no scancode */ 14 | #define BS 8 /* scancode: 14 */ /* backspace / rubout */ 15 | #define TAB 9 /* scancode: 15 */ 16 | #define ESC 27 /* scancode: 1 */ 17 | 18 | #define F1 (FKEY+0x3b) /* scancode: 0x3b */ 19 | #define F2 (FKEY+0x3c) 20 | #define F3 (FKEY+0x3d) 21 | #define F4 (FKEY+0x3e) 22 | #define F5 (FKEY+0x3f) 23 | #define F6 (FKEY+0x40) 24 | #define F7 (FKEY+0x41) 25 | #define F8 (FKEY+0x42) 26 | #define F9 (FKEY+0x43) 27 | #define F10 (FKEY+0x44) 28 | 29 | #define CTRL_F1 (FKEY+94) 30 | #define CTRL_F2 (FKEY+95) 31 | #define CTRL_F3 (FKEY+96) 32 | #define CTRL_F4 (FKEY+97) 33 | #define CTRL_F5 (FKEY+98) 34 | #define CTRL_F6 (FKEY+99) 35 | #define CTRL_F7 (FKEY+100) 36 | #define CTRL_F8 (FKEY+101) 37 | #define CTRL_F9 (FKEY+102) 38 | #define CTRL_F10 (FKEY+103) 39 | 40 | #define ALT_F1 (FKEY+104) 41 | #define ALT_F2 (FKEY+105) 42 | #define ALT_F3 (FKEY+106) 43 | #define ALT_F4 (FKEY+107) 44 | #define ALT_F5 (FKEY+108) 45 | #define ALT_F6 (FKEY+109) 46 | #define ALT_F7 (FKEY+110) 47 | #define ALT_F8 (FKEY+111) 48 | #define ALT_F9 (FKEY+112) 49 | #define ALT_F10 (FKEY+113) 50 | 51 | #define HOME (FKEY+0x47) /* scancode: 0x47 */ 52 | #define UP (FKEY+0x48) 53 | #define PGUP (FKEY+0x49) 54 | /* 4a: grey- 4b: left 4c: keypad5 4d: right 4e: grey+ */ 55 | #define END (FKEY+0x4f) 56 | #define DN (FKEY+0x50) 57 | #define PGDN (FKEY+0x51) 58 | #define INS (FKEY+0x52) 59 | #define DEL (FKEY+0x53) 60 | 61 | #define LARROW (FKEY+0x4b) /* -ea */ 62 | #define RARROW (FKEY+0x4d) /* -ea */ 63 | /* old name of RARROW is "FWD" ... */ 64 | 65 | /* valid in ANSI, so assuming that those are universal: */ 66 | #define CTRL_END (FKEY+117) 67 | #define CTRL_PGDN (FKEY+118) 68 | #define CTRL_HOME (FKEY+119) 69 | #define CTRL_PGUP (FKEY+132) 70 | 71 | /* #define CTRL_FIVE (143) */ /* ctrl-numeric-keypad-5 */ 72 | #ifdef HOOKKEYB 73 | #define CTRL_FWD (244) /* ctrl-rightarrow */ 74 | #else 75 | #define CTRL_LARROW (FKEY+0x73) /* ctrl-leftarrow */ 76 | #define CTRL_RARROW (FKEY+0x74) /* ctrl-rightarrow */ 77 | #endif 78 | 79 | #define CTRL_BS (127) /* yet another deletion keystroke */ 80 | #define SHIFT_HT (FKEY+0x0f) /* scancode: 0x0f */ 81 | #define ALT_HYPHEN (130) 82 | 83 | #ifdef HOOKKEYB /* only available with own int 9 handler! */ 84 | #define ALT_BS (197) /* HOOKKEYB only! */ 85 | #define ALT_DEL (184) /* HOOKKEYB only! */ 86 | #define CTRL_INS (186) /* HOOKKEYB only! */ 87 | /* the next few are even missing in our int 9 handler!? */ 88 | #define SHIFT_DEL (198) /* HOOKKEYB only! */ 89 | #define SHIFT_INS (185) /* HOOKKEYB only! */ 90 | #define SHIFT_F8 (219) /* HOOKKEYB only! */ 91 | #else /* in 0.7, this finally works again, for AT keyboards */ 92 | #define ALT_BS CTRL_Z /* undo block removal */ 93 | #define CTRL_INS CTRL_C /* clipboard copy */ 94 | #define SHIFT_DEL CTRL_X /* clipboard cut */ 95 | #define SHIFT_INS CTRL_V /* clipboard paste */ 96 | #endif 97 | 98 | 99 | /* stupid... those depend on keyboard layout! */ 100 | #define ALT_A (FKEY+0x1e) /* scancode 0x1e */ 101 | #define ALT_S (FKEY+0x1f) 102 | #define ALT_D (FKEY+0x20) 103 | #define ALT_F (FKEY+0x21) 104 | #define ALT_G (FKEY+0x22) 105 | #define ALT_H (FKEY+0x23) 106 | #define ALT_J (FKEY+0x24) 107 | #define ALT_K (FKEY+0x25) 108 | #define ALT_L (FKEY+0x26) 109 | 110 | #define ALT_Q (FKEY+0x10) 111 | #define ALT_W (FKEY+0x11) 112 | #define ALT_E (FKEY+0x12) 113 | #define ALT_R (FKEY+0x13) 114 | #define ALT_T (FKEY+0x14) 115 | #define ALT_Y (FKEY+0x15) 116 | #define ALT_U (FKEY+0x16) 117 | #define ALT_I (FKEY+0x17) 118 | #define ALT_O (FKEY+0x18) 119 | #define ALT_P (FKEY+0x19) 120 | 121 | #define ALT_Z (FKEY+0x2c) 122 | #define ALT_X (FKEY+0x2d) 123 | #define ALT_C (FKEY+0x2e) 124 | #define ALT_B (FKEY+0x2f) 125 | #define ALT_V (FKEY+0x30) 126 | #define ALT_N (FKEY+0x31) 127 | #define ALT_M (FKEY+0x32) 128 | 129 | 130 | #define ALT_1 (FKEY+0x78) /* 120 */ 131 | #define ALT_2 (FKEY+0x79) 132 | #define ALT_3 (FKEY+0x7a) 133 | #define ALT_4 (FKEY+0x7b) 134 | #define ALT_5 (FKEY+0x7c) 135 | #define ALT_6 (FKEY+0x7d) 136 | #define ALT_7 (FKEY+0x7e) 137 | #define ALT_8 (FKEY+0x7f) 138 | #define ALT_9 (FKEY+0x80) 139 | #define ALT_0 (FKEY+0x81) 140 | 141 | 142 | /* those are values that are at least typical for DOS: */ 143 | #define CTRL_A 1 144 | #define CTRL_B 2 145 | #define CTRL_C 3 /* must have "ignore ^C / ^Break handler to use this */ 146 | /* see messages.c */ 147 | #define CTRL_D 4 148 | #define CTRL_E 5 149 | #define CTRL_F 6 /* (special meaning for DOS-CON readline?) */ 150 | #define CTRL_G 7 151 | #define CTRL_H 8 152 | #define CTRL_I 9 153 | #define CTRL_J 10 154 | #define CTRL_K 11 155 | #define CTRL_L 12 156 | #define CTRL_M 13 157 | #define CTRL_N 14 158 | #define CTRL_O 15 159 | #define CTRL_P 16 /* (causes print in DOS-CON) */ 160 | #define CTRL_Q 17 161 | #define CTRL_R 18 162 | #define CTRL_S 19 /* (causes scroll-halt in DOS-CON) */ 163 | #define CTRL_T 20 164 | #define CTRL_U 21 165 | #define CTRL_V 22 166 | #define CTRL_W 23 167 | #define CTRL_X 24 168 | #define CTRL_Y 25 169 | #define CTRL_Z 26 /* (marks EOF in DOS-CON) */ 170 | 171 | 172 | /* shift bit mask */ 173 | #define RIGHTSHIFT 0x01 174 | #define LEFTSHIFT 0x02 175 | #define CTRLKEY 0x04 176 | #define ALTKEY 0x08 177 | #define SCROLLLOCK 0x10 178 | #define NUMLOCK 0x20 179 | #define CAPSLOCK 0x40 /* caps lock BEING on */ 180 | #define INSERTKEY 0x80 181 | 182 | /* Following is new by Eric 11/2002, but see CONSOLE.C */ 183 | #define SYSRQKEY 0x8000 184 | #define CAPSLKEY 0x4000 /* PRESSING caps lock */ 185 | #define NUMLKEY 0x2000 186 | #define SCROLLLKEY 0x1000 187 | /* Especially the L/R distinction is important - Eric */ 188 | #define RALTKEY 0x800 /* treat this als AltGr, which is NOT Alt */ 189 | #define RCTRLKEY 0x400 190 | #define LALTKEY 0x200 191 | #define LCTRLKEY 0x100 192 | 193 | struct keys { 194 | int keycode; 195 | char *keylabel; 196 | }; 197 | extern struct keys keys[]; 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /source/lists.c: -------------------------------------------------------------------------------- 1 | /* --------------- lists.c -------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | /* ----- set focus to the next sibling ----- */ 6 | void SetNextFocus() 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() 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 | /* Bad: This shuffles around the window list items, but we need */ 65 | /* it as the "next" relation of siblings determines the window */ 66 | /* stacking: Z coordinate, "last" window is the topmost one... */ 67 | void ReFocus(WINDOW wnd) 68 | { 69 | if (GetParent(wnd) != NULL) { 70 | RemoveWindow(wnd); /* splice out window from list: */ 71 | /* if it was a first-child, make the next one first, */ 72 | /* if it was a last-child, make the previous one last */ 73 | AppendWindow(wnd); /* add window as last one in list: */ 74 | /* if it has a parent w/o first-child, make it first, */ 75 | /* if it has a parent, make it last-child... */ 76 | ReFocus(GetParent(wnd)); /* recurse until at top */ 77 | } 78 | } 79 | 80 | /* ---- remove a window from the linked list ---- */ 81 | void RemoveWindow(WINDOW wnd) 82 | { 83 | if (wnd != NULL) { 84 | WINDOW pwnd = GetParent(wnd); 85 | if (PrevWindow(wnd) != NULL) 86 | NextWindow(PrevWindow(wnd)) = NextWindow(wnd); 87 | if (NextWindow(wnd) != NULL) 88 | PrevWindow(NextWindow(wnd)) = PrevWindow(wnd); 89 | if (pwnd != NULL) { 90 | if (wnd == FirstWindow(pwnd)) 91 | FirstWindow(pwnd) = NextWindow(wnd); 92 | if (wnd == LastWindow(pwnd)) 93 | LastWindow(pwnd) = PrevWindow(wnd); 94 | } 95 | } 96 | } 97 | 98 | /* ---- append a window to the linked list ---- */ 99 | void AppendWindow(WINDOW wnd) 100 | { 101 | if (wnd != NULL) { 102 | WINDOW pwnd = GetParent(wnd); 103 | if (pwnd != NULL) { 104 | if (FirstWindow(pwnd) == NULL) 105 | FirstWindow(pwnd) = wnd; 106 | if (LastWindow(pwnd) != NULL) 107 | NextWindow(LastWindow(pwnd)) = wnd; 108 | PrevWindow(wnd) = LastWindow(pwnd); 109 | LastWindow(pwnd) = wnd; 110 | } 111 | NextWindow(wnd) = NULL; 112 | } 113 | } 114 | 115 | /* ----- if document windows and statusbar or menubar get the focus, 116 | pass it on ------- */ 117 | void SkipApplicationControls(void) 118 | { 119 | BOOL EmptyAppl = FALSE; 120 | int ct = 0; 121 | while (!EmptyAppl && inFocus != NULL) { 122 | CLASS cl = GetClass(inFocus); 123 | if (cl == MENUBAR || cl == STATUSBAR) { 124 | SetPrevFocus(); 125 | EmptyAppl = (cl == MENUBAR && ct++); 126 | } 127 | else 128 | break; 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/makefile: -------------------------------------------------------------------------------- 1 | # FreeDOS Editor Makefile 2 | # By Joe Cosentino and Jeremy Davis (updated by Eric Auer 11/2003) 3 | # 4 | # For use with Turbo C 2.01, Turbo C++ 1.01, Turbo C/C++ 3.0 5 | # and Borland C/C++ 3.1 - if you have another compiler, please 6 | # send us your adjusted makefile to share it with the community. 7 | # 8 | 9 | all : edit.exe edit.hlp 10 | 11 | #------------------------------------------------ 12 | # NOTE: Set DRIVE to match where you installed your compiler 13 | #------------------------------------------------ 14 | DRIVE = c:\tc 15 | #DRIVE = c:\tc201 16 | #DRIVE = c:\tc101 17 | #DRIVE = c:\tc30 18 | #DRIVE = c:\borlandc 19 | 20 | #------------------------------------------------------------------- 21 | # This macro builds the full Edit system with all options enabled. 22 | # Comment it out for a minimum system or selectively 23 | # comment out the #defines at the top of dflat.h. 24 | #------------------------------------------------------------------- 25 | FULL = -DBUILD_FULL_DFLAT 26 | 27 | #------------------------------------------------------------------- 28 | # Select a memory model here. L = LARGE recommended. 29 | # T tiny, S small (default), M medium, C compact, L large, H huge. 30 | # T: 1 ds/ss/cs, all near. 31 | # S: 1 cs, 1 ds/ss, all near. 32 | # M: 1 ds/ss, many CS, functions far. 33 | # C: 1 ds/ss, 1 cs, heap (malloc'ed data) is far. 34 | # L: 1 ds/ss, many CS, functions and heap are far. 35 | # H: 1 ss, many CS, many DS (static vars), everything far. 36 | MODEL = l 37 | 38 | #------------------------------------------------ 39 | # NOTE: Delete the DEBUG and LINKDEBUG macros to 40 | # build without debugging information in the .EXE 41 | #------------------------------------------------ 42 | #DEBUG = -v -Od 43 | #LINKDEBUG = /m /v 44 | LINKDEBUG = /m 45 | 46 | #------------------------------------------------ 47 | # NOTE: Temporary file space. Change to match 48 | # your computer. A RAM disk works best. 49 | #------------------------------------------------ 50 | HEADERS=tcdef.sym 51 | 52 | #------------------------------------------------ 53 | # Set to match your compiler 54 | #------------------------------------------------ 55 | CC = tcc 56 | #CC = bcc 57 | LINKER = tlink 58 | LIB = tlib 59 | 60 | #------------------------------------------------ 61 | # Set any extra options here 62 | #------------------------------------------------ 63 | # -1 use 186/286 -G for speed -K unsigned char -Z optimize register usage 64 | # -O optimize jumps -M create link map -a word align (handle with care!) 65 | # -f emulate FPU (default) -f- use no FPU -f87 use native FPU 66 | # -r use reg vars -w enable warnings -N add stack checks 67 | # -k use standard stack frame -p use pascal calls ... 68 | # *** -w should only display "structure passed by value" errors! 69 | # ### Feel free to use -w-stv to mute those 70 | # ### and still see all other error messages. 71 | # ### adding -K ("default char is unsigned"), as dflat has unsigned char! 72 | CCEXTRA = -K -w -w-stv 73 | # Calendar utility; you can disable (remove from menu) by defining NOCALENDAR 74 | #CCEXTRA = $(CCEXTRA) -DNOCALENDAR 75 | 76 | #------------------------------------------------ 77 | # -c is "compile only" (do not link), -d "merge duplicate strings" 78 | COMPILE = $(CC) $(DEBUG) $(FULL) -c -d -m$(MODEL) $(CCEXTRA) -I$(DRIVE)\include -L$(DRIVE)\lib 79 | LINK= $(LINKER) $(LINKDEBUG) $(DRIVE)\lib\c0$(MODEL) 80 | LIBS= $(DRIVE)\lib\c$(MODEL) 81 | 82 | #------------------------------------------------ 83 | # *** You should never have to modify this file below this line! *** 84 | 85 | .c.obj: 86 | $(COMPILE) $*.c 87 | 88 | # creates the main binary 89 | edit.exe : edit.obj dialogs.obj menus.obj dflat.lib 90 | $(LINK) edit dialogs menus,edit.exe,edit,dflat $(LIBS) 91 | 92 | # dflat.bld contents: For each of the listed .obj files, 1 line like 93 | # "+windows.obj &". Do not put an & after the last line. 94 | dflat.lib : window.obj video.obj message.obj \ 95 | mouse.obj console.obj textbox.obj listbox.obj \ 96 | normal.obj config.obj menu.obj menubar.obj popdown.obj \ 97 | rect.obj applicat.obj keys.obj sysmenu.obj editbox.obj \ 98 | dialbox.obj button.obj fileopen.obj msgbox.obj \ 99 | helpbox.obj log.obj lists.obj statbar.obj decomp.obj \ 100 | combobox.obj pictbox.obj clipbord.obj search.obj \ 101 | dfalloc.obj checkbox.obj text.obj radio.obj box.obj \ 102 | spinbutt.obj watch.obj slidebox.obj direct.obj \ 103 | editor.obj calendar.obj asciitab.obj 104 | del dflat.lib 105 | $(LIB) dflat @dflat.bld 106 | 107 | # help file helper tool 108 | huffc.exe : huffc.obj htree.obj 109 | $(LINK) huffc htree,$*.exe,$*,$(LIBS) 110 | 111 | # help file helper tool 112 | fixhelp.exe : fixhelp.obj decomp.obj 113 | $(LINK) fixhelp decomp,$*.exe,$*,$(LIBS) 114 | 115 | # runs huffc and fixhelp to compress and index the help file 116 | edit.hlp : edit.txt huffc.exe fixhelp.exe 117 | huffc edit.txt edit.hlp 118 | fixhelp edit 119 | 120 | # run this make target to compress EDIT with UPX (http://upx.sf.net/) 121 | # the --best option compresses much slower but only very slighly better. 122 | upx : all 123 | upx --8086 --best edit.exe 124 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/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 | 64 | -------------------------------------------------------------------------------- /source/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 | /* is the key one of the globally valid accel keys? */ 107 | static void KeyboardMsg(WINDOW wnd, PARAM p1) 108 | { 109 | MENU *mnu; 110 | int sel; 111 | if (mwnd == NULL) { 112 | /* ----- search for menu bar shortcut keys ---- */ 113 | int c = tolower((int)p1); 114 | int a = AltConvert((int)p1); 115 | int j; 116 | for (j = 0; j < mctr; j++) { 117 | if ((inFocus == wnd && menu[j].sc == c) || 118 | (a && menu[j].sc == a)) { 119 | SendMessage(wnd, SETFOCUS, TRUE, 0); 120 | SendMessage(wnd, MB_SELECTION, j, 0); 121 | return; 122 | } 123 | } 124 | } 125 | /* -------- search for accelerator keys -------- */ 126 | mnu = ActiveMenu; 127 | while (mnu->Title != (void *)-1) { 128 | struct PopDown *pd = mnu->Selections; 129 | if (mnu->PrepMenu) 130 | (*(mnu->PrepMenu))(GetDocFocus(), mnu); 131 | sel = 0; 132 | while (pd->SelectionTitle != NULL) { 133 | if (pd->Accelerator == (int) p1) { 134 | if (pd->Attrib & INACTIVE) 135 | beep(); 136 | else { 137 | if (pd->Attrib & TOGGLE) 138 | pd->Attrib ^= CHECKED; 139 | /* wnd->mnu->Selection is only for highlighting */ 140 | /* inside visible popdowns. however, we set the */ 141 | /* CurrentMenuSelection for applicat.c, as extra */ 142 | /* parameter for the ID_WINDOW message... - 0.7c */ 143 | /* alternative would be using several ID_WINDOWx */ 144 | /* as actually *only* ID_WINDOW uses C.M.S. yet! */ 145 | CurrentMenuSelection = sel; 146 | SendMessage(GetDocFocus(), 147 | SETFOCUS, TRUE, 0); 148 | PostMessage(GetParent(wnd), 149 | COMMAND, pd->ActionId, 0); 150 | } 151 | return; 152 | } 153 | pd++; /* search through all items of the popdown */ 154 | sel++; 155 | } 156 | mnu++; /* search through all possible popdowns */ 157 | } 158 | switch ((int)p1) { 159 | case F1: /* help inside menubar - possible context sensitive */ 160 | if (ActiveMenu == NULL || ActiveMenuBar == NULL) 161 | break; 162 | sel = ActiveMenuBar->ActiveSelection; 163 | if (sel == -1) { 164 | BaseWndProc(MENUBAR, wnd, KEYBOARD, F1, 0); 165 | return; 166 | } 167 | mnu = ActiveMenu+sel; 168 | if (mwnd == NULL || 169 | mnu->Selections[0].SelectionTitle == NULL) { 170 | DisplayHelp(wnd,mnu->Title); 171 | return; 172 | } 173 | break; 174 | case DN: /* suggested by Fox: down arrow to open sub-menu (0.7b) */ 175 | case '\r': 176 | if (mwnd == NULL && 177 | ActiveMenuBar->ActiveSelection != -1) 178 | SendMessage(wnd, MB_SELECTION, 179 | ActiveMenuBar->ActiveSelection, 0); 180 | break; 181 | case F10: /* F10, as ALT, toggles menu bar activation */ 182 | if (wnd != inFocus && mwnd == NULL) { 183 | SendMessage(wnd, SETFOCUS, TRUE, 0); 184 | if ( ActiveMenuBar->ActiveSelection == -1) 185 | ActiveMenuBar->ActiveSelection = 0; 186 | SendMessage(wnd, PAINT, 0, 0); 187 | break; 188 | } 189 | /* ------- fall through ------- */ 190 | case ESC: 191 | if (inFocus == wnd && mwnd == NULL) { 192 | ActiveMenuBar->ActiveSelection = -1; 193 | SendMessage(GetDocFocus(),SETFOCUS,TRUE,0); 194 | SendMessage(wnd, PAINT, 0, 0); 195 | } 196 | break; 197 | #ifdef HOOKKEYB 198 | case FWD: /* right arrow */ 199 | #else 200 | case RARROW: /* formerly called FWD */ 201 | #endif 202 | ActiveMenuBar->ActiveSelection++; 203 | if (ActiveMenuBar->ActiveSelection == mctr) 204 | ActiveMenuBar->ActiveSelection = 0; 205 | if (mwnd != NULL) 206 | SendMessage(wnd, MB_SELECTION, 207 | ActiveMenuBar->ActiveSelection, 0); 208 | else 209 | SendMessage(wnd, PAINT, 0, 0); 210 | break; 211 | #ifndef HOOKKEYB: 212 | case LARROW: /* hope that makes sense */ 213 | #endif 214 | case BS: 215 | if (ActiveMenuBar->ActiveSelection == 0 || 216 | ActiveMenuBar->ActiveSelection == -1) 217 | ActiveMenuBar->ActiveSelection = mctr; 218 | --ActiveMenuBar->ActiveSelection; 219 | if (mwnd != NULL) 220 | SendMessage(wnd, MB_SELECTION, 221 | ActiveMenuBar->ActiveSelection, 0); 222 | else 223 | SendMessage(wnd, PAINT, 0, 0); 224 | break; 225 | default: 226 | break; 227 | } 228 | } 229 | 230 | /* --------------- LEFT_BUTTON Message ---------- */ 231 | static void LeftButtonMsg(WINDOW wnd, PARAM p1) 232 | { 233 | int i; 234 | int mx = (int) p1 - GetLeft(wnd); 235 | /* --- compute the selection that the left button hit --- */ 236 | for (i = 0; i < mctr; i++) 237 | if (mx >= menu[i].x1-4*i && 238 | mx <= menu[i].x2-4*i-5) 239 | break; 240 | if (i < mctr) 241 | if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL) 242 | SendMessage(wnd, MB_SELECTION, i, 0); 243 | } 244 | 245 | /* -------------- MB_SELECTION Message -------------- */ 246 | static void SelectionMsg(WINDOW wnd, PARAM p1, PARAM p2) 247 | { 248 | int wd, mx, my; 249 | MENU *mnu; 250 | 251 | if (!p2) { 252 | ActiveMenuBar->ActiveSelection = -1; 253 | SendMessage(wnd, PAINT, 0, 0); 254 | } 255 | Selecting = TRUE; 256 | mnu = ActiveMenu+(int)p1; 257 | if (mnu->PrepMenu != NULL) 258 | (*(mnu->PrepMenu))(GetDocFocus(), mnu); 259 | wd = MenuWidth(mnu->Selections); 260 | if (p2) { 261 | int brd = GetRight(wnd); 262 | mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1; 263 | if (mx + wd > brd) 264 | mx = brd - wd; 265 | my = GetTop(mwnd) + mwnd->selection; 266 | } 267 | else { 268 | int offset = menu[(int)p1].x1 - 4 * (int)p1; 269 | if (mwnd != NULL) 270 | SendMessage(mwnd, CLOSE_WINDOW, 0, 0); 271 | ActiveMenuBar->ActiveSelection = (int) p1; 272 | if (offset > WindowWidth(wnd)-wd) 273 | offset = WindowWidth(wnd)-wd; 274 | mx = GetLeft(wnd)+offset; 275 | my = GetTop(wnd)+1; 276 | } 277 | mwnd = CreateWindow(POPDOWNMENU, NULL, 278 | mx, my, 279 | MenuHeight(mnu->Selections), 280 | wd, 281 | NULL, 282 | wnd, 283 | NULL, 284 | SHADOW); 285 | if (!p2) { 286 | Selecting = FALSE; 287 | SendMessage(wnd, PAINT, 0, 0); 288 | Selecting = TRUE; 289 | } 290 | if (mnu->Selections[0].SelectionTitle != NULL) { 291 | SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0); 292 | SendMessage(mwnd, SETFOCUS, TRUE, 0); 293 | SendMessage(mwnd, SHOW_WINDOW, 0, 0); 294 | } 295 | Selecting = FALSE; 296 | } 297 | 298 | /* --------- COMMAND Message ---------- */ 299 | static void CommandMsg(WINDOW wnd, PARAM p1, PARAM p2) 300 | { 301 | if (p1 == ID_HELP) { 302 | BaseWndProc(MENUBAR, wnd, COMMAND, p1, p2); 303 | return; 304 | } 305 | if (isCascadedCommand(ActiveMenuBar, (int)p1)) { 306 | /* find the cascaded menu based on command id in p1 */ 307 | MENU *mnu = ActiveMenu+mctr; 308 | while (mnu->Title != (void *)-1) { 309 | if (mnu->CascadeId == (int) p1) { 310 | if (casc < MAXCASCADES) { 311 | Cascaders[casc++] = mwnd; 312 | SendMessage(wnd, MB_SELECTION, 313 | (PARAM)(mnu-ActiveMenu), TRUE); 314 | } 315 | break; 316 | } 317 | mnu++; 318 | } 319 | } 320 | else { 321 | if (mwnd != NULL) 322 | SendMessage(mwnd, CLOSE_WINDOW, 0, 0); 323 | SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0); 324 | PostMessage(GetParent(wnd), COMMAND, p1, p2); 325 | } 326 | } 327 | 328 | /* --------------- CLOSE_POPDOWN Message --------------- */ 329 | static void ClosePopdownMsg(WINDOW wnd) 330 | { 331 | if (casc > 0) 332 | SendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0); 333 | else { 334 | mwnd = NULL; 335 | ActiveMenuBar->ActiveSelection = -1; 336 | if (!Selecting) { 337 | SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0); 338 | SendMessage(wnd, PAINT, 0, 0); 339 | } 340 | } 341 | } 342 | 343 | /* ---------------- CLOSE_WINDOW Message --------------- */ 344 | static void CloseWindowMsg(WINDOW wnd) 345 | { 346 | if (GetText(wnd) != NULL) { 347 | free(GetText(wnd)); 348 | GetText(wnd) = NULL; 349 | } 350 | mctr = 0; 351 | ActiveMenuBar->ActiveSelection = -1; 352 | ActiveMenu = NULL; 353 | ActiveMenuBar = NULL; 354 | } 355 | 356 | /* --- Window processing module for MENUBAR window class --- */ 357 | int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 358 | { 359 | int rtn; 360 | 361 | switch (msg) { 362 | case CREATE_WINDOW: 363 | reset_menubar(wnd); 364 | break; 365 | case SETFOCUS: 366 | return SetFocusMsg(wnd, p1); 367 | case BUILDMENU: 368 | BuildMenuMsg(wnd, p1); 369 | break; 370 | case PAINT: 371 | if (!isVisible(wnd) || GetText(wnd) == NULL) 372 | break; 373 | PaintMsg(wnd); 374 | return FALSE; 375 | case BORDER: 376 | if (mwnd == NULL) 377 | SendMessage(wnd, PAINT, 0, 0); 378 | return TRUE; 379 | case KEYBOARD: 380 | KeyboardMsg(wnd, p1); 381 | return TRUE; 382 | case LEFT_BUTTON: 383 | LeftButtonMsg(wnd, p1); 384 | return TRUE; 385 | case MB_SELECTION: 386 | SelectionMsg(wnd, p1, p2); 387 | break; 388 | case COMMAND: 389 | CommandMsg(wnd, p1, p2); 390 | return TRUE; 391 | case INSIDE_WINDOW: 392 | return InsideRect(p1, p2, WindowRect(wnd)); 393 | case CLOSE_POPDOWN: 394 | ClosePopdownMsg(wnd); 395 | return TRUE; 396 | case CLOSE_WINDOW: 397 | rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2); 398 | CloseWindowMsg(wnd); 399 | return rtn; 400 | default: 401 | break; 402 | } 403 | return BaseWndProc(MENUBAR, wnd, msg, p1, p2); 404 | } 405 | 406 | /* ------------- reset the MENUBAR -------------- */ 407 | static void reset_menubar(WINDOW wnd) 408 | { 409 | GetText(wnd) = DFrealloc(GetText(wnd), SCREENWIDTH+5); 410 | memset(GetText(wnd), ' ', SCREENWIDTH); 411 | *(GetText(wnd)+WindowWidth(wnd)) = '\0'; 412 | } 413 | 414 | static WINDOW GetDocFocus(void) 415 | { 416 | WINDOW wnd = ApplicationWindow; 417 | if (wnd != NULL) { 418 | wnd = LastWindow(wnd); 419 | while (wnd != NULL && (GetClass(wnd) == MENUBAR || 420 | GetClass(wnd) == STATUSBAR)) 421 | wnd = PrevWindow(wnd); 422 | if (wnd != NULL) 423 | while (wnd->childfocus != NULL) 424 | wnd = wnd->childfocus; 425 | } 426 | return wnd ? wnd : ApplicationWindow; 427 | } 428 | 429 | -------------------------------------------------------------------------------- /source/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, "Commands for manipulating files" ) 9 | SELECTION( "~New", ID_NEW, CTRL_N, 0) /* 0.7a */ 10 | SELECTION( "~Open...", ID_OPEN, CTRL_O, 0) /* 0.7a */ 11 | SEPARATOR 12 | SELECTION( "~Save", ID_SAVE, CTRL_S, INACTIVE) /* 0.7a */ 13 | SELECTION( "Save ~as...", ID_SAVEAS, 0, INACTIVE) 14 | SELECTION( "~Close", ID_CLOSE, 0, INACTIVE) 15 | #if 0 16 | /* SELECTION( "D~elete", ID_DELETEFILE, 0, INACTIVE) */ 17 | #endif 18 | SEPARATOR 19 | SELECTION( "~Print", ID_PRINT, 0, INACTIVE) 20 | SELECTION( "P~rinter setup...", ID_PRINTSETUP, 0, 0) 21 | SEPARATOR 22 | SELECTION( "~DOS Shell", ID_DOS, 0, 0) 23 | SELECTION( "E~xit", ID_EXIT, ALT_X, 0) 24 | ENDPOPDOWN 25 | 26 | /* --------------- the Edit popdown menu ----------------*/ 27 | POPDOWN( "~Edit", PrepEditMenu, "Commands for editing files" ) 28 | #ifdef HOOKKEYB 29 | SELECTION( "~Undo", ID_UNDO, ALT_BS, INACTIVE) 30 | #else 31 | SELECTION( "~Undo", ID_UNDO, CTRL_Z, INACTIVE) 32 | #endif 33 | SEPARATOR 34 | SELECTION( "Cu~t", ID_CUT, CTRL_X, INACTIVE) 35 | SELECTION( "~Copy", ID_COPY, CTRL_C, INACTIVE) 36 | /* ^-- must handle ^C / ^Break as "ignore" to use this */ 37 | SELECTION( "~Paste", ID_PASTE, CTRL_V, INACTIVE) 38 | SEPARATOR 39 | SELECTION( "Cl~ear", ID_CLEAR, 0, INACTIVE) 40 | SELECTION( "~Delete", ID_DELETETEXT, DEL, INACTIVE) 41 | SEPARATOR 42 | SELECTION( "Pa~ragraph", ID_PARAGRAPH, ALT_P,INACTIVE) 43 | /* new 0.7d stuff follows: */ 44 | SELECTION( "Upc~ase Block", ID_UPCASE, 0, INACTIVE) 45 | SELECTION( "Do~wncase Block", ID_DOWNCASE, 0, INACTIVE) 46 | SELECTION( "Stats of ~Block", ID_WORDCOUNT, 0, 0) 47 | ENDPOPDOWN 48 | 49 | /* --------------- the Search popdown menu ----------------*/ 50 | POPDOWN( "~Search", PrepSearchMenu, "Search and replace text" ) 51 | SELECTION( "~Find", ID_SEARCH, CTRL_F, INACTIVE) 52 | /* *** CTRL_F added 0.7c, see also editbox.c *** */ 53 | SELECTION( "~Next", ID_SEARCHNEXT, F3, INACTIVE) 54 | SELECTION( "~Replace",ID_REPLACE, 0, INACTIVE) 55 | ENDPOPDOWN 56 | 57 | /* ------------ the Utilities popdown menu --------------- */ 58 | POPDOWN( "~Utilities", NULL, "Utility programs" ) 59 | #ifndef NOCALENDAR 60 | SELECTION( "~Calendar", ID_CALENDAR, 0, 0) 61 | #endif 62 | #if WITH_ASCIITAB 63 | SELECTION( "~ASCII Table", ID_ASCIITAB, 0, 0) /* new 0.7c */ 64 | #endif 65 | ENDPOPDOWN 66 | 67 | /* ------------- the Options popdown menu ---------------*/ 68 | POPDOWN( "~Options", NULL, "Commands for setting editor and display options" ) 69 | SELECTION( "~Display...", ID_DISPLAY, 0, 0 ) 70 | SEPARATOR 71 | #ifdef INCLUDE_LOGGING 72 | SELECTION( "~Log messages", ID_LOG, ALT_L, 0 ) 73 | SEPARATOR 74 | #endif 75 | SELECTION( "~Insert", ID_INSERT, INS, TOGGLE) 76 | SELECTION( "~Word wrap", ID_WRAP, 0, TOGGLE) 77 | SELECTION( "~Tabs ( )", ID_TABS, 0, CASCADED) 78 | SEPARATOR 79 | SELECTION( "~Save options", ID_SAVEOPTIONS, 0, 0 ) 80 | ENDPOPDOWN 81 | 82 | /* --------------- the Window popdown menu --------------*/ 83 | POPDOWN( "~Window", PrepWindowMenu, "Select/close document windows" ) 84 | SELECTION( NULL, ID_CLOSEALL, 0, 0) 85 | SEPARATOR 86 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 87 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 88 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 89 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 90 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 91 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 92 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 93 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 94 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 95 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 96 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 97 | SELECTION( "~More Windows...", ID_MOREWINDOWS, 0, 0) 98 | SELECTION( NULL, ID_WINDOW, 0, 0 ) 99 | ENDPOPDOWN 100 | 101 | /* --------------- the Help popdown menu ----------------*/ 102 | POPDOWN( "~Help", NULL, "Get help...really." ) 103 | SELECTION( "~Help for help...", ID_HELPHELP, 0, 0 ) 104 | SELECTION( "~Extended help...", ID_EXTHELP, 0, 0 ) 105 | SELECTION( "~Keys help...", ID_KEYSHELP, 0, 0 ) 106 | SELECTION( "Help ~index...", ID_HELPINDEX, 0, 0 ) 107 | SEPARATOR 108 | SELECTION( "~About...", ID_ABOUT, 0, 0 ) 109 | ENDPOPDOWN 110 | 111 | /* ----- cascaded pulldown from Tabs... above ----- */ 112 | CASCADED_POPDOWN( ID_TABS, NULL ) 113 | SELECTION( "raw tabs ~0", ID_TAB0, 0, 0) /* -ea */ 114 | SELECTION( "tab size ~2", ID_TAB2, 0, 0) 115 | SELECTION( "tab size ~4", ID_TAB4, 0, 0) 116 | SELECTION( "tab size ~6", ID_TAB6, 0, 0) 117 | SELECTION( "tab size ~8", ID_TAB8, 0, 0) 118 | ENDPOPDOWN 119 | 120 | ENDMENU 121 | 122 | /* ------------- the System Menu --------------------- */ 123 | DEFMENU(SystemMenu) 124 | POPDOWN("System Menu", NULL, NULL) 125 | #ifdef INCLUDE_RESTORE 126 | SELECTION("~Restore", ID_SYSRESTORE, 0, 0 ) 127 | #endif 128 | SELECTION("~Move", ID_SYSMOVE, 0, 0 ) 129 | SELECTION("~Size", ID_SYSSIZE, 0, 0 ) 130 | #ifdef INCLUDE_MINIMIZE 131 | SELECTION("Mi~nimize", ID_SYSMINIMIZE, 0, 0 ) 132 | #endif 133 | #ifdef INCLUDE_MAXIMIZE 134 | SELECTION("Ma~ximize", ID_SYSMAXIMIZE, 0, 0 ) 135 | #endif 136 | SEPARATOR 137 | SELECTION("~Close", ID_SYSCLOSE, CTRL_F4, 0 ) 138 | ENDPOPDOWN 139 | ENDMENU 140 | 141 | -------------------------------------------------------------------------------- /source/mouse.c: -------------------------------------------------------------------------------- 1 | /* ------------- mouse.c ------------- */ 2 | 3 | #include "dflat.h" 4 | 5 | static union REGS regs; 6 | static struct SREGS sregs; 7 | 8 | static void near mouse(int m1,int m2,int m3,int m4) 9 | { 10 | regs.x.dx = m4; 11 | regs.x.cx = m3; 12 | regs.x.bx = m2; 13 | regs.x.ax = m1; 14 | int86x(MOUSE, ®s, ®s, &sregs); 15 | } 16 | 17 | /* ---------- reset the mouse ---------- */ 18 | void resetmouse(void) 19 | { 20 | segread(&sregs); 21 | mouse(0,0,0,0); 22 | } 23 | 24 | /* ----- test to see if the mouse driver is installed ----- */ 25 | BOOL mouse_installed(void) 26 | { 27 | unsigned char far *ms; 28 | ms = MK_FP(peek(0, MOUSE*4+2), peek(0, MOUSE*4)); 29 | return (SCREENWIDTH <= 80 && ms != NULL && *ms != 0xcf); 30 | } 31 | 32 | /* ------ return true if mouse buttons are pressed ------- */ 33 | int mousebuttons(void) 34 | { 35 | if (mouse_installed()) { 36 | segread(&sregs); 37 | mouse(3,0,0,0); 38 | return regs.x.bx & 3; 39 | } 40 | return 0; 41 | } 42 | 43 | /* ---------- return mouse coordinates ---------- */ 44 | void get_mouseposition(int *x, int *y) 45 | { 46 | *x = *y = -1; 47 | if (mouse_installed()) { 48 | segread(&sregs); 49 | mouse(3,0,0,0); 50 | *x = regs.x.cx/8; 51 | *y = regs.x.dx/8; 52 | if (SCREENWIDTH == 40) 53 | *x /= 2; 54 | } 55 | } 56 | 57 | /* -------- position the mouse cursor -------- */ 58 | void set_mouseposition(int x, int y) 59 | { 60 | if (mouse_installed()) { 61 | segread(&sregs); 62 | if (SCREENWIDTH == 40) 63 | x *= 2; 64 | mouse(4,0,x*8,y*8); 65 | } 66 | } 67 | 68 | /* --------- display the mouse cursor -------- */ 69 | void show_mousecursor(void) 70 | { 71 | if (mouse_installed()) { 72 | segread(&sregs); 73 | mouse(1,0,0,0); 74 | } 75 | } 76 | 77 | /* --------- hide the mouse cursor ------- */ 78 | void hide_mousecursor(void) 79 | { 80 | if (mouse_installed()) { 81 | segread(&sregs); 82 | mouse(2,0,0,0); 83 | } 84 | } 85 | 86 | /* --- return true if a mouse button has been released --- */ 87 | int button_releases(void) 88 | { 89 | if (mouse_installed()) { 90 | segread(&sregs); 91 | mouse(6,0,0,0); 92 | return regs.x.bx; 93 | } 94 | return 0; 95 | } 96 | 97 | /* ----- set mouse travel limits ------- */ 98 | void set_mousetravel(int minx, int maxx, int miny, int maxy) 99 | { 100 | if (mouse_installed()) { 101 | if (SCREENWIDTH == 40) { 102 | minx *= 2; 103 | maxx *= 2; 104 | } 105 | segread(&sregs); 106 | mouse(7, 0, minx*8, maxx*8); 107 | mouse(8, 0, miny*8, maxy*8); 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/pictbox.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/edit/4ed5d50a4d2d516e857478ab437985d1e07b9eb3/source/pictbox.c -------------------------------------------------------------------------------- /source/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,sel[80]; 81 | struct PopDown *ActivePopDown,*pd1; 82 | 83 | ActivePopDown = pd1 = wnd->mnu->Selections; 84 | wd = MenuWidth(ActivePopDown)-2; 85 | while (wd--) 86 | *cp++ = LINE; 87 | 88 | *cp = '\0'; 89 | SendMessage(wnd, CLEARTEXT, 0, 0); 90 | wnd->selection = wnd->mnu->Selection; 91 | while (pd1->SelectionTitle != NULL) 92 | { 93 | if (*pd1->SelectionTitle == LINE) 94 | SendMessage(wnd, ADDTEXT, (PARAM) sep, 0); 95 | else 96 | { 97 | int len; 98 | 99 | memset(sel, '\0', sizeof sel); 100 | if (pd1->Attrib & INACTIVE) 101 | /* ------ inactive menu selection ----- */ 102 | sprintf(sel, "%c%c%c", CHANGECOLOR, wnd->WindowColors [HILITE_COLOR] [FG]|0x80, wnd->WindowColors [STD_COLOR] [BG]|0x80); 103 | 104 | strcat(sel, " "); 105 | if (pd1->Attrib & CHECKED) 106 | /* ---- paint the toggle checkmark ---- */ 107 | sel[strlen(sel)-1] = CHECKMARK; 108 | 109 | len=CopyCommand(sel+strlen(sel), pd1->SelectionTitle, pd1->Attrib & INACTIVE, wnd->WindowColors [STD_COLOR] [BG]); 110 | if (pd1->Accelerator) 111 | { 112 | /* ---- paint accelerator key ---- */ 113 | int i; 114 | int wd1=2+SelectionWidth(ActivePopDown)-strlen(pd1->SelectionTitle); 115 | int key=pd1->Accelerator; 116 | 117 | if (key > 0 && key < 27) 118 | { 119 | /* --- CTRL+ key --- */ 120 | while (wd1--) 121 | strcat(sel, " "); 122 | 123 | sprintf(sel+strlen(sel), "Ctrl+%c", key-1+'A'); 124 | } 125 | else /* accelerator keys with names defined in keys.c */ 126 | { 127 | for (i = 0; keys[i].keylabel; i++) 128 | { 129 | if (keys[i].keycode == key) 130 | { 131 | while (wd1--) 132 | strcat(sel, " "); 133 | 134 | sprintf(sel+strlen(sel), "%s", 135 | keys[i].keylabel); 136 | break; 137 | } 138 | 139 | } 140 | 141 | } 142 | 143 | } 144 | 145 | if (pd1->Attrib & CASCADED) 146 | { 147 | /* ---- paint cascaded menu token ---- */ 148 | if (!pd1->Accelerator) 149 | { 150 | wd = MenuWidth(ActivePopDown)-len+1; 151 | while (wd--) 152 | strcat(sel, " "); 153 | 154 | } 155 | 156 | sel[strlen(sel)-1] = CASCADEPOINTER; 157 | } 158 | else 159 | strcat(sel, " "); 160 | 161 | strcat(sel, " "); 162 | sel[strlen(sel)-1] = RESETCOLOR; 163 | SendMessage(wnd, ADDTEXT, (PARAM) sel, 0); 164 | } 165 | 166 | pd1++; 167 | } 168 | 169 | } 170 | 171 | /* ---------- BORDER Message ----------- */ 172 | static int BorderMsg(WINDOW wnd) 173 | { 174 | int i, rtn = TRUE; 175 | WINDOW currFocus; 176 | if (wnd->mnu != NULL) { 177 | currFocus = inFocus; 178 | inFocus = NULL; 179 | rtn = BaseWndProc(POPDOWNMENU, wnd, BORDER, 0, 0); 180 | inFocus = currFocus; 181 | for (i = 0; i < ClientHeight(wnd); i++) { 182 | if (*TextLine(wnd, i) == LINE) { 183 | wputch(wnd, LEDGE, 0, i+1); 184 | wputch(wnd, REDGE, WindowWidth(wnd)-1, i+1); 185 | } 186 | } 187 | } 188 | return rtn; 189 | } 190 | 191 | /* -------------- LB_CHOOSE Message -------------- */ 192 | /* did the user left-click one of the items in the current popdown? */ 193 | static void LBChooseMsg(WINDOW wnd, PARAM p1) 194 | { 195 | struct PopDown *ActivePopDown = wnd->mnu->Selections; 196 | if (ActivePopDown != NULL) { 197 | int *attr = &(ActivePopDown+(int)p1)->Attrib; 198 | wnd->mnu->Selection = (int)p1; 199 | if (!(*attr & INACTIVE)) { 200 | WINDOW pwnd = GetParent(wnd); 201 | if (*attr & TOGGLE) 202 | *attr ^= CHECKED; 203 | if (pwnd != NULL) { 204 | CurrentMenuSelection = (int)p1; 205 | /* PARAM is long, CurrentM..S... is int! */ 206 | PostMessage(pwnd, COMMAND, 207 | (ActivePopDown+(int)p1)->ActionId, 0); 208 | } 209 | } 210 | else 211 | beep(); 212 | } 213 | } 214 | 215 | /* ---------- KEYBOARD Message --------- */ 216 | /* did the user hit the highlighted key for an item in the current popdown? */ 217 | static BOOL KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2) 218 | { 219 | struct PopDown *ActivePopDown = wnd->mnu->Selections; 220 | if (wnd->mnu != NULL) { 221 | if (ActivePopDown != NULL) { 222 | int c = (int)p1; 223 | int sel = 0; 224 | int a; 225 | struct PopDown *pd = ActivePopDown; 226 | 227 | #ifdef HOOKKEYB 228 | if ((c & OFFSET) == 0) 229 | #else 230 | if ((c & FKEY) == 0) 231 | #endif 232 | c = tolower(c); 233 | a = AltConvert(c); 234 | 235 | while (pd->SelectionTitle != NULL) { 236 | char *cp = strchr(pd->SelectionTitle, 237 | SHORTCUTCHAR); 238 | int sc = tolower(*(cp+1)); 239 | if ((cp && sc == c) || 240 | (a && sc == a) || 241 | (pd->Accelerator == c)) 242 | { 243 | PostMessage(wnd, LB_SELECTION, sel, 0); 244 | PostMessage(wnd, LB_CHOOSE, sel, TRUE); 245 | return TRUE; 246 | } 247 | pd++, sel++; 248 | } 249 | } 250 | } 251 | switch ((int)p1) { 252 | case F1: /* (possibly context sensitive) help */ 253 | if (ActivePopDown == NULL) 254 | SendMessage(GetParent(wnd), KEYBOARD, p1, p2); 255 | else 256 | DisplayHelp(wnd, 257 | (ActivePopDown+wnd->selection)->help); 258 | return TRUE; 259 | case ESC: 260 | SendMessage(wnd, CLOSE_WINDOW, 0, 0); 261 | return TRUE; 262 | #ifdef HOOKKEYB 263 | case FWD: /* old name of right arrow */ 264 | #else 265 | case LARROW: /* hope this makes sense */ 266 | case RARROW: /* formerly called FWD */ 267 | #endif 268 | case BS: 269 | if (GetClass(GetParent(wnd)) == MENUBAR) 270 | PostMessage(GetParent(wnd), KEYBOARD, p1, p2); 271 | return TRUE; 272 | case UP: 273 | if (wnd->selection == 0) { 274 | if (wnd->wlines == ClientHeight(wnd)) { 275 | PostMessage(wnd, LB_SELECTION, 276 | wnd->wlines-1, FALSE); 277 | return TRUE; 278 | } 279 | } 280 | break; 281 | case DN: 282 | if (wnd->selection == wnd->wlines-1) { 283 | if (wnd->wlines == ClientHeight(wnd)) { 284 | PostMessage(wnd, LB_SELECTION, 0, FALSE); 285 | return TRUE; 286 | } 287 | } 288 | break; 289 | case HOME: 290 | case END: 291 | case '\r': 292 | break; 293 | default: 294 | return TRUE; 295 | } 296 | return FALSE; 297 | } 298 | 299 | /* ----------- CLOSE_WINDOW Message ---------- */ 300 | static int CloseWindowMsg(WINDOW wnd) 301 | { 302 | int rtn; 303 | WINDOW pwnd = GetParent(wnd); 304 | SendMessage(wnd, RELEASE_MOUSE, 0, 0); 305 | SendMessage(wnd, RELEASE_KEYBOARD, 0, 0); 306 | SendMessage(NULL, RESTORE_CURSOR, 0, 0); 307 | inFocus = wnd->oldFocus; 308 | rtn = BaseWndProc(POPDOWNMENU, wnd, CLOSE_WINDOW, 0, 0); 309 | SendMessage(pwnd, CLOSE_POPDOWN, 0, 0); 310 | return rtn; 311 | } 312 | 313 | /* - Window processing module for POPDOWNMENU window class - */ 314 | int PopDownProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) 315 | { 316 | switch (msg) { 317 | case CREATE_WINDOW: 318 | return CreateWindowMsg(wnd); 319 | case LEFT_BUTTON: 320 | LeftButtonMsg(wnd, p1, p2); 321 | return FALSE; 322 | case DOUBLE_CLICK: 323 | return TRUE; 324 | case LB_SELECTION: 325 | if (*TextLine(wnd, (int)p1) == LINE) 326 | return TRUE; 327 | wnd->mnu->Selection = (int)p1; 328 | break; 329 | case BUTTON_RELEASED: 330 | if (ButtonReleasedMsg(wnd, p1, p2)) 331 | return TRUE; 332 | break; 333 | case BUILD_SELECTIONS: 334 | wnd->mnu = (void *) p1; 335 | wnd->selection = wnd->mnu->Selection; 336 | break; 337 | case PAINT: 338 | if (wnd->mnu == NULL) 339 | return TRUE; 340 | PaintMsg(wnd); 341 | break; 342 | case BORDER: 343 | return BorderMsg(wnd); 344 | case LB_CHOOSE: 345 | LBChooseMsg(wnd, p1); 346 | return TRUE; 347 | case KEYBOARD: 348 | if (KeyboardMsg(wnd, p1, p2)) 349 | return TRUE; 350 | break; 351 | case CLOSE_WINDOW: 352 | return CloseWindowMsg(wnd); 353 | default: 354 | break; 355 | } 356 | return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2); 357 | } 358 | 359 | /* --------- compute menu height -------- */ 360 | int MenuHeight(struct PopDown *pd) 361 | { 362 | int ht = 0; 363 | while (pd[ht].SelectionTitle != NULL) 364 | ht++; 365 | return ht+2; 366 | } 367 | 368 | /* --------- compute menu width -------- */ 369 | int MenuWidth(struct PopDown *pd) 370 | { 371 | int wd = 0, i; 372 | int len = 0; 373 | 374 | wd = SelectionWidth(pd); 375 | while (pd->SelectionTitle != NULL) { 376 | if (pd->Accelerator) { 377 | for (i = 0; keys[i].keylabel; i++) 378 | if (keys[i].keycode == pd->Accelerator) { 379 | len = max(len, 2+strlen(keys[i].keylabel)); 380 | break; 381 | } 382 | } 383 | if (pd->Attrib & CASCADED) 384 | len = max(len, 2); 385 | pd++; 386 | } 387 | return wd+5+len; 388 | } 389 | 390 | /* ---- compute the maximum selection width in a menu ---- */ 391 | static int SelectionWidth(struct PopDown *pd) 392 | { 393 | int wd = 0; 394 | while (pd->SelectionTitle != NULL) { 395 | int len = strlen(pd->SelectionTitle)-1; 396 | wd = max(wd, len); 397 | pd++; 398 | } 399 | return wd; 400 | } 401 | 402 | /* ----- copy a menu command to a display buffer ---- */ 403 | int CopyCommand(unsigned char *dest, unsigned char *src, 404 | int skipcolor, int bg) 405 | { 406 | unsigned char *d = dest; 407 | while (*src && *src != '\n') { 408 | if (*src == SHORTCUTCHAR) { 409 | src++; 410 | if (!skipcolor) { 411 | *dest++ = CHANGECOLOR; 412 | *dest++ = cfg.clr[POPDOWNMENU] 413 | [HILITE_COLOR] [BG] | 0x80; 414 | *dest++ = bg | 0x80; 415 | *dest++ = *src++; 416 | *dest++ = RESETCOLOR; 417 | } 418 | } 419 | else 420 | *dest++ = *src++; 421 | } 422 | return (int) (dest - d); 423 | } 424 | 425 | -------------------------------------------------------------------------------- /source/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 | 114 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/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 | /* even for "find again" (not replacing) this runs at least once */ 59 | rpl = Replacing ? 60 | CheckBoxSetting(&ReplaceTextDB, ID_REPLACEALL) : 61 | FALSE; 62 | if (TextBlockMarked(wnd)) { 63 | ClearTextBlock(wnd); /* un-mark block */ 64 | SendMessage(wnd, PAINT, 0, 0); 65 | } 66 | /* search for a match starting at cursor position */ 67 | cp1 = CurrChar; 68 | if (incr) 69 | cp1 += lastsize; /* start past the last hit */ 70 | /* --- compare at each character position --- */ 71 | while (*cp1) { 72 | s1 = cp; 73 | s2 = cp1; 74 | while (*s1 && *s1 != '\n') { 75 | if (SearchCmp(*s1, *s2)) 76 | break; 77 | s1++, s2++; 78 | } 79 | if (*s1 == '\0' || *s1 == '\n') 80 | break; 81 | cp1++; 82 | } 83 | if (s1 != NULL && (*s1 == 0 || *s1 == '\n')) { 84 | /* ----- match at *cp1 ------- */ 85 | FoundOne = TRUE; 86 | 87 | /* mark a block at beginning of matching text */ 88 | wnd->BlkEndLine = TextLineNumber(wnd, s2); 89 | wnd->BlkBegLine = TextLineNumber(wnd, cp1); 90 | if (wnd->BlkEndLine < wnd->BlkBegLine) 91 | wnd->BlkEndLine = wnd->BlkBegLine; 92 | wnd->BlkEndCol = 93 | (int)(s2 - TextLine(wnd, wnd->BlkEndLine)); 94 | wnd->BlkBegCol = 95 | (int)(cp1 - TextLine(wnd, wnd->BlkBegLine)); 96 | 97 | /* position the cursor at the matching text */ 98 | wnd->CurrCol = wnd->BlkBegCol; 99 | wnd->CurrLine = wnd->BlkBegLine; 100 | wnd->WndRow = wnd->CurrLine - wnd->wtop; 101 | 102 | /* -- remember the size of the matching text -- */ 103 | lastsize = strlen(cp); 104 | 105 | /* align the window scroll to matching text */ 106 | if (WndCol > ClientWidth(wnd)-1) 107 | wnd->wleft = wnd->CurrCol; 108 | if (wnd->WndRow > ClientHeight(wnd)-1) { 109 | wnd->wtop = wnd->CurrLine; 110 | wnd->WndRow = 0; 111 | } 112 | 113 | SendMessage(wnd, PAINT, 0, 0); 114 | SendMessage(wnd, KEYBOARD_CURSOR, 115 | WndCol, wnd->WndRow); 116 | 117 | if (Replacing) { 118 | if (rpl || YesNoBox("Replace the text?")) { 119 | replacetext(wnd, cp1, db); 120 | wnd->TextChanged = TRUE; 121 | BuildTextPointers(wnd); 122 | if (rpl) { 123 | incr = TRUE; 124 | continue; 125 | } 126 | } 127 | ClearTextBlock(wnd); 128 | SendMessage(wnd, PAINT, 0, 0); 129 | } 130 | return; 131 | } 132 | break; 133 | } 134 | if (!FoundOne) 135 | MessageBox("Edit", "Edit was unable to find a match"); 136 | } 137 | 138 | /* ------- search for the occurrance of a string, 139 | replace it with a specified string ------- */ 140 | void ReplaceText(WINDOW wnd) 141 | { 142 | Replacing = TRUE; 143 | lastsize = 0; 144 | if (CheckCase) 145 | SetCheckBox(&ReplaceTextDB, ID_MATCHCASE); 146 | if (DialogBox(NULL, &ReplaceTextDB, TRUE, NULL)) { 147 | CheckCase=CheckBoxSetting(&ReplaceTextDB,ID_MATCHCASE); 148 | SearchTextBox(wnd, FALSE); 149 | } 150 | } 151 | 152 | /* ------- search for the first occurrance of a string ------ */ 153 | void SearchText(WINDOW wnd) 154 | { 155 | Replacing = FALSE; 156 | lastsize = 0; 157 | if (CheckCase) 158 | SetCheckBox(&SearchTextDB, ID_MATCHCASE); 159 | if (DialogBox(NULL, &SearchTextDB, TRUE, NULL)) { 160 | CheckCase=CheckBoxSetting(&SearchTextDB,ID_MATCHCASE); 161 | SearchTextBox(wnd, FALSE); 162 | } 163 | } 164 | 165 | /* ------- search for the next occurrance of a string ------- */ 166 | void SearchNext(WINDOW wnd) 167 | { 168 | SearchTextBox(wnd, TRUE); 169 | } 170 | 171 | -------------------------------------------------------------------------------- /source/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 | 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 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/statbar.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/edit/4ed5d50a4d2d516e857478ab437985d1e07b9eb3/source/statbar.c -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/system.h: -------------------------------------------------------------------------------- 1 | /* --------------- system.h -------------- */ 2 | #ifndef SYSTEM_H 3 | #define SYSTEM_H 4 | 5 | #if MSC | WATCOM 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | #define swap(a,b){int x=a;a=b;b=x;} 12 | /* ----- interrupt vectors ----- */ 13 | #define TIMER 8 14 | #define VIDEO 0x10 15 | #define KEYBRD 0x16 16 | #define DOS 0x21 17 | #define CRIT 0x24 18 | #define MOUSE 0x33 19 | #define KEYBOARDVECT 9 20 | /* ------- platform-dependent values ------ */ 21 | #define KEYBOARDPORT 0x60 22 | #define FREQUENCY 100 23 | #define COUNT (1193280L / FREQUENCY) 24 | #define ZEROFLAG 0x40 25 | #define MAXSAVES 50 26 | #define SCREENWIDTH (peekb(0x40,0x4a) & 255) 27 | #define SCREENHEIGHT (isVGA() || isEGA() ? peekb(0x40,0x84)+1 : 25) 28 | #define clearBIOSbuffer() *(int far *)(MK_FP(0x40,0x1a)) = \ 29 | *(int far *)(MK_FP(0x40,0x1c)); 30 | 31 | #ifdef HOOKKEYB 32 | /* if irq 9 hooked, waitforkeyboard clears buffer until key released */ 33 | /* (used to wait for a key but also to zap special keys from buffer) */ 34 | #define waitforkeyboard() while ((keyportvalue & 0x80) == 0) \ 35 | clearBIOSbuffer() 36 | #else 37 | /* if irq 9 not hooked, waitforkeyboard only drains buffer */ 38 | /* (used for "press a key to continue" cases only) */ 39 | #define waitforkeyboard() while (Xbioskey(1)) (void)Xbioskey(0) 40 | #endif 41 | 42 | /* ----- keyboard BIOS (0x16) functions -------- */ 43 | #define READKB 0 44 | #define KBSTAT 1 45 | /* ------- video BIOS (0x10) functions --------- */ 46 | #define SETCURSORTYPE 1 47 | #define SETCURSOR 2 48 | #define READCURSOR 3 49 | #define READATTRCHAR 8 50 | #define WRITEATTRCHAR 9 51 | #define HIDECURSOR 0x20 52 | /* ------- the interrupt function registers -------- */ 53 | typedef struct { 54 | int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,fl; 55 | } IREGS; 56 | /* ---------- keyboard prototypes -------- */ 57 | int AltConvert(int); 58 | int Xbioskey(int); /* enhanced for 102 key keyboard support */ 59 | int getkey(void); 60 | int getshift(void); 61 | BOOL keyhit(void); 62 | void beep(void); 63 | /* ---------- cursor prototypes -------- */ 64 | void curr_cursor(int *x, int *y); 65 | void cursor(int x, int y); 66 | void hidecursor(void); 67 | void unhidecursor(void); 68 | void savecursor(void); 69 | void restorecursor(void); 70 | void normalcursor(void); 71 | void set_cursor_type(unsigned t); 72 | void videomode(void); 73 | void SwapCursorStack(void); 74 | /* --------- screen prototpyes -------- */ 75 | void clearscreen(void); 76 | /* ---------- mouse prototypes ---------- */ 77 | BOOL mouse_installed(void); 78 | int mousebuttons(void); 79 | void get_mouseposition(int *x, int *y); 80 | void set_mouseposition(int x, int y); 81 | void show_mousecursor(void); 82 | void hide_mousecursor(void); 83 | int button_releases(void); 84 | void resetmouse(void); 85 | void set_mousetravel(int, int, int, int); 86 | #define leftbutton() (mousebuttons()&1) 87 | #define rightbutton() (mousebuttons()&2) 88 | #define waitformouse() while(mousebuttons()); 89 | /* ------------ timer macros -------------- */ 90 | #ifdef HOOKTIMER /* if timer IRQ handler in use - classic style */ 91 | #define timed_out(timer) (timer==0) 92 | #define set_timer(timer, secs) timer=(secs)*182/10+1 93 | #define set_timer_ticks(timer, ticks) timer=(ticks) 94 | #define disable_timer(timer) timer = -1 95 | #define timer_running(timer) (timer > 0) 96 | #define countdown(timer) --timer 97 | #define timer_disabled(timer) (timer == -1) 98 | #else /* else use functions in message.c (by ea) */ 99 | /* functions only use constants in timer variables */ 100 | /* to identify which timer is used! So take care: */ 101 | /* Never manipulate timer variables directly! -ea */ 102 | int timed_out(int timer); 103 | void set_timer(int timer, int secs); 104 | void set_timer_ticks(int timer, int ticks); 105 | void disable_timer(int timer); 106 | int timer_running(int timer); 107 | /* void countdown(int timer); -- only used in IRQ handler anyway -- */ 108 | int timer_disabled(int timer); 109 | #endif 110 | 111 | /* ----------- video adaptor prototypes ----------- */ 112 | BOOL isEGA(void); 113 | BOOL isVGA(void); 114 | void Set25(void); 115 | void Set43(void); 116 | void Set50(void); 117 | 118 | /* #ifndef TURBOC */ 119 | #ifndef BLACK 120 | /* ============= Color Macros ============ */ 121 | #define BLACK 0 122 | #define BLUE 1 123 | #define GREEN 2 124 | #define CYAN 3 125 | #define RED 4 126 | #define MAGENTA 5 127 | #define BROWN 6 128 | #define LIGHTGRAY 7 129 | #define DARKGRAY 8 130 | #define LIGHTBLUE 9 131 | #define LIGHTGREEN 10 132 | #define LIGHTCYAN 11 133 | #define LIGHTRED 12 134 | #define LIGHTMAGENTA 13 135 | #define YELLOW 14 136 | #define WHITE 15 137 | #endif /* 138 | /* #endif */ 139 | 140 | #if MSC | WATCOM 141 | /* ============= Compatibility Macros ============ */ 142 | #define asm __asm 143 | #undef FP_OFF 144 | #undef FP_SEG 145 | #undef MK_FP 146 | #define FP_OFF(p) ((unsigned)(p)) 147 | #define FP_SEG(p) ((unsigned)((unsigned long)(p) >> 16)) 148 | #define MK_FP(s,o) ((void far *) \ 149 | (((unsigned long)(s) << 16) | (unsigned)(o))) 150 | #define findfirst(p,f,a) _dos_findfirst(p,a,f) 151 | #define findnext(f) _dos_findnext(f) 152 | #define ffblk find_t 153 | #define ff_name name 154 | #define ff_fsize size 155 | #define ff_attrib attrib 156 | #define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c)) 157 | #define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c)) 158 | #define peek(a,b) (*((int far*)MK_FP((a),(b)))) 159 | #define peekb(a,b) (*((char far*)MK_FP((a),(b)))) 160 | #define getvect(v) _dos_getvect(v) 161 | #define setvect(v,f) _dos_setvect(v,f) 162 | #define fnsplit _splitpath 163 | #define fnmerge _makepath 164 | #define EXTENSION 2 165 | #define FILENAME 4 166 | #define DIRECTORY 8 167 | #define DRIVE 16 168 | int getdisk(void); 169 | #define setdisk(d) _dos_setdrive((d)+1, NULL) 170 | #define bioskey _bios_keybrd 171 | #define MAXPATH 80 172 | #define MAXDRIVE 3 173 | #define MAXDIR 66 174 | #define MAXFILE 9 175 | #define MAXEXT 5 176 | #endif 177 | 178 | typedef enum messages { 179 | #ifdef WATCOM 180 | WATCOMFIX1 = -1, 181 | #endif 182 | #undef DFlatMsg 183 | #define DFlatMsg(m) m, 184 | #include "dflatmsg.h" 185 | MESSAGECOUNT 186 | } MESSAGE; 187 | 188 | typedef enum window_class { 189 | #ifdef WATCOM 190 | WATCOMFIX2 = -1, 191 | #endif 192 | #define ClassDef(c,b,p,a) c, 193 | #include "classes.h" 194 | CLASSCOUNT 195 | } CLASS; 196 | 197 | #endif 198 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/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 int near vpeek(int far *vp); 10 | static void near vpoke(int far *vp, int 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 | 136 | if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT && isVisible(wnd)) 137 | { 138 | int ln[200]; 139 | int *cp1=ln; 140 | int fg=foreground; 141 | int bg=background; 142 | int len; 143 | int off=0; 144 | unsigned char *str=s; 145 | 146 | while (*str) 147 | { 148 | if (*str == CHANGECOLOR) 149 | { 150 | int fgcode, bgcode; /* new 0.7c: sanity checks */ 151 | str++; 152 | fgcode = (*str++); 153 | bgcode = (*str++); 154 | if ((fgcode & 0x80) && (bgcode & 0x80) && 155 | !(fgcode & 0x70) && !(bgcode & 0x70)) { 156 | foreground = fgcode & 0x7f; 157 | background = bgcode & 0x7f; 158 | continue; 159 | } else { /* this also makes CHANGECOLOR almost normal */ 160 | str--; /* and useable as character in your texts... */ 161 | str--; /* treat as non-escape sequence */ 162 | str--; 163 | } 164 | } 165 | 166 | if (*str == RESETCOLOR) 167 | { 168 | foreground = fg & 0x7f; 169 | background = bg & 0x7f; 170 | str++; 171 | continue; 172 | } 173 | 174 | #ifdef TAB_TOGGLING /* made consistent with editor.c - 0.7c */ 175 | if (*str == ('\t' | 0x80) || *str == ('\f' | 0x80)) 176 | *cp1 = ' ' | (clr(foreground, background) << 8); 177 | else 178 | #endif 179 | *cp1 = (*str & 255) | (clr(foreground, background) << 8); 180 | 181 | if (ClipString) 182 | if (!CharInView(wnd, x, y)) 183 | *cp1 = peek(video_address, vad(x2,y1)); 184 | 185 | cp1++; 186 | str++; 187 | x++; 188 | x2++; 189 | } 190 | 191 | foreground = fg; 192 | background = bg; 193 | len = (int)(cp1-ln); 194 | if (x1+len > SCREENWIDTH) 195 | len = SCREENWIDTH-x1; 196 | 197 | if (!ClipString && !TestAttribute(wnd, NOCLIP)) 198 | { 199 | /* -- clip the line to within ancestor windows -- */ 200 | RECT rc = WindowRect(wnd); 201 | WINDOW nwnd = GetParent(wnd); 202 | 203 | while (len > 0 && nwnd != NULL) 204 | { 205 | if (!isVisible(nwnd)) 206 | { 207 | len = 0; 208 | break; 209 | } 210 | 211 | rc = subRectangle(rc, ClientRect(nwnd)); 212 | nwnd = GetParent(nwnd); 213 | } 214 | 215 | while (len > 0 && !InsideRect(x1+off,y1,rc)) 216 | { 217 | off++; 218 | --len; 219 | } 220 | 221 | if (len > 0) 222 | { 223 | x2 = x1+len-1; 224 | while (len && !InsideRect(x2,y1,rc)) 225 | { 226 | --x2; 227 | --len; 228 | } 229 | 230 | } 231 | 232 | } 233 | 234 | if (len > 0) 235 | { 236 | hide_mousecursor(); 237 | movetoscreen(ln+off, vad(x1+off,y1), len*2); 238 | show_mousecursor(); 239 | } 240 | 241 | } 242 | } 243 | 244 | /* --------- get the current video mode -------- */ 245 | void get_videomode(void) 246 | { 247 | videomode(); 248 | 249 | /* ---- Monochrome Display Adaptor or text mode ---- */ 250 | snowy = FALSE; 251 | if (ismono()) 252 | video_address = 0xb000; 253 | else 254 | { 255 | /* ------ Text mode -------- */ 256 | video_address = 0xb800 + video_page; 257 | if (!isEGA() && !isVGA()) 258 | /* -------- CGA --------- */ 259 | snowy = cfg.snowy; 260 | 261 | } 262 | 263 | } 264 | 265 | /* --------- scroll the window. d: 1 = up, 0 = dn ---------- */ 266 | void scroll_window(WINDOW wnd, RECT rc, int d) 267 | { 268 | if (RectTop(rc) != RectBottom(rc)) { 269 | union REGS regs; 270 | regs.h.cl = RectLeft(rc); 271 | regs.h.ch = RectTop(rc); 272 | regs.h.dl = RectRight(rc); 273 | regs.h.dh = RectBottom(rc); 274 | regs.h.bh = clr(WndForeground(wnd),WndBackground(wnd)); 275 | regs.h.ah = 7 - d; 276 | regs.h.al = 1; 277 | hide_mousecursor(); 278 | int86(VIDEO, ®s, ®s); 279 | show_mousecursor(); 280 | } 281 | } 282 | 283 | 284 | /* Waits for the beginning of a vertical ("big") retrace, to 285 | * avoid flicker. Old version of this was in Assembly language. 286 | */ 287 | static void near waitforretrace(void) 288 | { 289 | /* disable interrupts */ 290 | disable(); 291 | 292 | /* next 2 lines are to catch a FULL vretrace */ 293 | if (inp(0x3da) & 8) /* if inside vertical retrace */ 294 | while ( inp(0x3da) & 8 ); /* wait until retrace ends */ 295 | 296 | while (!( inp(0x3da) & 8 )); /* wait for vretrace to START */ 297 | while (!( inp(0x3da) & 0x01 )); /* wait for 1st hretrace in it */ 298 | 299 | /* re-enable interrupts */ 300 | enable(); 301 | } 302 | 303 | void movetoscreen(void *bf, int offset, int len) 304 | { 305 | if (snowy) 306 | waitforretrace(); 307 | movedata(FP_SEG(bf), FP_OFF(bf), video_address, offset, len); 308 | } 309 | 310 | void movefromscreen(void *bf, int offset, int len) 311 | { 312 | if (snowy) 313 | waitforretrace(); 314 | movedata(video_address, offset, FP_SEG(bf), FP_OFF(bf), len); 315 | } 316 | 317 | 318 | static int near vpeek(int far *vp) 319 | { 320 | int c; 321 | if (snowy) /* added 0.7c */ 322 | waitforretrace(); 323 | c = *vp; 324 | return c; 325 | } 326 | 327 | static void near vpoke(int far *vp, int c) 328 | { 329 | if (snowy) /* added 0.7c */ 330 | waitforretrace(); 331 | *vp = c; 332 | } 333 | 334 | -------------------------------------------------------------------------------- /source/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 | -------------------------------------------------------------------------------- /source/watch.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/edit/4ed5d50a4d2d516e857478ab437985d1e07b9eb3/source/watch.c --------------------------------------------------------------------------------