[BACK]Return to wtext.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / win

Annotation of OpenXM_contrib/gnuplot/win/wtext.c, Revision 1.1.1.2

1.1       maekawa     1: #ifndef lint
1.1.1.2 ! maekawa     2: static char *RCSid = "$Id: wtext.c,v 1.3.2.1 1999/09/21 18:48:28 lhecking Exp $";
1.1       maekawa     3: #endif
                      4:
                      5: /* GNUPLOT - win/wtext.c */
1.1.1.2 ! maekawa     6:
1.1       maekawa     7: /*[
                      8:  * Copyright 1992, 1993, 1998   Russell Lang
                      9:  *
                     10:  * Permission to use, copy, and distribute this software and its
                     11:  * documentation for any purpose with or without fee is hereby granted,
                     12:  * provided that the above copyright notice appear in all copies and
                     13:  * that both that copyright notice and this permission notice appear
                     14:  * in supporting documentation.
                     15:  *
                     16:  * Permission to modify the software is granted, but not the right to
                     17:  * distribute the complete modified source code.  Modifications are to
                     18:  * be distributed as patches to the released version.  Permission to
                     19:  * distribute binaries produced by compiling modified sources is granted,
                     20:  * provided you
                     21:  *   1. distribute the corresponding source modifications from the
                     22:  *    released version in the form of a patch file along with the binaries,
                     23:  *   2. add special version identification to distinguish your version
                     24:  *    in addition to the base release version number,
                     25:  *   3. provide your name and address as the primary contact for the
                     26:  *    support of your modified version, and
                     27:  *   4. retain our contact information in regard to use of the base
                     28:  *    software.
                     29:  * Permission to distribute the released version of the source code along
                     30:  * with corresponding source modifications in the form of a patch file is
                     31:  * granted with same provisions 2 through 4 for binary distributions.
                     32:  *
                     33:  * This software is provided "as is" without express or implied warranty
                     34:  * to the extent permitted by applicable law.
                     35: ]*/
                     36:
                     37: /*
                     38:  * AUTHORS
                     39:  *
                     40:  *   Russell Lang
                     41:  *
                     42:  * Send your comments or suggestions to
                     43:  *  info-gnuplot@dartmouth.edu.
                     44:  * This is a mailing list; to join it send a note to
                     45:  *  majordomo@dartmouth.edu.
                     46:  * Send bug reports to
                     47:  *  bug-gnuplot@dartmouth.edu.
                     48:  */
                     49:
                     50: /* WARNING: Do not write to stdout/stderr with functions not listed
                     51:    in win/wtext.h */
                     52:
                     53: #define STRICT
                     54:
                     55: #include <string.h>    /* use only far items */
                     56: #include <stdlib.h>
                     57: #include <ctype.h>
                     58: #include <dos.h>
                     59: #ifndef __MSC__
                     60: # include <mem.h>
                     61: #endif
                     62:
                     63: #include <windows.h>
                     64: #include <windowsx.h>
                     65: #if WINVER >= 0x030a
                     66: # include <commdlg.h>
                     67: #endif
                     68:
                     69: #include "wgnuplib.h"
                     70: #include "wresourc.h"
                     71: #include "wcommon.h"
                     72:
                     73: /* font stuff */
                     74: #define TEXTFONTSIZE 9
                     75: #define TEXTFONTNAME "Terminal"
                     76:
                     77: #ifndef EOF /* HBB 980809: for MinGW32 */
                     78: #define EOF -1         /* instead of using <stdio.h> */
                     79: #endif
                     80: /* limits */
                     81: #define MAXSTR 256
                     82: POINT ScreenMinSize = {16,4};
                     83:
                     84: LRESULT CALLBACK WINEXPORT WndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
                     85: LRESULT CALLBACK WINEXPORT WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
                     86:
                     87: void ReadTextIni(LPTW lptw);
                     88: void LimitMark(LPTW lptw, POINT FAR *lppt);
                     89:
                     90: char szNoMemory[] = "out of memory";
                     91: COLORREF TextColorTable[16] = {
                     92:        RGB(0,0,0),                     /* black */
                     93:        RGB(0,0,128),           /* dark blue */
                     94:        RGB(0,128,0),           /* dark green */
                     95:        RGB(0,128,128),         /* dark cyan */
                     96:        RGB(128,0,0),           /* dark red */
                     97:        RGB(128,0,128),         /* dark magenta */
                     98:        RGB(128,128,0),         /* dark yellow */
                     99:        RGB(128,128,128),       /* dark grey */
                    100:        RGB(192,192,192),       /* light grey */
                    101:        RGB(0,0,255),           /* blue */
                    102:        RGB(0,255,0),           /* green */
                    103:        RGB(0,255,255),         /* cyan */
                    104:        RGB(255,0,0),           /* red */
                    105:        RGB(255,0,255),         /* magenta */
                    106:        RGB(255,255,0),         /* yellow */
                    107:        RGB(255,255,255),       /* white */
                    108: };
                    109: #define NOTEXT 0xF0
                    110: #define MARKFORE RGB(255,255,255)
                    111: #define MARKBACK RGB(0,0,128)
                    112: #define TextFore(attr) TextColorTable[(attr) & 15]
                    113: #define TextBack(attr) TextColorTable[(attr>>4) & 15]
                    114:
                    115:
                    116: void WDPROC
                    117: TextMessage(void)
                    118: {
                    119:     MSG msg;
                    120:
                    121:     while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
                    122:         {
1.1.1.2 ! maekawa   123: #if 1 /* HBB 19990505: Petzold says we should check this: */
        !           124:         if (msg.message == WM_QUIT)
        !           125:             return;
        !           126: #endif
1.1       maekawa   127:         TranslateMessage(&msg);
                    128:         DispatchMessage(&msg);
                    129:         }
                    130:     return;
                    131: }
                    132:
                    133:
                    134:
                    135: void
                    136: CreateTextClass(LPTW lptw)
                    137: {
                    138: WNDCLASS wndclass;
                    139: #ifdef WIN32
                    140: hdllInstance = lptw->hInstance;        /* not using a DLL */
                    141: #endif
                    142:        wndclass.style = CS_HREDRAW | CS_VREDRAW;
                    143:        wndclass.lpfnWndProc = WndTextProc;
                    144:        wndclass.cbClsExtra = 0;
                    145:        wndclass.cbWndExtra = 2 * sizeof(void FAR *);
                    146:        wndclass.hInstance = lptw->hInstance;
                    147:        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
                    148:        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
                    149:        wndclass.hbrBackground = NULL;
                    150:        lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ?
                    151:                GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
                    152:        wndclass.lpszMenuName = NULL;
                    153:        wndclass.lpszClassName = szTextClass;
                    154:        RegisterClass(&wndclass);
                    155:
                    156:        wndclass.style = CS_HREDRAW | CS_VREDRAW;
                    157:        wndclass.lpfnWndProc = WndParentProc;
                    158:        wndclass.cbClsExtra = 0;
                    159:        wndclass.cbWndExtra = 2 * sizeof(void FAR *);
                    160:        wndclass.hInstance = lptw->hInstance;
                    161:        if (lptw->hIcon)
                    162:                wndclass.hIcon = lptw->hIcon;
                    163:        else
                    164:                wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
                    165:        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
                    166:        wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
                    167:        wndclass.lpszMenuName = NULL;
                    168:        wndclass.lpszClassName = szParentClass;
                    169:        RegisterClass(&wndclass);
                    170: }
                    171:
                    172:
                    173: /* make text window */
                    174: int WDPROC
                    175: TextInit(LPTW lptw)
                    176: {
                    177:        RECT rect;
                    178:        HMENU sysmenu;
                    179:        HGLOBAL hglobal;
                    180:        char buf[80];
                    181:
                    182:        ReadTextIni(lptw);
                    183:
                    184:        if (!lptw->hPrevInstance)
                    185:                CreateTextClass(lptw);
                    186:
                    187:        if (lptw->KeyBufSize == 0)
                    188:                lptw->KeyBufSize = 256;
                    189:
                    190:        if (lptw->ScreenSize.x < ScreenMinSize.x)
                    191:                lptw->ScreenSize.x = ScreenMinSize.x;
                    192:        if (lptw->ScreenSize.y < ScreenMinSize.y)
                    193:                lptw->ScreenSize.y = ScreenMinSize.y;
                    194:
                    195:        lptw->CursorPos.x = lptw->CursorPos.y = 0;
                    196:        lptw->bFocus = FALSE;
                    197:        lptw->bGetCh = FALSE;
                    198:        lptw->CaretHeight = 0;
                    199:        if (!lptw->nCmdShow)
                    200:                lptw->nCmdShow = SW_SHOWNORMAL;
                    201:        if (!lptw->Attr)
                    202:                lptw->Attr = 0xf0;      /* black on white */
                    203:
                    204:        hglobal = GlobalAlloc(GHND, lptw->ScreenSize.x * lptw->ScreenSize.y);
                    205:        lptw->ScreenBuffer = (BYTE FAR *)GlobalLock(hglobal);
                    206:        if (lptw->ScreenBuffer == (BYTE FAR *)NULL) {
                    207:                MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
                    208:                return(1);
                    209:        }
                    210:        _fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x * lptw->ScreenSize.y);
                    211:        hglobal = GlobalAlloc(GHND, lptw->ScreenSize.x * lptw->ScreenSize.y);
                    212:        lptw->AttrBuffer = (BYTE FAR *)GlobalLock(hglobal);
                    213:        if (lptw->AttrBuffer == (BYTE FAR *)NULL) {
                    214:                MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
                    215:                return(1);
                    216:        }
                    217:        _fmemset(lptw->AttrBuffer, NOTEXT, lptw->ScreenSize.x * lptw->ScreenSize.y);
                    218:        hglobal = GlobalAlloc(LHND, lptw->KeyBufSize);
                    219:        lptw->KeyBuf = (BYTE FAR *)GlobalLock(hglobal);
                    220:        if (lptw->KeyBuf == (BYTE FAR *)NULL) {
                    221:                MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
                    222:                return(1);
                    223:        }
                    224:        lptw->KeyBufIn = lptw->KeyBufOut = lptw->KeyBuf;
                    225:
                    226:        lptw->hWndParent = CreateWindow(szParentClass, lptw->Title,
                    227:                  WS_OVERLAPPEDWINDOW,
                    228:                  lptw->Origin.x, lptw->Origin.y,
                    229:                  lptw->Size.x, lptw->Size.y,
                    230:                  NULL, NULL, lptw->hInstance, lptw);
                    231:        if (lptw->hWndParent == (HWND)NULL) {
                    232:                MessageBox((HWND)NULL,"Couldn't open parent text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
                    233:                return(1);
                    234:        }
                    235:        GetClientRect(lptw->hWndParent, &rect);
                    236:
                    237:        lptw->hWndText = CreateWindow(szTextClass, lptw->Title,
                    238:                  WS_CHILD | WS_VSCROLL | WS_HSCROLL,
                    239:                  0, lptw->ButtonHeight,
                    240:                  rect.right, rect.bottom-lptw->ButtonHeight,
                    241:                  lptw->hWndParent, NULL, lptw->hInstance, lptw);
                    242:        if (lptw->hWndText == (HWND)NULL) {
                    243:                MessageBox((HWND)NULL,"Couldn't open text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
                    244:                return(1);
                    245:        }
                    246:
                    247:        lptw->hPopMenu = CreatePopupMenu();
                    248:        AppendMenu(lptw->hPopMenu, MF_STRING, M_COPY_CLIP, "&Copy to Clipboard");
                    249:        AppendMenu(lptw->hPopMenu, MF_STRING, M_PASTE, "&Paste");
                    250: #if WINVER >= 0x030a
                    251:        AppendMenu(lptw->hPopMenu, MF_STRING, M_CHOOSE_FONT, "Choose &Font...");
                    252: #endif
                    253:        AppendMenu(lptw->hPopMenu, MF_STRING | (lptw->bSysColors ? MF_CHECKED : MF_UNCHECKED),
                    254:                M_SYSCOLORS, "&System Colors");
                    255:        if (lptw->IniFile != (LPSTR)NULL) {
                    256:                wsprintf(buf,"&Update %s",lptw->IniFile);
                    257:                AppendMenu(lptw->hPopMenu, MF_STRING, M_WRITEINI, (LPSTR)buf);
                    258:        }
                    259:
                    260:        sysmenu = GetSystemMenu(lptw->hWndParent,0);    /* get the sysmenu */
                    261:        AppendMenu(sysmenu, MF_SEPARATOR, 0, NULL);
                    262:        AppendMenu(sysmenu, MF_POPUP, (UINT)lptw->hPopMenu, "&Options");
                    263:        AppendMenu(sysmenu, MF_STRING, M_ABOUT, "&About");
                    264:
                    265:        if (lptw->lpmw)
                    266:                LoadMacros(lptw);
                    267:
                    268:        ShowWindow(lptw->hWndText, SW_SHOWNORMAL);
                    269:        BringWindowToTop(lptw->hWndText);
                    270:        SetFocus(lptw->hWndText);
                    271:        TextMessage();
                    272:        return(0);
                    273: }
                    274:
                    275: /* close a text window */
                    276: void WDPROC
                    277: TextClose(LPTW lptw)
                    278: {
                    279:        HGLOBAL hglobal;
                    280:
                    281:        /* close window */
                    282:        if (lptw->hWndParent)
                    283:                DestroyWindow(lptw->hWndParent);
                    284:        TextMessage();
                    285:
                    286:        hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->ScreenBuffer) );
                    287:        if (hglobal) {
                    288:                GlobalUnlock(hglobal);
                    289:                GlobalFree(hglobal);
                    290:        }
                    291:        hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->AttrBuffer) );
                    292:        if (hglobal) {
                    293:                GlobalUnlock(hglobal);
                    294:                GlobalFree(hglobal);
                    295:        }
                    296:        hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->KeyBuf) );
                    297:        if (hglobal) {
                    298:                GlobalUnlock(hglobal);
                    299:                GlobalFree(hglobal);
                    300:        }
                    301:
                    302:        if (lptw->lpmw)
                    303:                CloseMacros(lptw);
                    304:        lptw->hWndParent = (HWND)NULL;
                    305: }
                    306:
                    307: void
                    308: WriteTextIni(LPTW lptw)
                    309: {
                    310:        RECT rect;
                    311:        LPSTR file = lptw->IniFile;
                    312:        LPSTR section = lptw->IniSection;
                    313:        char profile[80];
                    314:        int iconic;
                    315:
                    316:
                    317:        if ((file == (LPSTR)NULL) || (section == (LPSTR)NULL))
                    318:                return;
                    319:
                    320:        iconic = IsIconic(lptw->hWndParent);
                    321:        if (iconic)
                    322:                ShowWindow(lptw->hWndParent, SW_SHOWNORMAL);
                    323:        GetWindowRect(lptw->hWndParent,&rect);
                    324:        wsprintf(profile, "%d %d", rect.left, rect.top);
                    325:        WritePrivateProfileString(section, "TextOrigin", profile, file);
                    326:        wsprintf(profile, "%d %d", rect.right-rect.left, rect.bottom-rect.top);
                    327:        WritePrivateProfileString(section, "TextSize", profile, file);
                    328:        wsprintf(profile, "%d", iconic);
                    329:        WritePrivateProfileString(section, "TextMinimized", profile, file);
                    330:        wsprintf(profile, "%s,%d", lptw->fontname, lptw->fontsize);
                    331:        WritePrivateProfileString(section, "TextFont", profile, file);
                    332:        wsprintf(profile, "%d", lptw->bSysColors);
                    333:        WritePrivateProfileString(section, "SysColors", profile, file);
                    334:        if (iconic)
                    335:                ShowWindow(lptw->hWndParent, SW_SHOWMINIMIZED);
                    336:        return;
                    337: }
                    338:
                    339: void
                    340: ReadTextIni(LPTW lptw)
                    341: {
                    342:        LPSTR file = lptw->IniFile;
                    343:        LPSTR section = lptw->IniSection;
                    344:        char profile[81];
                    345:        LPSTR p;
                    346:        BOOL bOKINI;
                    347:
                    348:        bOKINI = (file != (LPSTR)NULL) && (section != (LPSTR)NULL);
                    349:        profile[0] = '\0';
                    350:
                    351:        if (bOKINI)
                    352:          GetPrivateProfileString(section, "TextOrigin", "", profile, 80, file);
                    353:        if ( (p = GetInt(profile, (LPINT)&lptw->Origin.x)) == NULL)
                    354:                lptw->Origin.x = CW_USEDEFAULT;
                    355:        if ( (p = GetInt(p, (LPINT)&lptw->Origin.y)) == NULL)
                    356:                lptw->Origin.y = CW_USEDEFAULT;
                    357:        if ( (file != (LPSTR)NULL) && (section != (LPSTR)NULL) )
                    358:          GetPrivateProfileString(section, "TextSize", "", profile, 80, file);
                    359:        if ( (p = GetInt(profile, (LPINT)&lptw->Size.x)) == NULL)
                    360:                lptw->Size.x = CW_USEDEFAULT;
                    361:        if ( (p = GetInt(p, (LPINT)&lptw->Size.y)) == NULL)
                    362:                lptw->Size.y = CW_USEDEFAULT;
                    363:
                    364:        if (bOKINI)
                    365:          GetPrivateProfileString(section, "TextFont", "", profile, 80, file);
                    366:        {
                    367:                char FAR *size;
                    368:                size = _fstrchr(profile,',');
                    369:                if (size) {
                    370:                        *size++ = '\0';
                    371:                        if ( (p = GetInt(size, &lptw->fontsize)) == NULL)
                    372:                                lptw->fontsize = TEXTFONTSIZE;
                    373:                }
                    374:                _fstrcpy(lptw->fontname, profile);
                    375:                if (lptw->fontsize == 0)
                    376:                        lptw->fontsize = TEXTFONTSIZE;
                    377:                if (!(*lptw->fontname))
                    378:                        _fstrcpy(lptw->fontname,TEXTFONTNAME);
                    379:        }
                    380:
                    381:        if (bOKINI) {
                    382:                int iconic;
                    383:                GetPrivateProfileString(section, "TextMinimized", "", profile, 80, file);
                    384:                if ((p = GetInt(profile, &iconic)) == NULL)
                    385:                        iconic = 0;
                    386:                if (iconic)
                    387:                        lptw->nCmdShow = SW_SHOWMINIMIZED;
                    388:        }
                    389:        lptw->bSysColors = FALSE;
                    390:        GetPrivateProfileString(section, "SysColors", "", profile, 80, file);
                    391:        if ((p = GetInt(profile, &lptw->bSysColors)) == NULL)
                    392:                lptw->bSysColors = 0;
                    393: }
                    394:
                    395:
                    396: /* Bring Cursor into text window */
                    397: void WDPROC
                    398: TextToCursor(LPTW lptw)
                    399: {
                    400: int nXinc=0;
                    401: int nYinc=0;
                    402: int cxCursor;
                    403: int cyCursor;
                    404:        cyCursor = lptw->CursorPos.y * lptw->CharSize.y;
                    405:        if ( (cyCursor + lptw->CharSize.y > lptw->ScrollPos.y + lptw->ClientSize.y)
                    406:          || (cyCursor < lptw->ScrollPos.y) ) {
                    407:                nYinc = max(0, cyCursor + lptw->CharSize.y - lptw->ClientSize.y) - lptw->ScrollPos.y;
                    408:                nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
                    409:        }
                    410:        cxCursor = lptw->CursorPos.x * lptw->CharSize.x;
                    411:        if ( (cxCursor + lptw->CharSize.x > lptw->ScrollPos.x + lptw->ClientSize.x)
                    412:          || (cxCursor < lptw->ScrollPos.x) ) {
                    413:                nXinc = max(0, cxCursor + lptw->CharSize.x - lptw->ClientSize.x/2) - lptw->ScrollPos.x;
                    414:                nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
                    415:        }
                    416:        if (nYinc || nXinc) {
                    417:                lptw->ScrollPos.y += nYinc;
                    418:                lptw->ScrollPos.x += nXinc;
                    419:                ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
                    420:                SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
                    421:                SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
                    422:                UpdateWindow(lptw->hWndText);
                    423:        }
                    424: }
                    425:
                    426: void
                    427: NewLine(LPTW lptw)
                    428: {
                    429:        lptw->CursorPos.x = 0;
                    430:        lptw->CursorPos.y++;
                    431:        if (lptw->CursorPos.y >= lptw->ScreenSize.y) {
                    432:            int i =  lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
                    433:                _fmemmove(lptw->ScreenBuffer, lptw->ScreenBuffer+lptw->ScreenSize.x, i);
                    434:                _fmemset(lptw->ScreenBuffer + i, ' ', lptw->ScreenSize.x);
                    435:                _fmemmove(lptw->AttrBuffer, lptw->AttrBuffer+lptw->ScreenSize.x, i);
                    436:                _fmemset(lptw->AttrBuffer + i, NOTEXT, lptw->ScreenSize.x);
                    437:                lptw->CursorPos.y--;
                    438:                ScrollWindow(lptw->hWndText,0,-lptw->CharSize.y,NULL,NULL);
                    439:                lptw->MarkBegin.y--;
                    440:                lptw->MarkEnd.y--;
                    441:                LimitMark(lptw, &lptw->MarkBegin);
                    442:                LimitMark(lptw, &lptw->MarkEnd);
                    443:                UpdateWindow(lptw->hWndText);
                    444:        }
                    445:        if (lptw->CursorFlag)
                    446:                TextToCursor(lptw);
                    447:        TextMessage();
                    448: }
                    449:
                    450: /* Update count characters in window at cursor position */
                    451: /* Updates cursor position */
                    452: void
                    453: UpdateText(LPTW lptw, int count)
                    454: {
                    455: HDC hdc;
                    456: int xpos, ypos;
                    457:        xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
                    458:        ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
                    459:        hdc = GetDC(lptw->hWndText);
                    460:        if (lptw->bSysColors) {
                    461:            SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
                    462:            SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
                    463:        }
                    464:        else {
                    465:            SetTextColor(hdc, TextFore(lptw->Attr));
                    466:            SetBkColor(hdc, TextBack(lptw->Attr));
                    467:        }
                    468:        SelectObject(hdc, lptw->hfont);
                    469:        TextOut(hdc,xpos,ypos,
                    470:                (LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x +
                    471:                lptw->CursorPos.x), count);
                    472:        (void)ReleaseDC(lptw->hWndText,hdc);
                    473:        lptw->CursorPos.x += count;
                    474:        if (lptw->CursorPos.x >= lptw->ScreenSize.x)
                    475:                NewLine(lptw);
                    476: }
                    477:
                    478: int WDPROC
                    479: TextPutCh(LPTW lptw, BYTE ch)
                    480: {
                    481: int pos;
                    482:        switch(ch) {
                    483:                case '\r':
                    484:                        lptw->CursorPos.x = 0;
                    485:                        if (lptw->CursorFlag)
                    486:                                TextToCursor(lptw);
                    487:                        break;
                    488:                case '\n':
                    489:                        NewLine(lptw);
                    490:                        break;
                    491:                case 7:
                    492:                        MessageBeep(0xFFFFFFFF);
                    493:                        if (lptw->CursorFlag)
                    494:                                TextToCursor(lptw);
                    495:                        break;
                    496:                case '\t':
                    497:                        {
                    498:                        int n;
                    499:                                for ( n = 8 - (lptw->CursorPos.x % 8); n>0; n-- )
                    500:                                        TextPutCh(lptw, ' ');
                    501:                        }
                    502:                        break;
                    503:                case 0x08:
                    504:                case 0x7f:
                    505:                        lptw->CursorPos.x--;
                    506:                        if (lptw->CursorPos.x < 0) {
                    507:                                lptw->CursorPos.x = lptw->ScreenSize.x - 1;
                    508:                                lptw->CursorPos.y--;
                    509:                        }
                    510:                        if (lptw->CursorPos.y < 0)
                    511:                                lptw->CursorPos.y = 0;
                    512:                        break;
                    513:                default:
                    514:                        pos = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
                    515:                        lptw->ScreenBuffer[pos] = ch;
                    516:                        lptw->AttrBuffer[pos] = lptw->Attr;
                    517:                        UpdateText(lptw, 1);
                    518:        }
                    519:        return ch;
                    520: }
                    521:
                    522: void
                    523: TextPutStr(LPTW lptw, LPSTR str)
                    524: {
                    525: BYTE FAR *p, FAR *pa;
                    526: int count, limit;
                    527:        while (*str) {
                    528:                p = lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
                    529:                pa = lptw->AttrBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
                    530:                limit = lptw->ScreenSize.x - lptw->CursorPos.x;
                    531:                for (count=0; (count < limit) && *str && (isprint(*str) || *str=='\t'); count++) {
                    532:                        if (*str=='\t') {
                    533:                                int n;
                    534:                                for ( n = 8 - ((lptw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ ) {
                    535:                                        *p++ = ' ';
                    536:                                        *pa++ = lptw->Attr;
                    537:                                }
                    538:                                str++;
                    539:                                count--;
                    540:                        }
                    541:                        else {
                    542:                                *p++ = *str++;
                    543:                                *pa++ = lptw->Attr;
                    544:                        }
                    545:                }
                    546:                if (count>0) {
                    547:                        UpdateText(lptw, count);
                    548:                }
                    549:                if (*str=='\n') {
                    550:                        NewLine(lptw);
                    551:                        str++;
                    552:                }
                    553:                else if (*str && !isprint(*str) && *str!='\t') {
                    554:                        TextPutCh(lptw, *str++);
                    555:                }
                    556:        }
                    557: }
                    558:
                    559:
                    560: void
                    561: LimitMark(LPTW lptw, POINT FAR *lppt)
                    562: {
                    563:        if (lppt->x < 0)
                    564:                lppt->x = 0;
                    565:        if (lppt->y < 0) {
                    566:                lppt->x = 0;
                    567:                lppt->y = 0;
                    568:        }
                    569:        if (lppt->x > lptw->ScreenSize.x)
                    570:                lppt->x = lptw->ScreenSize.x;
                    571:        if (lppt->y >= lptw->ScreenSize.y) {
                    572:                lppt->x = 0;
                    573:                lppt->y = lptw->ScreenSize.y;
                    574:        }
                    575: }
                    576:
                    577: void
                    578: ClearMark(LPTW lptw, POINT pt)
                    579: {
                    580: RECT rect1, rect2, rect3;
                    581: int tmp;
                    582:   if ((lptw->MarkBegin.x != lptw->MarkEnd.x) ||
                    583:       (lptw->MarkBegin.y != lptw->MarkEnd.y) ) {
                    584:        if (lptw->MarkBegin.x > lptw->MarkEnd.x) {
                    585:                tmp = lptw->MarkBegin.x;
                    586:                lptw->MarkBegin.x = lptw->MarkEnd.x;
                    587:                lptw->MarkEnd.x = tmp;
                    588:        }
                    589:        if (lptw->MarkBegin.y > lptw->MarkEnd.y) {
                    590:                tmp = lptw->MarkBegin.y;
                    591:                lptw->MarkBegin.y = lptw->MarkEnd.y;
                    592:                lptw->MarkEnd.y = tmp;
                    593:        }
                    594:        /* calculate bounding rectangle in character coordinates */
                    595:        if (lptw->MarkBegin.y != lptw->MarkEnd.y) {
                    596:                rect1.left = 0;
                    597:                rect1.right = lptw->ScreenSize.x;
                    598:        }
                    599:        else {
                    600:                rect1.left = lptw->MarkBegin.x;
                    601:                rect1.right = lptw->MarkEnd.x + 1;
                    602:        }
                    603:        rect1.top = lptw->MarkBegin.y;
                    604:        rect1.bottom = lptw->MarkEnd.y + 1;
                    605:        /* now convert to client coordinates */
                    606:        rect1.left   = rect1.left   * lptw->CharSize.x - lptw->ScrollPos.x;
                    607:        rect1.right  = rect1.right  * lptw->CharSize.x - lptw->ScrollPos.x;
                    608:        rect1.top    = rect1.top    * lptw->CharSize.y - lptw->ScrollPos.y;
                    609:        rect1.bottom = rect1.bottom * lptw->CharSize.y - lptw->ScrollPos.y;
                    610:        /* get client rect and calculate intersection */
                    611:        GetClientRect(lptw->hWndText, &rect2);
                    612:        IntersectRect(&rect3,  &rect1, &rect2);
                    613:        /* update window if necessary */
                    614:        if (!IsRectEmpty(&rect3)) {
                    615:                InvalidateRect(lptw->hWndText, &rect3, TRUE);
                    616:        }
                    617:   }
                    618:   LimitMark(lptw, &pt);
                    619:   lptw->MarkBegin.x = lptw->MarkEnd.x = pt.x;
                    620:   lptw->MarkBegin.y = lptw->MarkEnd.y = pt.y;
                    621:   UpdateWindow(lptw->hWndText);
                    622: }
                    623:
                    624:
                    625: /* output a line including attribute changes as needed */
                    626: void
                    627: DoLine(LPTW lptw, HDC hdc, int xpos, int ypos, int offset, int count)
                    628: {
                    629:        BYTE FAR *pa, attr;
                    630:        int idx, num;
                    631:        pa = lptw->AttrBuffer + offset;
                    632: if ((offset < 0) || (offset >= lptw->ScreenSize.x*lptw->ScreenSize.y))
                    633: MessageBox((HWND)NULL, "panic", "panic", MB_OK | MB_ICONEXCLAMATION);
                    634:        idx = 0;
                    635:        num = count;
                    636:        while (num > 0) {
                    637:                attr = *pa;
                    638:                while ((num > 0) && (attr == *pa)) {
                    639:                        /* skip over bytes with same attribute */
                    640:                        num--;
                    641:                        pa++;
                    642:                }
                    643:                if (lptw->bSysColors) {
                    644:                    SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
                    645:                    SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
                    646:                }
                    647:                else {
                    648:                    SetTextColor(hdc, TextFore(attr));
                    649:                    SetBkColor(hdc, TextBack(attr));
                    650:                }
                    651:                TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset + idx),
                    652:                        count-num-idx);
                    653:                xpos += lptw->CharSize.x * (count-num-idx);
                    654:                idx = count-num;
                    655:        }
                    656: }
                    657:
                    658: void
                    659: DoMark(LPTW lptw, POINT pt, POINT end, BOOL mark)
                    660: {
                    661: int xpos, ypos;
                    662: HDC hdc;
                    663: int count;
                    664: int offset;
                    665:        offset = lptw->ScreenSize.x * pt.y + pt.x;
                    666:        hdc = GetDC(lptw->hWndText);
                    667:        SelectObject(hdc, lptw->hfont);
                    668:        if (lptw->bSysColors) {
                    669:            SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
                    670:            SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
                    671:        }
                    672:        else {
                    673:            SetTextColor(hdc, MARKFORE);
                    674:            SetBkColor(hdc, MARKBACK);
                    675:        }
                    676:        while (pt.y < end.y) {
                    677:                /* multiple lines */
                    678:                xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
                    679:                ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
                    680:                count = lptw->ScreenSize.x - pt.x;
                    681:                if (mark)
                    682:                        TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
                    683:                else {
                    684:                        DoLine(lptw, hdc, xpos, ypos, offset, count);
                    685:                        if (lptw->bSysColors) {
                    686:                            SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
                    687:                            SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
                    688:                        }
                    689:                        else {
                    690:                            SetTextColor(hdc, MARKFORE);
                    691:                            SetBkColor(hdc, MARKBACK);
                    692:                        }
                    693:                }
                    694:                offset += count;
                    695:                pt.y++;
                    696:                pt.x=0;
                    697:        }
                    698:        /* partial line */
                    699:        xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
                    700:        ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
                    701:        count = end.x - pt.x;
                    702:        if (end.y != lptw->ScreenSize.y) {
                    703:                if (mark)
                    704:                        TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
                    705:                else
                    706:                        DoLine(lptw, hdc, xpos, ypos, offset, count);
                    707:        }
                    708:        (void)ReleaseDC(lptw->hWndText,hdc);
                    709: }
                    710:
                    711: void
                    712: UpdateMark(LPTW lptw, POINT pt)
                    713: {
                    714: int begin, point, end;
                    715:        LimitMark(lptw, &pt);
                    716:        begin = lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x;
                    717:        point = lptw->ScreenSize.x*pt.y + pt.x;
                    718:        end   = lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x;
                    719:
                    720:        if (begin <= end) {
                    721:                /* forward mark */
                    722:                if (point >= end) {
                    723:                        /* extend marked area */
                    724:                        DoMark(lptw, lptw->MarkEnd, pt, TRUE);
                    725:                }
                    726:                else if (point >= begin) {
                    727:                        /* retract marked area */
                    728:                        DoMark(lptw, pt, lptw->MarkEnd, FALSE);
                    729:                }
                    730:                else {  /* retract and reverse */
                    731:                        DoMark(lptw, lptw->MarkBegin, lptw->MarkEnd, FALSE);
                    732:                        DoMark(lptw, pt, lptw->MarkBegin, TRUE);
                    733:                }
                    734:        }
                    735:        else {
                    736:                /* reverse mark */
                    737:                if (point <= end) {
                    738:                        /* extend marked area */
                    739:                        DoMark(lptw, pt, lptw->MarkEnd, TRUE);
                    740:                }
                    741:                else if (point <= begin) {
                    742:                        /* retract marked area */
                    743:                        DoMark(lptw, lptw->MarkEnd, pt, FALSE);
                    744:                }
                    745:                else {  /* retract and reverse */
                    746:                        DoMark(lptw, lptw->MarkEnd, lptw->MarkBegin, FALSE);
                    747:                        DoMark(lptw, lptw->MarkBegin, pt, TRUE);
                    748:                }
                    749:        }
                    750:        lptw->MarkEnd.x = pt.x;
                    751:        lptw->MarkEnd.y = pt.y;
                    752: }
                    753:
                    754:
                    755: #if WINVER >= 0x030a
                    756: /* Windows 3.1 drag-drop feature */
                    757: char szFile[80];
                    758: void
                    759: DragFunc(LPTW lptw, HDROP hdrop)
                    760: {
                    761:        int i, cFiles;
                    762:        LPSTR p;
                    763:        if ( (lptw->DragPre==(LPSTR)NULL) || (lptw->DragPost==(LPSTR)NULL) )
                    764:                return;
                    765:        cFiles = DragQueryFile(hdrop, 0xffff, (LPSTR)NULL, 0);
                    766:        for (i=0; i<cFiles; i++) {
                    767:                DragQueryFile(hdrop, i, szFile, 80);
                    768:                for (p=lptw->DragPre; *p; p++)
                    769:                        SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
                    770:                for (p=szFile; *p; p++)
                    771:                        SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
                    772:                for (p=lptw->DragPost; *p; p++)
                    773:                        SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
                    774:        }
                    775:        DragFinish(hdrop);
                    776: }
                    777: #endif
                    778:
                    779:
                    780: void
                    781: TextCopyClip(LPTW lptw)
                    782: {
                    783:        int size, count;
                    784:        HGLOBAL hGMem;
                    785:        LPSTR cbuf, cp;
                    786:        POINT pt, end;
                    787:        TEXTMETRIC tm;
                    788:        UINT type;
                    789:        HDC hdc;
                    790:
                    791:        if ((lptw->MarkBegin.x == lptw->MarkEnd.x) &&
                    792:            (lptw->MarkBegin.y == lptw->MarkEnd.y) ) {
                    793:                /* copy user text */
                    794:                return;
                    795:        }
                    796:
                    797:        size = (lptw->MarkEnd.y - lptw->MarkBegin.y + 1)
                    798:                * (lptw->ScreenSize.x + 2) + 1;
                    799:        hGMem = GlobalAlloc(GMEM_MOVEABLE, (DWORD)size);
                    800:        cbuf = cp = (LPSTR)GlobalLock(hGMem);
                    801:        if (cp == (LPSTR)NULL)
                    802:                return;
                    803:
                    804:        pt.x = lptw->MarkBegin.x;
                    805:        pt.y = lptw->MarkBegin.y;
                    806:        end.x   = lptw->MarkEnd.x;
                    807:        end.y   = lptw->MarkEnd.y;
                    808:
                    809:        while (pt.y < end.y) {
                    810:                /* copy to global buffer */
                    811:                count = lptw->ScreenSize.x - pt.x;
                    812:                _fmemcpy(cp, lptw->ScreenBuffer + lptw->ScreenSize.x*pt.y+pt.x, count);
                    813:                /* remove trailing spaces */
                    814:                for (count=count-1; count>=0; count--) {
                    815:                        if (cp[count]!=' ')
                    816:                                break;
                    817:                        cp[count] = '\0';
                    818:                }
                    819:                cp[++count] = '\r';
                    820:                cp[++count] = '\n';
                    821:                cp[++count] = '\0';
                    822:                cp += count;
                    823:                pt.y++;
                    824:                pt.x=0;
                    825:        }
                    826:        /* partial line */
                    827:        count = end.x - pt.x;
                    828:        if (end.y != lptw->ScreenSize.y) {
                    829:                _fmemcpy(cp, lptw->ScreenBuffer + lptw->ScreenSize.x*pt.y+pt.x, count);
                    830:                cp[count] = '\0';
                    831:        }
                    832:        size = _fstrlen(cbuf) + 1;
                    833:        GlobalUnlock(hGMem);
                    834:        hGMem = GlobalReAlloc(hGMem, (DWORD)size, GMEM_MOVEABLE);
                    835:        /* find out what type to put into clipboard */
                    836:        hdc = GetDC(lptw->hWndText);
                    837:        SelectObject(hdc, lptw->hfont);
                    838:        GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
                    839:        if (tm.tmCharSet == OEM_CHARSET)
                    840:                type = CF_OEMTEXT;
                    841:        else
                    842:                type = CF_TEXT;
                    843:        ReleaseDC(lptw->hWndText, hdc);
                    844:        /* give buffer to clipboard */
                    845:        OpenClipboard(lptw->hWndParent);
                    846:        EmptyClipboard();
                    847:        SetClipboardData(type, hGMem);
                    848:        CloseClipboard();
                    849: }
                    850:
                    851: void
                    852: TextMakeFont(LPTW lptw)
                    853: {
                    854:        LOGFONT lf;
                    855:        TEXTMETRIC tm;
                    856:        LPSTR p;
                    857:        HDC hdc;
                    858:
                    859:        hdc = GetDC(lptw->hWndText);
                    860:        _fmemset(&lf, 0, sizeof(LOGFONT));
                    861:        _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
                    862:        lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
                    863:        lf.lfPitchAndFamily = FIXED_PITCH;
                    864:        lf.lfCharSet = DEFAULT_CHARSET;
                    865:        if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
                    866:                lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
                    867:                lf.lfItalic = TRUE;
                    868:        }
                    869:        if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
                    870:                lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
                    871:                lf.lfWeight = FW_BOLD;
                    872:        }
                    873:        if (lptw->hfont != 0)
                    874:                DeleteObject(lptw->hfont);
                    875:        lptw->hfont = CreateFontIndirect((LOGFONT FAR *)&lf);
                    876:        /* get text size */
                    877:        SelectObject(hdc, lptw->hfont);
                    878:        GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
                    879:        lptw->CharSize.y = tm.tmHeight;
                    880:        lptw->CharSize.x = tm.tmAveCharWidth;
                    881:        lptw->CharAscent = tm.tmAscent;
                    882:        if (lptw->bFocus)
                    883:                CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
                    884:        ReleaseDC(lptw->hWndText, hdc);
                    885:        return;
                    886: }
                    887:
                    888: void
                    889: TextSelectFont(LPTW lptw) {
                    890: #if WINVER >= 0x030a
                    891:        LOGFONT lf;
                    892:        CHOOSEFONT cf;
                    893:        HDC hdc;
                    894:        char lpszStyle[LF_FACESIZE];
                    895:        LPSTR p;
                    896:
                    897:        /* Set all structure fields to zero. */
                    898:        _fmemset(&cf, 0, sizeof(CHOOSEFONT));
                    899:        _fmemset(&lf, 0, sizeof(LOGFONT));
                    900:        cf.lStructSize = sizeof(CHOOSEFONT);
                    901:        cf.hwndOwner = lptw->hWndParent;
                    902:        _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
                    903:        if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
                    904:                _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
                    905:                lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
                    906:        }
                    907:        else if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
                    908:                _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
                    909:                lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
                    910:        }
                    911:        else
                    912:                _fstrcpy(lpszStyle,"Regular");
                    913:        cf.lpszStyle = lpszStyle;
                    914:        hdc = GetDC(lptw->hWndText);
                    915:        lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
                    916:        ReleaseDC(lptw->hWndText, hdc);
                    917:        lf.lfPitchAndFamily = FIXED_PITCH;
                    918:        cf.lpLogFont = &lf;
                    919:        cf.nFontType = SCREEN_FONTTYPE;
                    920:        cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_INITTOLOGFONTSTRUCT | CF_USESTYLE;
                    921:        if (ChooseFont(&cf)) {
                    922:                RECT rect;
                    923:                _fstrcpy(lptw->fontname,lf.lfFaceName);
                    924:                lptw->fontsize = cf.iPointSize / 10;
                    925:                if (cf.nFontType & BOLD_FONTTYPE)
                    926:                        lstrcat(lptw->fontname," Bold");
                    927:                if (cf.nFontType & ITALIC_FONTTYPE)
                    928:                        lstrcat(lptw->fontname," Italic");
                    929:                TextMakeFont(lptw);
                    930:                /* force a window update */
                    931:                GetClientRect(lptw->hWndText, (LPRECT) &rect);
                    932:                SendMessage(lptw->hWndText, WM_SIZE, SIZE_RESTORED,
                    933:                        MAKELPARAM(rect.right-rect.left, rect.bottom-rect.top));
                    934:                GetClientRect(lptw->hWndText, (LPRECT) &rect);
                    935:                InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
                    936:                UpdateWindow(lptw->hWndText);
                    937:        }
                    938: #endif
                    939: }
                    940:
                    941:
                    942: /* parent overlapped window */
                    943: LRESULT CALLBACK WINEXPORT
                    944: WndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                    945: {
                    946:        HDC hdc;
                    947:        PAINTSTRUCT ps;
                    948:        RECT rect;
                    949:        LPTW lptw;
                    950:
                    951:        lptw = (LPTW)GetWindowLong(hwnd, 0);
                    952:
                    953:        switch(message) {
                    954:                case WM_SYSCOMMAND:
                    955:                        switch(LOWORD(wParam))
                    956:                        {
                    957:                                case M_COPY_CLIP:
                    958:                                case M_PASTE:
                    959:                                case M_CHOOSE_FONT:
                    960:                                case M_SYSCOLORS:
                    961:                                case M_WRITEINI:
                    962:                                case M_ABOUT:
                    963:                                  SendMessage(lptw->hWndText, WM_COMMAND, wParam, lParam);
                    964:                        }
                    965:                        break;
                    966:                case WM_SETFOCUS:
                    967:                        if (IsWindow(lptw->hWndText)) {
                    968:                                SetFocus(lptw->hWndText);
                    969:                                return(0);
                    970:                        }
                    971:                        break;
                    972:                case WM_GETMINMAXINFO:
                    973:                        {
                    974:                         POINT FAR * MMinfo = (POINT FAR *)lParam;
                    975:                        TEXTMETRIC tm;
                    976:                        hdc = GetDC(hwnd);
                    977:                        SelectObject(hdc, GetStockObject(OEM_FIXED_FONT));
                    978:                        GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
                    979:                        ReleaseDC(hwnd,hdc);
                    980:                        /* minimum size */
                    981:                        MMinfo[3].x = ScreenMinSize.x*tm.tmAveCharWidth
                    982:                                + GetSystemMetrics(SM_CXVSCROLL) + 2*GetSystemMetrics(SM_CXFRAME);
                    983:                        MMinfo[3].y = ScreenMinSize.y*tm.tmHeight
                    984:                                + GetSystemMetrics(SM_CYHSCROLL) + 2*GetSystemMetrics(SM_CYFRAME)
                    985:                                + GetSystemMetrics(SM_CYCAPTION);
                    986:                        }
                    987:                        return(0);
                    988:                case WM_SIZE:
                    989:                        SetWindowPos(lptw->hWndText, (HWND)NULL, 0, lptw->ButtonHeight,
                    990:                                LOWORD(lParam), HIWORD(lParam)-lptw->ButtonHeight,
                    991:                                SWP_NOZORDER | SWP_NOACTIVATE);
                    992:                        return(0);
                    993:                case WM_COMMAND:
                    994:                        if (IsWindow(lptw->hWndText))
                    995:                                SetFocus(lptw->hWndText);
                    996:                        SendMessage(lptw->hWndText, message, wParam, lParam); /* pass on menu commands */
                    997:                        return(0);
                    998:                case WM_PAINT:
                    999:                        {
                   1000:                        hdc = BeginPaint(hwnd, &ps);
                   1001:                        if (lptw->ButtonHeight) {
                   1002:                                HBRUSH hbrush;
                   1003:                                GetClientRect(hwnd, &rect);
                   1004:                                hbrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
                   1005:                                rect.bottom = lptw->ButtonHeight-1;
                   1006:                                FillRect(hdc, &rect, hbrush);
                   1007:                                DeleteObject(hbrush);
                   1008:                                SelectObject(hdc, GetStockObject(BLACK_PEN));
                   1009:                                MoveTo(hdc, rect.left, lptw->ButtonHeight-1);
                   1010:                                LineTo(hdc, rect.right, lptw->ButtonHeight-1);
                   1011:                        }
                   1012:                        EndPaint(hwnd, &ps);
                   1013:                        return 0;
                   1014:                        }
                   1015: #if WINVER >= 0x030a
                   1016:                case WM_DROPFILES:
                   1017:                        {
                   1018:                        WORD version = LOWORD(GetVersion());
                   1019:                        if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
                   1020:                                DragFunc(lptw, (HDROP)wParam);
                   1021:                        }
                   1022:                        break;
                   1023: #endif
                   1024:                case WM_CREATE:
                   1025:                        {
                   1026:                        RECT crect, wrect;
                   1027:                        TEXTMETRIC tm;
                   1028:                        lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
                   1029:                        SetWindowLong(hwnd, 0, (LONG)lptw);
                   1030:                        lptw->hWndParent = hwnd;
                   1031:                        /* get character size */
                   1032:                        TextMakeFont(lptw);
                   1033:                        hdc = GetDC(hwnd);
                   1034:                        SelectObject(hdc, lptw->hfont);
                   1035:                        GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
                   1036:                        lptw->CharSize.y = tm.tmHeight;
                   1037:                        lptw->CharSize.x = tm.tmAveCharWidth;
                   1038:                        lptw->CharAscent = tm.tmAscent;
                   1039:                        ReleaseDC(hwnd,hdc);
                   1040:                        GetClientRect(hwnd, &crect);
                   1041:                        if ( lptw->CharSize.x*lptw->ScreenSize.x < crect.right ) {
                   1042:                                /* shrink x size */
                   1043:                            GetWindowRect(lptw->hWndParent,&wrect);
                   1044:                            MoveWindow(lptw->hWndParent, wrect.left, wrect.top,
                   1045:                                 wrect.right-wrect.left + (lptw->CharSize.x*lptw->ScreenSize.x - crect.right),
                   1046:                                 wrect.bottom-wrect.top,
                   1047:                                 TRUE);
                   1048:                    }
                   1049:                        if ( lptw->CharSize.y*lptw->ScreenSize.y < crect.bottom ) {
                   1050:                                /* shrink y size */
                   1051:                            GetWindowRect(lptw->hWndParent,&wrect);
                   1052:                            MoveWindow(lptw->hWndParent, wrect.left, wrect.top,
                   1053:                                 wrect.right-wrect.left,
                   1054:                                 wrect.bottom-wrect.top + (lptw->CharSize.y*lptw->ScreenSize.y+lptw->ButtonHeight - crect.bottom),
                   1055:                                 TRUE);
                   1056:                        }
                   1057:                        }
                   1058: #if WINVER >= 0x030a
                   1059:                        {
                   1060:                        WORD version = LOWORD(GetVersion());
                   1061:                        if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
                   1062:                                if ( (lptw->DragPre!=(LPSTR)NULL) && (lptw->DragPost!=(LPSTR)NULL) )
                   1063:                                        DragAcceptFiles(hwnd, TRUE);
                   1064:                        }
                   1065: #endif
                   1066:                        break;
                   1067:                case WM_DESTROY:
                   1068: #if WINVER >= 0x030a
                   1069:                        {
                   1070:                        WORD version = LOWORD(GetVersion());
                   1071:                        if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
                   1072:                                DragAcceptFiles(hwnd, FALSE);
                   1073:                        }
                   1074: #endif
                   1075:                        DeleteObject(lptw->hfont);
                   1076:                        lptw->hfont = 0;
                   1077:                        break;
                   1078:                case WM_CLOSE:
                   1079:                        if (lptw->shutdown) {
                   1080:                                FARPROC lpShutDown = lptw->shutdown;
                   1081:                                (*lpShutDown)();
                   1082:                        }
                   1083:                        break;
                   1084:        }
                   1085:        return DefWindowProc(hwnd, message, wParam, lParam);
                   1086: }
                   1087:
                   1088: /* child text window */
                   1089: LRESULT CALLBACK WINEXPORT
                   1090: WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                   1091: {
                   1092:        HDC hdc;
                   1093:        PAINTSTRUCT ps;
                   1094:        RECT rect;
                   1095:        int nYinc, nXinc;
                   1096:        LPTW lptw;
                   1097:
                   1098:        lptw = (LPTW)GetWindowLong(hwnd, 0);
                   1099:
                   1100:        switch(message) {
                   1101:                case WM_SETFOCUS:
                   1102:                        lptw->bFocus = TRUE;
                   1103:                        CreateCaret(hwnd, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
                   1104:                        SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
                   1105:                                lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
                   1106:                                 - lptw->CaretHeight - lptw->ScrollPos.y);
                   1107:                        if (lptw->bGetCh)
                   1108:                                ShowCaret(hwnd);
                   1109:                        break;
                   1110:                case WM_KILLFOCUS:
                   1111:                        DestroyCaret();
                   1112:                        lptw->bFocus = FALSE;
                   1113:                        break;
                   1114:                case WM_SIZE:
                   1115:                        lptw->ClientSize.y = HIWORD(lParam);
                   1116:                        lptw->ClientSize.x = LOWORD(lParam);
                   1117:
                   1118:                        lptw->ScrollMax.y = max(0, lptw->CharSize.y*lptw->ScreenSize.y - lptw->ClientSize.y);
                   1119:                        lptw->ScrollPos.y = min(lptw->ScrollPos.y, lptw->ScrollMax.y);
                   1120:
                   1121:                        SetScrollRange(hwnd, SB_VERT, 0, lptw->ScrollMax.y, FALSE);
                   1122:                        SetScrollPos(hwnd, SB_VERT, lptw->ScrollPos.y, TRUE);
                   1123:
                   1124:                        lptw->ScrollMax.x = max(0, lptw->CharSize.x*lptw->ScreenSize.x - lptw->ClientSize.x);
                   1125:                        lptw->ScrollPos.x = min(lptw->ScrollPos.x, lptw->ScrollMax.x);
                   1126:
                   1127:                        SetScrollRange(hwnd, SB_HORZ, 0, lptw->ScrollMax.x, FALSE);
                   1128:                        SetScrollPos(hwnd, SB_HORZ, lptw->ScrollPos.x, TRUE);
                   1129:
                   1130:                        if (lptw->bFocus && lptw->bGetCh) {
                   1131:                                SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
                   1132:                                        lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
                   1133:                                        - lptw->CaretHeight - lptw->ScrollPos.y);
                   1134:                                ShowCaret(hwnd);
                   1135:                        }
                   1136:                        return(0);
                   1137:                case WM_VSCROLL:
                   1138:                        switch(LOWORD(wParam)) {
                   1139:                                case SB_TOP:
                   1140:                                        nYinc = -lptw->ScrollPos.y;
                   1141:                                        break;
                   1142:                                case SB_BOTTOM:
                   1143:                                        nYinc = lptw->ScrollMax.y - lptw->ScrollPos.y;
                   1144:                                        break;
                   1145:                                case SB_LINEUP:
                   1146:                                        nYinc = -lptw->CharSize.y;
                   1147:                                        break;
                   1148:                                case SB_LINEDOWN:
                   1149:                                        nYinc = lptw->CharSize.y;
                   1150:                                        break;
                   1151:                                case SB_PAGEUP:
                   1152:                                        nYinc = min(-1,-lptw->ClientSize.y);
                   1153:                                        break;
                   1154:                                case SB_PAGEDOWN:
                   1155:                                        nYinc = max(1,lptw->ClientSize.y);
                   1156:                                        break;
                   1157:                                case SB_THUMBPOSITION:
                   1158:                                        nYinc = LOWORD(lParam) - lptw->ScrollPos.y;
                   1159:                                        break;
                   1160:                                default:
                   1161:                                        nYinc = 0;
                   1162:                                }
                   1163:                        if ( (nYinc = max(-lptw->ScrollPos.y,
                   1164:                                min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y)))
                   1165:                                != 0 ) {
                   1166:                                lptw->ScrollPos.y += nYinc;
                   1167:                                ScrollWindow(hwnd,0,-nYinc,NULL,NULL);
                   1168:                                SetScrollPos(hwnd,SB_VERT,lptw->ScrollPos.y,TRUE);
                   1169:                                UpdateWindow(hwnd);
                   1170:                        }
                   1171:                        return(0);
                   1172:                case WM_HSCROLL:
                   1173:                        switch(LOWORD(wParam)) {
                   1174:                                case SB_LINEUP:
                   1175:                                        nXinc = -lptw->CharSize.x;
                   1176:                                        break;
                   1177:                                case SB_LINEDOWN:
                   1178:                                        nXinc = lptw->CharSize.x;
                   1179:                                        break;
                   1180:                                case SB_PAGEUP:
                   1181:                                        nXinc = min(-1,-lptw->ClientSize.x);
                   1182:                                        break;
                   1183:                                case SB_PAGEDOWN:
                   1184:                                        nXinc = max(1,lptw->ClientSize.x);
                   1185:                                        break;
                   1186:                                case SB_THUMBPOSITION:
                   1187:                                        nXinc = LOWORD(lParam) - lptw->ScrollPos.x;
                   1188:                                        break;
                   1189:                                default:
                   1190:                                        nXinc = 0;
                   1191:                                }
                   1192:                        if ( (nXinc = max(-lptw->ScrollPos.x,
                   1193:                                min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x)))
                   1194:                                != 0 ) {
                   1195:                                lptw->ScrollPos.x += nXinc;
                   1196:                                ScrollWindow(hwnd,-nXinc,0,NULL,NULL);
                   1197:                                SetScrollPos(hwnd,SB_HORZ,lptw->ScrollPos.x,TRUE);
                   1198:                                UpdateWindow(hwnd);
                   1199:                        }
                   1200:                        return(0);
                   1201:                case WM_KEYDOWN:
                   1202:                        if (GetKeyState(VK_SHIFT) < 0) {
                   1203:                          switch(wParam) {
                   1204:                                case VK_HOME:
                   1205:                                        SendMessage(hwnd, WM_VSCROLL, SB_TOP, (LPARAM)0);
                   1206:                                        break;
                   1207:                                case VK_END:
                   1208:                                        SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, (LPARAM)0);
                   1209:                                        break;
                   1210:                                case VK_PRIOR:
                   1211:                                        SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, (LPARAM)0);
                   1212:                                        break;
                   1213:                                case VK_NEXT:
                   1214:                                        SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, (LPARAM)0);
                   1215:                                        break;
                   1216:                                case VK_UP:
                   1217:                                        SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, (LPARAM)0);
                   1218:                                        break;
                   1219:                                case VK_DOWN:
                   1220:                                        SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, (LPARAM)0);
                   1221:                                        break;
                   1222:                                case VK_LEFT:
                   1223:                                        SendMessage(hwnd, WM_HSCROLL, SB_LINEUP, (LPARAM)0);
                   1224:                                        break;
                   1225:                                case VK_RIGHT:
                   1226:                                        SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, (LPARAM)0);
                   1227:                                        break;
                   1228:                          }
                   1229:                        }
                   1230:                        else {
                   1231:                          switch(wParam) {
                   1232:                                case VK_HOME:
                   1233:                                case VK_END:
                   1234:                                case VK_PRIOR:
                   1235:                                case VK_NEXT:
                   1236:                                case VK_UP:
                   1237:                                case VK_DOWN:
                   1238:                                case VK_LEFT:
                   1239:                                case VK_RIGHT:
                   1240:                                case VK_DELETE:
                   1241:                                { /* store key in circular buffer */
                   1242:                                long count;
                   1243:                                        count = lptw->KeyBufIn - lptw->KeyBufOut;
                   1244:                                        if (count < 0) count += lptw->KeyBufSize;
                   1245:                                        if (count < lptw->KeyBufSize-2) {
                   1246:                                                *lptw->KeyBufIn++ = 0;
                   1247:                                                if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
                   1248:                                                        lptw->KeyBufIn = lptw->KeyBuf;  /* wrap around */
                   1249:                                                *lptw->KeyBufIn++ = HIWORD(lParam) & 0xff;
                   1250:                                                if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
                   1251:                                                        lptw->KeyBufIn = lptw->KeyBuf;  /* wrap around */
                   1252:                                        }
                   1253:                                }
                   1254:                          }
                   1255:                        }
                   1256:                        break;
                   1257:                case WM_RBUTTONDOWN:
                   1258:                        {
                   1259:                        POINT pt;
                   1260:                        pt.x = LOWORD(lParam);
                   1261:                        pt.y = HIWORD(lParam);
                   1262:                        ClientToScreen(hwnd,&pt);
                   1263:                        TrackPopupMenu(lptw->hPopMenu, TPM_LEFTALIGN,
                   1264:                                pt.x, pt.y, 0, hwnd, NULL);
                   1265:                        }
                   1266:                        return(0);
                   1267:                case WM_LBUTTONDOWN:
                   1268:                        { /* start marking text */
                   1269:                        POINT pt;
                   1270:                        pt.x = LOWORD(lParam);
                   1271:                        pt.y = HIWORD(lParam);
                   1272:                        pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
                   1273:                        pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
                   1274:                        ClearMark(lptw, pt);
                   1275:                        }
                   1276:                        SetCapture(hwnd);       /* track the mouse */
                   1277:                        lptw->Marking = TRUE;
                   1278:                        break;
                   1279:                case WM_LBUTTONUP:
                   1280:                        { /* finish marking text */
                   1281:                        /* ensure begin mark is before end mark */
                   1282:                        ReleaseCapture();
                   1283:                        lptw->Marking = FALSE;
                   1284:                        if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
                   1285:                            (lptw->ScreenSize.x*lptw->MarkEnd.y   + lptw->MarkEnd.x)) {
                   1286:                                POINT tmp;
                   1287:                                tmp.x = lptw->MarkBegin.x;
                   1288:                                tmp.y = lptw->MarkBegin.y;
                   1289:                                lptw->MarkBegin.x = lptw->MarkEnd.x;
                   1290:                                lptw->MarkBegin.y = lptw->MarkEnd.y;
                   1291:                                lptw->MarkEnd.x   = tmp.x;
                   1292:                                lptw->MarkEnd.y   = tmp.y;
                   1293:                        }
                   1294:                        }
                   1295:                        break;
                   1296:                case WM_MOUSEMOVE:
                   1297:                        if ( (wParam & MK_LBUTTON) && lptw->Marking ) {
                   1298:                        RECT rect;
                   1299:                        POINT pt;
                   1300:                        pt.x = LOWORD(lParam);
                   1301:                        pt.y = HIWORD(lParam);
                   1302:                        GetClientRect(hwnd, &rect);
                   1303:                        if (PtInRect(&rect, pt)) {
                   1304:                                pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
                   1305:                                pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
                   1306:                                UpdateMark(lptw, pt);
                   1307:                        }
                   1308:                        else {
                   1309:                          int nXinc;
                   1310:                          int nYinc;
                   1311:                          do {
                   1312:                                nXinc = 0;
                   1313:                                nYinc = 0;
                   1314:                                if (pt.x > rect.right) {
                   1315:                                        nXinc = lptw->CharSize.x * 4;
                   1316:                                        pt.x = (rect.right + lptw->ScrollPos.x)/lptw->CharSize.x + 2;
                   1317:                                }
                   1318:                                else if (pt.x < rect.left) {
                   1319:                                        nXinc = -lptw->CharSize.x * 4;
                   1320:                                        pt.x = (rect.left + lptw->ScrollPos.x)/lptw->CharSize.x - 2;
                   1321:                                }
                   1322:                                else
                   1323:                                        pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
                   1324:                                if (pt.y > rect.bottom) {
                   1325:                                        nYinc = lptw->CharSize.y;
                   1326:                                        pt.y = (rect.bottom + lptw->ScrollPos.y)/lptw->CharSize.y + 1;
                   1327:                                }
                   1328:                                else if (pt.y < rect.top) {
                   1329:                                        nYinc = -lptw->CharSize.y;
                   1330:                                        pt.y = (rect.top + lptw->ScrollPos.y)/lptw->CharSize.y - 1;
                   1331:                                }
                   1332:                                else
                   1333:                                        pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
                   1334:                                LimitMark(lptw, &pt);
                   1335:                                nXinc = max(nXinc, -lptw->ScrollPos.x);
                   1336:                                nYinc = max(nYinc, -lptw->ScrollPos.y);
                   1337:                                nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
                   1338:                                nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
                   1339:                                if (nYinc || nXinc) {
                   1340:                                        lptw->ScrollPos.y += nYinc;
                   1341:                                        lptw->ScrollPos.x += nXinc;
                   1342:                                        ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
                   1343:                                        SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
                   1344:                                        SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
                   1345:                                        UpdateWindow(lptw->hWndText);
                   1346:                                }
                   1347:                                UpdateMark(lptw, pt);
                   1348:                                GetCursorPos(&pt);
                   1349:                                ScreenToClient(hwnd, &pt);
                   1350:                          }
                   1351:                          while( (nYinc || nXinc) && !PtInRect(&rect, pt) &&
                   1352:                                (GetAsyncKeyState(VK_LBUTTON) < 0) );
                   1353:                        }
                   1354:                        }
                   1355:                        break;
                   1356:                case WM_CHAR:
                   1357:                        { /* store key in circular buffer */
                   1358:                        long count;
                   1359:                                count = lptw->KeyBufIn - lptw->KeyBufOut;
                   1360:                                if (count < 0) count += lptw->KeyBufSize;
                   1361:                                if (count < lptw->KeyBufSize-1) {
                   1362:                                        *lptw->KeyBufIn++ = wParam;
                   1363:                                        if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
                   1364:                                                lptw->KeyBufIn = lptw->KeyBuf;  /* wrap around */
                   1365:                                }
                   1366:                        }
                   1367:                        return(0);
                   1368:                case WM_COMMAND:
                   1369:                        if (LOWORD(wParam) < NUMMENU)
                   1370:                                SendMacro(lptw, LOWORD(wParam));
                   1371:                        else
                   1372:                        switch(LOWORD(wParam))
                   1373:                        {
                   1374:                                case M_COPY_CLIP:
                   1375:                                        TextCopyClip(lptw);
                   1376:                                        return 0;
                   1377:                                case M_PASTE:
                   1378:                                        {
                   1379:                                        HGLOBAL hGMem;
                   1380:                                        BYTE FAR *cbuf;
                   1381:                                        TEXTMETRIC tm;
                   1382:                                        UINT type;
                   1383:                                        /* find out what type to get from clipboard */
                   1384:                                        hdc = GetDC(hwnd);
                   1385:                                        SelectObject(hdc, lptw->hfont);
                   1386:                                        GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
                   1387:                                        if (tm.tmCharSet == OEM_CHARSET)
                   1388:                                                type = CF_OEMTEXT;
                   1389:                                        else
                   1390:                                                type = CF_TEXT;
                   1391:                                        ReleaseDC(lptw->hWndText, hdc);
                   1392:                                        /* now get it from clipboard */
                   1393:                                        OpenClipboard(hwnd);
                   1394:                                        hGMem = GetClipboardData(type);
                   1395:                                        if (hGMem) {
                   1396:                                                cbuf = (BYTE FAR *) GlobalLock(hGMem);
                   1397:                                                while (*cbuf) {
                   1398:                                                        if (*cbuf != '\n')
                   1399:                                                                SendMessage(lptw->hWndText,WM_CHAR,*cbuf,1L);
                   1400:                                                        cbuf++;
                   1401:                                                }
                   1402:                                                GlobalUnlock(hGMem);
                   1403:                                        }
                   1404:                                        CloseClipboard();
                   1405:                                        return 0;
                   1406:                                        }
                   1407:                                case M_CHOOSE_FONT:
                   1408:                                        TextSelectFont(lptw);
                   1409:                                        return 0;
                   1410:                                case M_SYSCOLORS:
                   1411:                                        lptw->bSysColors = !lptw->bSysColors;
                   1412:                                        if (lptw->bSysColors)
                   1413:                                                CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_CHECKED);
                   1414:                                        else
                   1415:                                                CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_UNCHECKED);
                   1416:                                        SendMessage(hwnd, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0);
                   1417:                                        InvalidateRect(hwnd, (LPRECT)NULL, 1);
                   1418:                                        UpdateWindow(hwnd);
                   1419:                                        return 0;
                   1420:                                case M_WRITEINI:
                   1421:                                        WriteTextIni(lptw);
                   1422:                                        return 0;
                   1423:                                case M_ABOUT:
                   1424:                                        AboutBox(hwnd,lptw->AboutText);
                   1425:                                        return 0;
                   1426:                        }
                   1427:                        return(0);
                   1428:                case WM_SYSCOLORCHANGE:
                   1429:                        DeleteObject(lptw->hbrBackground);
                   1430:                        lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ?
                   1431:                                GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
                   1432:                        return(0);
                   1433:                case WM_ERASEBKGND:
                   1434:                        return(1);      /* we will erase it ourselves */
                   1435:                case WM_PAINT:
                   1436:                        {
                   1437:                        POINT source, width, dest;
                   1438:                        POINT MarkBegin, MarkEnd;
                   1439:                        hdc = BeginPaint(hwnd, &ps);
                   1440:                        if (ps.fErase)
                   1441:                                FillRect(hdc, &ps.rcPaint, lptw->hbrBackground);
                   1442:                        SelectObject(hdc, lptw->hfont);
                   1443:                        SetMapMode(hdc, MM_TEXT);
                   1444:                        SetBkMode(hdc,OPAQUE);
                   1445:                        GetClientRect(hwnd, &rect);
                   1446:                        source.x = (rect.left + lptw->ScrollPos.x) / lptw->CharSize.x;          /* source */
                   1447:                        source.y = (rect.top + lptw->ScrollPos.y) / lptw->CharSize.y;
                   1448:                        dest.x = source.x * lptw->CharSize.x - lptw->ScrollPos.x;                               /* destination */
                   1449:                        dest.y = source.y * lptw->CharSize.y - lptw->ScrollPos.y;
                   1450:                        width.x = ((rect.right  + lptw->ScrollPos.x + lptw->CharSize.x - 1) / lptw->CharSize.x) - source.x; /* width */
                   1451:                        width.y = ((rect.bottom + lptw->ScrollPos.y + lptw->CharSize.y - 1) / lptw->CharSize.y) - source.y;
                   1452:                        if (source.x < 0)
                   1453:                                source.x = 0;
                   1454:                        if (source.y < 0)
                   1455:                                source.y = 0;
                   1456:                        if (source.x+width.x > lptw->ScreenSize.x)
                   1457:                                width.x = lptw->ScreenSize.x - source.x;
                   1458:                        if (source.y+width.y > lptw->ScreenSize.y)
                   1459:                                width.y = lptw->ScreenSize.y - source.y;
                   1460:                        /* ensure begin mark is before end mark */
                   1461:                        if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
                   1462:                            (lptw->ScreenSize.x*lptw->MarkEnd.y   + lptw->MarkEnd.x)) {
                   1463:                                MarkBegin.x = lptw->MarkEnd.x;
                   1464:                                MarkBegin.y = lptw->MarkEnd.y;
                   1465:                                MarkEnd.x   = lptw->MarkBegin.x;
                   1466:                                MarkEnd.y   = lptw->MarkBegin.y;
                   1467:                        }
                   1468:                        else {
                   1469:                                MarkBegin.x = lptw->MarkBegin.x;
                   1470:                                MarkBegin.y = lptw->MarkBegin.y;
                   1471:                                MarkEnd.x   = lptw->MarkEnd.x;
                   1472:                                MarkEnd.y   = lptw->MarkEnd.y;
                   1473:                        }
                   1474:                        /* for each line */
                   1475:                        while (width.y>0) {
                   1476:                                if ( (source.y >= MarkBegin.y) && (source.y <= MarkEnd.y) ) {
                   1477:                                        int start, end;
                   1478:                                        int count, offset;
                   1479:                                        if (source.y == MarkBegin.y)
                   1480:                                                start = MarkBegin.x;
                   1481:                                        else
                   1482:                                                start = 0;
                   1483:                                        if (source.y == MarkEnd.y)
                   1484:                                                end = MarkEnd.x;
                   1485:                                        else
                   1486:                                                end = lptw->ScreenSize.x;
                   1487:                                        /* do stuff before marked text */
                   1488:                                        offset = 0;
                   1489:                                        count = start - source.x;
                   1490:                                        if (count > 0)
                   1491:                                          DoLine(lptw, hdc, dest.x, dest.y,
                   1492:                                                source.y*lptw->ScreenSize.x + source.x, count);
                   1493:                                        /* then the marked text */
                   1494:                                        offset += count;
                   1495:                                        count = end - start;
                   1496:                                        if ((count > 0) && (offset < width.x)){
                   1497:                                          if (lptw->bSysColors) {
                   1498:                                            SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
                   1499:                                            SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
                   1500:                                          }
                   1501:                                          else {
                   1502:                                            SetTextColor(hdc, MARKFORE);
                   1503:                                            SetBkColor(hdc, MARKBACK);
                   1504:                                          }
                   1505:                                          TextOut(hdc, dest.x + lptw->CharSize.x*offset, dest.y,
                   1506:                                                (LPSTR)(lptw->ScreenBuffer + source.y*lptw->ScreenSize.x
                   1507:                                                + source.x + offset), count);
                   1508:                                        }
                   1509:                                        /* then stuff after marked text */
                   1510:                                        offset += count;
                   1511:                                        count = width.x + source.x - end;
                   1512:                                        if ((count > 0) && (offset < width.x))
                   1513:                                          DoLine(lptw, hdc, dest.x + lptw->CharSize.x*offset, dest.y,
                   1514:                                                source.y*lptw->ScreenSize.x + source.x + offset, count);
                   1515:                                }
                   1516:                                else {
                   1517:                                        DoLine(lptw, hdc, dest.x, dest.y,
                   1518:                                                source.y*lptw->ScreenSize.x + source.x, width.x);
                   1519:                                }
                   1520:                                dest.y += lptw->CharSize.y;
                   1521:                                source.y++;
                   1522:                                width.y--;
                   1523:                        }
                   1524:                        EndPaint(hwnd, &ps);
                   1525:                        return 0;
                   1526:                        }
                   1527:                case WM_CREATE:
                   1528:                        lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
                   1529:                        SetWindowLong(hwnd, 0, (LONG)lptw);
                   1530:                        lptw->hWndText = hwnd;
                   1531:                        break;
                   1532:                case WM_DESTROY:
                   1533:                        DeleteObject(lptw->hbrBackground);
                   1534:                        break;
                   1535:        }
                   1536:        return DefWindowProc(hwnd, message, wParam, lParam);
                   1537: }
                   1538:
                   1539:
                   1540: /* ================================== */
                   1541: /* replacement stdio routines */
                   1542:
                   1543: /* TRUE if key hit, FALSE if no key */
                   1544: int WDPROC
                   1545: TextKBHit(LPTW lptw)
                   1546: {
                   1547:        return (lptw->KeyBufIn != lptw->KeyBufOut);
                   1548: }
                   1549:
                   1550: /* get character from keyboard, no echo */
                   1551: /* need to add extended codes */
                   1552: int WDPROC
                   1553: TextGetCh(LPTW lptw)
                   1554: {
                   1555:        int ch;
                   1556:        TextToCursor(lptw);
                   1557:        lptw->bGetCh = TRUE;
                   1558:        if (lptw->bFocus) {
                   1559:                SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
                   1560:                        lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
                   1561:                        - lptw->CaretHeight - lptw->ScrollPos.y);
                   1562:                ShowCaret(lptw->hWndText);
                   1563:        }
                   1564:         while (!TextKBHit(lptw)) { /* CMW: can't use TextMessage here as it does not idle properly */
                   1565:                 MSG msg;
                   1566:                 GetMessage(&msg, 0, 0, 0);
                   1567:                 TranslateMessage(&msg);
                   1568:                 DispatchMessage(&msg);
                   1569:         }
                   1570:        ch = *lptw->KeyBufOut++;
                   1571:        if (ch=='\r')
                   1572:                ch = '\n';
                   1573:        if (lptw->KeyBufOut - lptw->KeyBuf >= lptw->KeyBufSize)
                   1574:                lptw->KeyBufOut = lptw->KeyBuf; /* wrap around */
                   1575:        if (lptw->bFocus)
                   1576:                HideCaret(lptw->hWndText);
                   1577:        lptw->bGetCh = FALSE;
                   1578:        return ch;
                   1579: }
                   1580:
                   1581: /* get character from keyboard, with echo */
                   1582: int WDPROC
                   1583: TextGetChE(LPTW lptw)
                   1584: {
                   1585: int ch;
                   1586:        ch = TextGetCh(lptw);
                   1587:        TextPutCh(lptw, (BYTE)ch);
                   1588:        return ch;
                   1589: }
                   1590:
                   1591: LPSTR WDPROC
                   1592: TextGetS(LPTW lptw, LPSTR str, unsigned int size)
                   1593: {
                   1594:        LPSTR next = str;
                   1595:        while (--size>0) {
                   1596:                switch(*next = TextGetChE(lptw)) {
                   1597:                        case EOF:
                   1598:                                *next = 0;
                   1599:                                if (next == str) return (char *)NULL;
                   1600:                                return str;
                   1601:                        case '\n':
                   1602:                                *(next+1) = 0;
                   1603:                                return str;
                   1604:                        case 0x08:
                   1605:                        case 0x7f:
                   1606:                                if (next > str)
                   1607:                                        --next;
                   1608:                                break;
                   1609:                        default:
                   1610:                                ++next;
                   1611:                }
                   1612:        }
                   1613:        *next = 0;
                   1614:        return str;
                   1615: }
                   1616:
                   1617: int WDPROC
                   1618: TextPutS(LPTW lptw, LPSTR str)
                   1619: {
                   1620:        TextPutStr(lptw, str);
                   1621:        return str[_fstrlen(str)-1];
                   1622: }
                   1623:
                   1624: /* ================================== */
                   1625: /* routines added for elvis */
                   1626:
                   1627: void WDPROC
                   1628: TextGotoXY(LPTW lptw, int x, int y)
                   1629: {
                   1630:        lptw->CursorPos.x = x;
                   1631:        lptw->CursorPos.y = y;
                   1632: }
                   1633:
                   1634: int  WDPROC
                   1635: TextWhereX(LPTW lptw)
                   1636: {
                   1637:        return lptw->CursorPos.x;
                   1638: }
                   1639:
                   1640: int  WDPROC
                   1641: TextWhereY(LPTW lptw)
                   1642: {
                   1643:        return lptw->CursorPos.y;
                   1644: }
                   1645:
                   1646: void WDPROC
                   1647: TextCursorHeight(LPTW lptw, int height)
                   1648: {
                   1649:        lptw->CaretHeight = height;
                   1650:        if (lptw->bFocus)
                   1651:                CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
                   1652: }
                   1653:
                   1654: void WDPROC
                   1655: TextClearEOL(LPTW lptw)
                   1656: {
                   1657: HDC hdc;
                   1658: int xpos, ypos;
                   1659: int from, len;
                   1660: POINT pt;
                   1661:        pt.x = pt.y = 0;
                   1662:        ClearMark(lptw, pt);
                   1663:        from = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
                   1664:        len = lptw->ScreenSize.x-lptw->CursorPos.x;
                   1665:        _fmemset(lptw->ScreenBuffer + from, ' ', len);
                   1666:        _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
                   1667:        xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
                   1668:        ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
                   1669:        hdc = GetDC(lptw->hWndText);
                   1670:        if (lptw->bSysColors) {
                   1671:            SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
                   1672:            SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
                   1673:        }
                   1674:        else {
                   1675:            SetTextColor(hdc, TextFore(lptw->Attr));
                   1676:            SetBkColor(hdc, TextBack(lptw->Attr));
                   1677:        }
                   1678:        SelectObject(hdc, (lptw->hfont));
                   1679:        TextOut(hdc,xpos,ypos,
                   1680:                (LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x +
                   1681:                lptw->CursorPos.x), lptw->ScreenSize.x-lptw->CursorPos.x);
                   1682:        (void)ReleaseDC(lptw->hWndText,hdc);
                   1683: }
                   1684:
                   1685: void WDPROC
                   1686: TextClearEOS(LPTW lptw)
                   1687: {
                   1688: RECT rect;
                   1689: int from, len;
                   1690: POINT pt;
                   1691:        pt.x = pt.y = 0;
                   1692:        ClearMark(lptw, pt);
                   1693:        from = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
                   1694:        len = lptw->ScreenSize.x-lptw->CursorPos.x +
                   1695:                        (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
                   1696:        _fmemset(lptw->ScreenBuffer + from, ' ', len);
                   1697:        _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
                   1698:        GetClientRect(lptw->hWndText, (LPRECT) &rect);
                   1699:        InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
                   1700:        UpdateWindow(lptw->hWndText);
                   1701: }
                   1702:
                   1703: void WDPROC
                   1704: TextInsertLine(LPTW lptw)
                   1705: {
                   1706: RECT rect;
                   1707: int from, to, len;
                   1708: POINT pt;
                   1709:        pt.x = pt.y = 0;
                   1710:        ClearMark(lptw, pt);
                   1711:        from = lptw->CursorPos.y*lptw->ScreenSize.x,
                   1712:        to = (lptw->CursorPos.y+1)*lptw->ScreenSize.x;
                   1713:        len = (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
                   1714:        _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
                   1715:        _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
                   1716:        _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
                   1717:        _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
                   1718:        GetClientRect(lptw->hWndText, (LPRECT) &rect);
                   1719:        InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
                   1720:        UpdateWindow(lptw->hWndText);
                   1721:        if (lptw->CursorFlag)
                   1722:                TextToCursor(lptw);
                   1723: }
                   1724:
                   1725: void WDPROC
                   1726: TextDeleteLine(LPTW lptw)
                   1727: {
                   1728: RECT rect;
                   1729: int from, to, len;
                   1730: POINT pt;
                   1731:        pt.x = pt.y = 0;
                   1732:        ClearMark(lptw, pt);
                   1733:        to = lptw->CursorPos.y*lptw->ScreenSize.x,
                   1734:        from = (lptw->CursorPos.y+1)*lptw->ScreenSize.x;
                   1735:        len = (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
                   1736:        _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
                   1737:        _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
                   1738:        from = lptw->ScreenSize.x*(lptw->ScreenSize.y -1);
                   1739:        _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
                   1740:        _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
                   1741:        GetClientRect(lptw->hWndText, (LPRECT) &rect);
                   1742:        InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
                   1743:        UpdateWindow(lptw->hWndText);
                   1744:        if (lptw->CursorFlag)
                   1745:                TextToCursor(lptw);
                   1746: }
                   1747:
                   1748: void WDPROC
                   1749: TextScrollReverse(LPTW lptw)
                   1750: {
                   1751: RECT rect;
                   1752: int len = lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
                   1753:        _fmemmove(lptw->ScreenBuffer+lptw->ScreenSize.x, lptw->ScreenBuffer, len);
                   1754:        _fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x);
                   1755:        _fmemmove(lptw->AttrBuffer+lptw->ScreenSize.x, lptw->AttrBuffer, len);
                   1756:        _fmemset(lptw->AttrBuffer, NOTEXT, lptw->ScreenSize.x);
                   1757:        if (lptw->CursorPos.y)
                   1758:                lptw->CursorPos.y--;
                   1759:        ScrollWindow(lptw->hWndText,0,+lptw->CharSize.y,NULL,NULL);
                   1760:        GetClientRect(lptw->hWndText, (LPRECT) &rect);
                   1761:        rect.top = lptw->ScreenSize.y*lptw->CharSize.y;
                   1762:        if (rect.top < rect.bottom)
                   1763:                InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
                   1764:        lptw->MarkBegin.y++;
                   1765:        lptw->MarkEnd.y++;
                   1766:        LimitMark(lptw, &lptw->MarkBegin);
                   1767:        LimitMark(lptw, &lptw->MarkEnd);
                   1768:        UpdateWindow(lptw->hWndText);
                   1769: }
                   1770:
                   1771: void WDPROC
                   1772: TextAttr(LPTW lptw, BYTE attr)
                   1773: {
                   1774:        lptw->Attr = attr;
                   1775: }
                   1776:
                   1777: /* About Box */
                   1778: BOOL CALLBACK WINEXPORT
                   1779: AboutDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
                   1780: {
                   1781:        switch (wMsg) {
                   1782:                case WM_INITDIALOG:
                   1783:                        {
                   1784:                        char buf[80];
                   1785:                        GetWindowText(GetParent(hDlg),buf,80);
                   1786:                        SetDlgItemText(hDlg, AB_TEXT1, buf);
                   1787:                        SetDlgItemText(hDlg, AB_TEXT2, (LPSTR)lParam);
                   1788: #ifdef __DLL__
                   1789:                        wsprintf(buf,"WGNUPLOT.DLL Version %s",(LPSTR)WGNUPLOTVERSION);
                   1790:                        SetDlgItemText(hDlg, AB_TEXT3, buf);
                   1791: #endif
                   1792:                        }
                   1793:                        return TRUE;
                   1794:                case WM_DRAWITEM:
                   1795:                        {
                   1796:                        LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
                   1797: #ifdef WIN32
                   1798:                        DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassLong(GetParent(hDlg), GCL_HICON));
                   1799: #else
                   1800:                        DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassWord(GetParent(hDlg), GCW_HICON));
                   1801: #endif
                   1802:                        }
                   1803:                        return FALSE;
                   1804:                case WM_COMMAND:
                   1805:                        switch (LOWORD(wParam)) {
                   1806:                                case IDCANCEL:
                   1807:                                case IDOK:
                   1808:                                        EndDialog(hDlg, LOWORD(wParam));
                   1809:                                        return TRUE;
                   1810:                        }
                   1811:                        break;
                   1812:        }
                   1813:        return FALSE;
                   1814: }
                   1815:
                   1816:
                   1817: void WDPROC
                   1818: AboutBox(HWND hwnd, LPSTR str)
                   1819: {
                   1820: #ifdef WIN32
                   1821:        DialogBoxParam(hdllInstance,"AboutDlgBox",hwnd,AboutDlgProc,(LPARAM)str);
                   1822: #else
                   1823: DLGPROC lpfnAboutDlgProc;
                   1824: #ifdef __DLL__
                   1825:        lpfnAboutDlgProc = (DLGPROC)GetProcAddress(hdllInstance, "AboutDlgProc");
                   1826: #else
                   1827:        lpfnAboutDlgProc = (DLGPROC)MakeProcInstance((FARPROC)AboutDlgProc, hdllInstance);
                   1828: #endif
                   1829:        DialogBoxParam(hdllInstance,"AboutDlgBox",hwnd,lpfnAboutDlgProc,(LPARAM)str);
                   1830:        EnableWindow(hwnd,TRUE);
                   1831: #ifndef __DLL__
                   1832:        FreeProcInstance((FARPROC)lpfnAboutDlgProc);
                   1833: #endif
                   1834: #endif
                   1835: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>