13ff48bf5SDavid du Colombier /* Copyright (C) 1996-2001 Ghostgum Software Pty Ltd. All rights reserved.
23ff48bf5SDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
53ff48bf5SDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
93ff48bf5SDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
153ff48bf5SDavid du Colombier */
163ff48bf5SDavid du Colombier
173ff48bf5SDavid du Colombier
18*593dc095SDavid du Colombier /* $Id: dwtext.c,v 1.9 2005/03/04 10:27:39 ghostgum Exp $ */
193ff48bf5SDavid du Colombier
203ff48bf5SDavid du Colombier /* Microsoft Windows text window for Ghostscript.
213ff48bf5SDavid du Colombier
223ff48bf5SDavid du Colombier #include <stdlib.h>
233ff48bf5SDavid du Colombier #include <string.h> /* use only far items */
243ff48bf5SDavid du Colombier #include <ctype.h>
253ff48bf5SDavid du Colombier
263ff48bf5SDavid du Colombier #define STRICT
273ff48bf5SDavid du Colombier #include <windows.h>
283ff48bf5SDavid du Colombier #include <windowsx.h>
293ff48bf5SDavid du Colombier #include <commdlg.h>
303ff48bf5SDavid du Colombier #include <shellapi.h>
313ff48bf5SDavid du Colombier
323ff48bf5SDavid du Colombier #include "dwtext.h"
333ff48bf5SDavid du Colombier
343ff48bf5SDavid du Colombier /* Define min and max, but make sure to use the identical definition */
353ff48bf5SDavid du Colombier /* to the one that all the compilers seem to have.... */
363ff48bf5SDavid du Colombier #ifndef min
373ff48bf5SDavid du Colombier # define min(a, b) (((a) < (b)) ? (a) : (b))
383ff48bf5SDavid du Colombier #endif
393ff48bf5SDavid du Colombier #ifndef max
403ff48bf5SDavid du Colombier # define max(a, b) (((a) > (b)) ? (a) : (b))
413ff48bf5SDavid du Colombier #endif
423ff48bf5SDavid du Colombier
433ff48bf5SDavid du Colombier #ifndef EOF
443ff48bf5SDavid du Colombier #define EOF (-1)
453ff48bf5SDavid du Colombier #endif
463ff48bf5SDavid du Colombier
473ff48bf5SDavid du Colombier /* sysmenu */
483ff48bf5SDavid du Colombier #define M_COPY_CLIP 1
493ff48bf5SDavid du Colombier #define M_PASTE_CLIP 2
503ff48bf5SDavid du Colombier
513ff48bf5SDavid du Colombier LRESULT CALLBACK WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
523ff48bf5SDavid du Colombier static void text_error(char *message);
533ff48bf5SDavid du Colombier static void text_new_line(TW *tw);
543ff48bf5SDavid du Colombier static void text_update_text(TW *tw, int count);
553ff48bf5SDavid du Colombier static void text_drag_drop(TW *tw, HDROP hdrop);
563ff48bf5SDavid du Colombier static void text_copy_to_clipboard(TW *tw);
573ff48bf5SDavid du Colombier static void text_paste_from_clipboard(TW *tw);
583ff48bf5SDavid du Colombier
593ff48bf5SDavid du Colombier static const char* TextWinClassName = "rjlTextWinClass";
603ff48bf5SDavid du Colombier static const POINT TextWinMinSize = {16, 4};
613ff48bf5SDavid du Colombier
623ff48bf5SDavid du Colombier static void
text_error(char * message)633ff48bf5SDavid du Colombier text_error(char *message)
643ff48bf5SDavid du Colombier {
653ff48bf5SDavid du Colombier MessageBox((HWND)NULL,message,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
663ff48bf5SDavid du Colombier }
673ff48bf5SDavid du Colombier
683ff48bf5SDavid du Colombier /* Bring Cursor into text window */
693ff48bf5SDavid du Colombier void
text_to_cursor(TW * tw)703ff48bf5SDavid du Colombier text_to_cursor(TW *tw)
713ff48bf5SDavid du Colombier {
723ff48bf5SDavid du Colombier int nXinc=0;
733ff48bf5SDavid du Colombier int nYinc=0;
743ff48bf5SDavid du Colombier int cxCursor;
753ff48bf5SDavid du Colombier int cyCursor;
763ff48bf5SDavid du Colombier cyCursor = tw->CursorPos.y * tw->CharSize.y;
773ff48bf5SDavid du Colombier if ( (cyCursor + tw->CharSize.y > tw->ScrollPos.y + tw->ClientSize.y)
783ff48bf5SDavid du Colombier /* || (cyCursor < tw->ScrollPos.y) ) { */
793ff48bf5SDavid du Colombier /* change to scroll to end of window instead of just making visible */
803ff48bf5SDavid du Colombier /* so that ALL of error message can be seen */
813ff48bf5SDavid du Colombier || (cyCursor < tw->ScrollPos.y+tw->ClientSize.y) ) {
823ff48bf5SDavid du Colombier nYinc = max(0, cyCursor + tw->CharSize.y
833ff48bf5SDavid du Colombier - tw->ClientSize.y) - tw->ScrollPos.y;
843ff48bf5SDavid du Colombier nYinc = min(nYinc, tw->ScrollMax.y - tw->ScrollPos.y);
853ff48bf5SDavid du Colombier }
863ff48bf5SDavid du Colombier cxCursor = tw->CursorPos.x * tw->CharSize.x;
873ff48bf5SDavid du Colombier if ( (cxCursor + tw->CharSize.x > tw->ScrollPos.x + tw->ClientSize.x)
883ff48bf5SDavid du Colombier || (cxCursor < tw->ScrollPos.x) ) {
893ff48bf5SDavid du Colombier nXinc = max(0, cxCursor + tw->CharSize.x
903ff48bf5SDavid du Colombier - tw->ClientSize.x/2) - tw->ScrollPos.x;
913ff48bf5SDavid du Colombier nXinc = min(nXinc, tw->ScrollMax.x - tw->ScrollPos.x);
923ff48bf5SDavid du Colombier }
933ff48bf5SDavid du Colombier if (nYinc || nXinc) {
943ff48bf5SDavid du Colombier tw->ScrollPos.y += nYinc;
953ff48bf5SDavid du Colombier tw->ScrollPos.x += nXinc;
963ff48bf5SDavid du Colombier ScrollWindow(tw->hwnd,-nXinc,-nYinc,NULL,NULL);
973ff48bf5SDavid du Colombier SetScrollPos(tw->hwnd,SB_VERT,tw->ScrollPos.y,TRUE);
983ff48bf5SDavid du Colombier SetScrollPos(tw->hwnd,SB_HORZ,tw->ScrollPos.x,TRUE);
993ff48bf5SDavid du Colombier UpdateWindow(tw->hwnd);
1003ff48bf5SDavid du Colombier }
1013ff48bf5SDavid du Colombier }
1023ff48bf5SDavid du Colombier
1033ff48bf5SDavid du Colombier static void
text_new_line(TW * tw)1043ff48bf5SDavid du Colombier text_new_line(TW *tw)
1053ff48bf5SDavid du Colombier {
1063ff48bf5SDavid du Colombier tw->CursorPos.x = 0;
1073ff48bf5SDavid du Colombier tw->CursorPos.y++;
1083ff48bf5SDavid du Colombier if (tw->CursorPos.y >= tw->ScreenSize.y) {
1093ff48bf5SDavid du Colombier int i = tw->ScreenSize.x * (tw->ScreenSize.y - 1);
1103ff48bf5SDavid du Colombier memmove(tw->ScreenBuffer, tw->ScreenBuffer+tw->ScreenSize.x, i);
1113ff48bf5SDavid du Colombier memset(tw->ScreenBuffer + i, ' ', tw->ScreenSize.x);
1123ff48bf5SDavid du Colombier tw->CursorPos.y--;
1133ff48bf5SDavid du Colombier ScrollWindow(tw->hwnd,0,-tw->CharSize.y,NULL,NULL);
1143ff48bf5SDavid du Colombier UpdateWindow(tw->hwnd);
1153ff48bf5SDavid du Colombier }
1163ff48bf5SDavid du Colombier if (tw->CursorFlag)
1173ff48bf5SDavid du Colombier text_to_cursor(tw);
1183ff48bf5SDavid du Colombier
1193ff48bf5SDavid du Colombier /* TextMessage(); */
1203ff48bf5SDavid du Colombier }
1213ff48bf5SDavid du Colombier
1223ff48bf5SDavid du Colombier /* Update count characters in window at cursor position */
1233ff48bf5SDavid du Colombier /* Updates cursor position */
1243ff48bf5SDavid du Colombier static void
text_update_text(TW * tw,int count)1253ff48bf5SDavid du Colombier text_update_text(TW *tw, int count)
1263ff48bf5SDavid du Colombier {
1273ff48bf5SDavid du Colombier HDC hdc;
1283ff48bf5SDavid du Colombier int xpos, ypos;
1293ff48bf5SDavid du Colombier xpos = tw->CursorPos.x*tw->CharSize.x - tw->ScrollPos.x;
1303ff48bf5SDavid du Colombier ypos = tw->CursorPos.y*tw->CharSize.y - tw->ScrollPos.y;
1313ff48bf5SDavid du Colombier hdc = GetDC(tw->hwnd);
1323ff48bf5SDavid du Colombier SelectFont(hdc, tw->hfont);
1333ff48bf5SDavid du Colombier TextOut(hdc,xpos,ypos,
1343ff48bf5SDavid du Colombier (LPSTR)(tw->ScreenBuffer + tw->CursorPos.y*tw->ScreenSize.x
1353ff48bf5SDavid du Colombier + tw->CursorPos.x), count);
1363ff48bf5SDavid du Colombier (void)ReleaseDC(tw->hwnd,hdc);
1373ff48bf5SDavid du Colombier tw->CursorPos.x += count;
1383ff48bf5SDavid du Colombier if (tw->CursorPos.x >= tw->ScreenSize.x)
1393ff48bf5SDavid du Colombier text_new_line(tw);
1403ff48bf5SDavid du Colombier }
1413ff48bf5SDavid du Colombier
1423ff48bf5SDavid du Colombier
1433ff48bf5SDavid du Colombier void
text_size(TW * tw,int width,int height)1443ff48bf5SDavid du Colombier text_size(TW *tw, int width, int height)
1453ff48bf5SDavid du Colombier {
1463ff48bf5SDavid du Colombier tw->ScreenSize.x = max(width, TextWinMinSize.x);
1473ff48bf5SDavid du Colombier tw->ScreenSize.y = max(height, TextWinMinSize.y);
1483ff48bf5SDavid du Colombier }
1493ff48bf5SDavid du Colombier
1503ff48bf5SDavid du Colombier void
text_font(TW * tw,const char * name,int size)1513ff48bf5SDavid du Colombier text_font(TW *tw, const char *name, int size)
1523ff48bf5SDavid du Colombier {
1533ff48bf5SDavid du Colombier /* make a new font */
1543ff48bf5SDavid du Colombier LOGFONT lf;
1553ff48bf5SDavid du Colombier TEXTMETRIC tm;
1563ff48bf5SDavid du Colombier LPSTR p;
1573ff48bf5SDavid du Colombier HDC hdc;
1583ff48bf5SDavid du Colombier
1593ff48bf5SDavid du Colombier /* reject inappropriate arguments */
1603ff48bf5SDavid du Colombier if (name == NULL)
1613ff48bf5SDavid du Colombier return;
1623ff48bf5SDavid du Colombier if (size < 4)
1633ff48bf5SDavid du Colombier return;
1643ff48bf5SDavid du Colombier
1653ff48bf5SDavid du Colombier /* set new name and size */
1663ff48bf5SDavid du Colombier if (tw->fontname)
1673ff48bf5SDavid du Colombier free(tw->fontname);
1683ff48bf5SDavid du Colombier tw->fontname = (char *)malloc(strlen(name)+1);
1693ff48bf5SDavid du Colombier if (tw->fontname == NULL)
1703ff48bf5SDavid du Colombier return;
1713ff48bf5SDavid du Colombier strcpy(tw->fontname, name);
1723ff48bf5SDavid du Colombier tw->fontsize = size;
1733ff48bf5SDavid du Colombier
1743ff48bf5SDavid du Colombier /* if window not open, hwnd == 0 == HWND_DESKTOP */
1753ff48bf5SDavid du Colombier hdc = GetDC(tw->hwnd);
1763ff48bf5SDavid du Colombier memset(&lf, 0, sizeof(LOGFONT));
1773ff48bf5SDavid du Colombier strncpy(lf.lfFaceName,tw->fontname,LF_FACESIZE);
1783ff48bf5SDavid du Colombier lf.lfHeight = -MulDiv(tw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
1793ff48bf5SDavid du Colombier lf.lfPitchAndFamily = FIXED_PITCH;
1803ff48bf5SDavid du Colombier lf.lfCharSet = DEFAULT_CHARSET;
1813ff48bf5SDavid du Colombier if ( (p = strstr(tw->fontname," Italic")) != (LPSTR)NULL ) {
1823ff48bf5SDavid du Colombier lf.lfFaceName[ (unsigned int)(p-tw->fontname) ] = '\0';
1833ff48bf5SDavid du Colombier lf.lfItalic = TRUE;
1843ff48bf5SDavid du Colombier }
1853ff48bf5SDavid du Colombier if ( (p = strstr(tw->fontname," Bold")) != (LPSTR)NULL ) {
1863ff48bf5SDavid du Colombier lf.lfFaceName[ (unsigned int)(p-tw->fontname) ] = '\0';
1873ff48bf5SDavid du Colombier lf.lfWeight = FW_BOLD;
1883ff48bf5SDavid du Colombier }
1893ff48bf5SDavid du Colombier if (tw->hfont)
1903ff48bf5SDavid du Colombier DeleteFont(tw->hfont);
1913ff48bf5SDavid du Colombier
1923ff48bf5SDavid du Colombier tw->hfont = CreateFontIndirect((LOGFONT FAR *)&lf);
1933ff48bf5SDavid du Colombier
1943ff48bf5SDavid du Colombier /* get text size */
1953ff48bf5SDavid du Colombier SelectFont(hdc, tw->hfont);
1963ff48bf5SDavid du Colombier GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
1973ff48bf5SDavid du Colombier tw->CharSize.y = tm.tmHeight;
1983ff48bf5SDavid du Colombier tw->CharSize.x = tm.tmAveCharWidth;
1993ff48bf5SDavid du Colombier tw->CharAscent = tm.tmAscent;
2003ff48bf5SDavid du Colombier if (tw->bFocus)
2013ff48bf5SDavid du Colombier CreateCaret(tw->hwnd, 0, tw->CharSize.x, 2+tw->CaretHeight);
2023ff48bf5SDavid du Colombier ReleaseDC(tw->hwnd, hdc);
2033ff48bf5SDavid du Colombier
2043ff48bf5SDavid du Colombier /* redraw window if necessary */
2053ff48bf5SDavid du Colombier if (tw->hwnd != HWND_DESKTOP) {
2063ff48bf5SDavid du Colombier /* INCOMPLETE */
2073ff48bf5SDavid du Colombier }
2083ff48bf5SDavid du Colombier }
2093ff48bf5SDavid du Colombier
2103ff48bf5SDavid du Colombier
2113ff48bf5SDavid du Colombier
2123ff48bf5SDavid du Colombier /* Set drag strings */
2133ff48bf5SDavid du Colombier void
text_drag(TW * tw,const char * pre,const char * post)2143ff48bf5SDavid du Colombier text_drag(TW *tw, const char *pre, const char *post)
2153ff48bf5SDavid du Colombier {
2163ff48bf5SDavid du Colombier /* remove old strings */
2173ff48bf5SDavid du Colombier if (tw->DragPre)
2183ff48bf5SDavid du Colombier free((char *)tw->DragPre);
2193ff48bf5SDavid du Colombier tw->DragPre = NULL;
2203ff48bf5SDavid du Colombier if (tw->DragPost)
2213ff48bf5SDavid du Colombier free((char *)tw->DragPost);
2223ff48bf5SDavid du Colombier tw->DragPost = NULL;
2233ff48bf5SDavid du Colombier
2243ff48bf5SDavid du Colombier /* add new strings */
2253ff48bf5SDavid du Colombier tw->DragPre = malloc(strlen(pre)+1);
2263ff48bf5SDavid du Colombier if (tw->DragPre)
2273ff48bf5SDavid du Colombier strcpy(tw->DragPre, pre);
2283ff48bf5SDavid du Colombier tw->DragPost = malloc(strlen(post)+1);
2293ff48bf5SDavid du Colombier if (tw->DragPost)
2303ff48bf5SDavid du Colombier strcpy(tw->DragPost, post);
2313ff48bf5SDavid du Colombier }
2323ff48bf5SDavid du Colombier
2333ff48bf5SDavid du Colombier /* Set the window position and size */
2343ff48bf5SDavid du Colombier void
text_setpos(TW * tw,int x,int y,int cx,int cy)2353ff48bf5SDavid du Colombier text_setpos(TW *tw, int x, int y, int cx, int cy)
2363ff48bf5SDavid du Colombier {
2373ff48bf5SDavid du Colombier tw->x = x;
2383ff48bf5SDavid du Colombier tw->y = y;
2393ff48bf5SDavid du Colombier tw->cx = cx;
2403ff48bf5SDavid du Colombier tw->cy = cy;
2413ff48bf5SDavid du Colombier }
2423ff48bf5SDavid du Colombier
2433ff48bf5SDavid du Colombier /* Get the window position and size */
text_getpos(TW * tw,int * px,int * py,int * pcx,int * pcy)2443ff48bf5SDavid du Colombier int text_getpos(TW *tw, int *px, int *py, int *pcx, int *pcy)
2453ff48bf5SDavid du Colombier {
2463ff48bf5SDavid du Colombier *px = tw->x;
2473ff48bf5SDavid du Colombier *py = tw->y;
2483ff48bf5SDavid du Colombier *pcx = tw->cx;
2493ff48bf5SDavid du Colombier *pcy = tw->cy;
2503ff48bf5SDavid du Colombier return 0;
2513ff48bf5SDavid du Colombier }
2523ff48bf5SDavid du Colombier
2533ff48bf5SDavid du Colombier /* Allocate new text window */
2543ff48bf5SDavid du Colombier TW *
text_new(void)2553ff48bf5SDavid du Colombier text_new(void)
2563ff48bf5SDavid du Colombier {
2573ff48bf5SDavid du Colombier TW *tw;
2583ff48bf5SDavid du Colombier tw = (TW *)malloc(sizeof(TW));
2593ff48bf5SDavid du Colombier if (tw == NULL)
2603ff48bf5SDavid du Colombier return NULL;
2613ff48bf5SDavid du Colombier /* make sure everything is null */
2623ff48bf5SDavid du Colombier memset(tw, 0, sizeof(TW));
2633ff48bf5SDavid du Colombier
2643ff48bf5SDavid du Colombier /* set some defaults */
2653ff48bf5SDavid du Colombier text_font(tw, "Courier New", 10);
2663ff48bf5SDavid du Colombier text_size(tw, 80, 24);
2673ff48bf5SDavid du Colombier tw->KeyBufSize = 2048;
2683ff48bf5SDavid du Colombier tw->CursorFlag = 1; /* scroll to cursor after \n or \r */
2693ff48bf5SDavid du Colombier tw->hwnd = HWND_DESKTOP;
2703ff48bf5SDavid du Colombier
2713ff48bf5SDavid du Colombier tw->line_end = 0;
2723ff48bf5SDavid du Colombier tw->line_start = 0;
2733ff48bf5SDavid du Colombier tw->line_complete = FALSE;
2743ff48bf5SDavid du Colombier tw->line_eof = FALSE;
2753ff48bf5SDavid du Colombier
2763ff48bf5SDavid du Colombier tw->x = CW_USEDEFAULT;
2773ff48bf5SDavid du Colombier tw->y = CW_USEDEFAULT;
2783ff48bf5SDavid du Colombier tw->cx = CW_USEDEFAULT;
2793ff48bf5SDavid du Colombier tw->cy = CW_USEDEFAULT;
2803ff48bf5SDavid du Colombier return tw;
2813ff48bf5SDavid du Colombier }
2823ff48bf5SDavid du Colombier
2833ff48bf5SDavid du Colombier /* Destroy window and deallocate text window structure */
2843ff48bf5SDavid du Colombier void
text_destroy(TW * tw)2853ff48bf5SDavid du Colombier text_destroy(TW *tw)
2863ff48bf5SDavid du Colombier {
2873ff48bf5SDavid du Colombier if (tw->hwnd)
2883ff48bf5SDavid du Colombier DestroyWindow(tw->hwnd);
2893ff48bf5SDavid du Colombier tw->hwnd = HWND_DESKTOP;
2903ff48bf5SDavid du Colombier
2913ff48bf5SDavid du Colombier if (tw->hfont)
2923ff48bf5SDavid du Colombier DeleteFont(tw->hfont);
2933ff48bf5SDavid du Colombier tw->hfont = NULL;
2943ff48bf5SDavid du Colombier
2953ff48bf5SDavid du Colombier if (tw->KeyBuf)
2963ff48bf5SDavid du Colombier free((char *)tw->KeyBuf);
2973ff48bf5SDavid du Colombier tw->KeyBuf = NULL;
2983ff48bf5SDavid du Colombier
2993ff48bf5SDavid du Colombier if (tw->ScreenBuffer)
3003ff48bf5SDavid du Colombier free((char *)tw->ScreenBuffer);
3013ff48bf5SDavid du Colombier tw->ScreenBuffer = NULL;
3023ff48bf5SDavid du Colombier
3033ff48bf5SDavid du Colombier if (tw->DragPre)
3043ff48bf5SDavid du Colombier free((char *)tw->DragPre);
3053ff48bf5SDavid du Colombier tw->DragPre = NULL;
3063ff48bf5SDavid du Colombier
3073ff48bf5SDavid du Colombier if (tw->DragPost)
3083ff48bf5SDavid du Colombier free((char *)tw->DragPost);
3093ff48bf5SDavid du Colombier tw->DragPost = NULL;
3103ff48bf5SDavid du Colombier
3113ff48bf5SDavid du Colombier if (tw->fontname)
3123ff48bf5SDavid du Colombier free((char *)tw->fontname);
3133ff48bf5SDavid du Colombier tw->fontname = NULL;
3143ff48bf5SDavid du Colombier }
3153ff48bf5SDavid du Colombier
3163ff48bf5SDavid du Colombier
3173ff48bf5SDavid du Colombier /* register the window class */
3183ff48bf5SDavid du Colombier int
text_register_class(TW * tw,HICON hicon)3193ff48bf5SDavid du Colombier text_register_class(TW *tw, HICON hicon)
3203ff48bf5SDavid du Colombier {
3213ff48bf5SDavid du Colombier WNDCLASS wndclass;
3223ff48bf5SDavid du Colombier HINSTANCE hInstance = GetModuleHandle(NULL);
3233ff48bf5SDavid du Colombier tw->hIcon = hicon;
3243ff48bf5SDavid du Colombier
3253ff48bf5SDavid du Colombier /* register window class */
3263ff48bf5SDavid du Colombier wndclass.style = CS_HREDRAW | CS_VREDRAW;
3273ff48bf5SDavid du Colombier wndclass.lpfnWndProc = WndTextProc;
3283ff48bf5SDavid du Colombier wndclass.cbClsExtra = 0;
3293ff48bf5SDavid du Colombier wndclass.cbWndExtra = sizeof(void *);
3303ff48bf5SDavid du Colombier wndclass.hInstance = hInstance;
3313ff48bf5SDavid du Colombier wndclass.hIcon = tw->hIcon ? tw->hIcon : LoadIcon(NULL, IDI_APPLICATION);
3323ff48bf5SDavid du Colombier wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
3333ff48bf5SDavid du Colombier wndclass.hbrBackground = GetStockBrush(WHITE_BRUSH);
3343ff48bf5SDavid du Colombier wndclass.lpszMenuName = NULL;
3353ff48bf5SDavid du Colombier wndclass.lpszClassName = TextWinClassName;
3363ff48bf5SDavid du Colombier return RegisterClass(&wndclass);
3373ff48bf5SDavid du Colombier }
3383ff48bf5SDavid du Colombier
3393ff48bf5SDavid du Colombier /* Show the window */
3403ff48bf5SDavid du Colombier int
text_create(TW * tw,const char * app_name,int show_cmd)3413ff48bf5SDavid du Colombier text_create(TW *tw, const char *app_name, int show_cmd)
3423ff48bf5SDavid du Colombier {
3433ff48bf5SDavid du Colombier HMENU sysmenu;
3443ff48bf5SDavid du Colombier HINSTANCE hInstance = GetModuleHandle(NULL);
3453ff48bf5SDavid du Colombier
3463ff48bf5SDavid du Colombier tw->Title = app_name;
3473ff48bf5SDavid du Colombier tw->nCmdShow = show_cmd;
3483ff48bf5SDavid du Colombier tw->quitnow = FALSE;
3493ff48bf5SDavid du Colombier
3503ff48bf5SDavid du Colombier /* make sure we have some sensible defaults */
3513ff48bf5SDavid du Colombier if (tw->KeyBufSize < 256)
3523ff48bf5SDavid du Colombier tw->KeyBufSize = 256;
3533ff48bf5SDavid du Colombier
3543ff48bf5SDavid du Colombier tw->CursorPos.x = tw->CursorPos.y = 0;
3553ff48bf5SDavid du Colombier tw->bFocus = FALSE;
3563ff48bf5SDavid du Colombier tw->bGetCh = FALSE;
3573ff48bf5SDavid du Colombier tw->CaretHeight = 0;
3583ff48bf5SDavid du Colombier
3593ff48bf5SDavid du Colombier
3603ff48bf5SDavid du Colombier /* allocate buffers */
3613ff48bf5SDavid du Colombier tw->KeyBufIn = tw->KeyBufOut = tw->KeyBuf = malloc(tw->KeyBufSize);
3623ff48bf5SDavid du Colombier if (tw->KeyBuf == NULL) {
3633ff48bf5SDavid du Colombier text_error("Out of memory");
3643ff48bf5SDavid du Colombier return 1;
3653ff48bf5SDavid du Colombier }
3663ff48bf5SDavid du Colombier tw->ScreenBuffer = malloc(tw->ScreenSize.x * tw->ScreenSize.y);
3673ff48bf5SDavid du Colombier if (tw->ScreenBuffer == NULL) {
3683ff48bf5SDavid du Colombier text_error("Out of memory");
3693ff48bf5SDavid du Colombier return 1;
3703ff48bf5SDavid du Colombier }
3713ff48bf5SDavid du Colombier memset(tw->ScreenBuffer, ' ', tw->ScreenSize.x * tw->ScreenSize.y);
3723ff48bf5SDavid du Colombier
3733ff48bf5SDavid du Colombier tw->hwnd = CreateWindow(TextWinClassName, tw->Title,
3743ff48bf5SDavid du Colombier WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
3753ff48bf5SDavid du Colombier tw->x, tw->y, tw->cx, tw->cy,
3763ff48bf5SDavid du Colombier NULL, NULL, hInstance, tw);
3773ff48bf5SDavid du Colombier
3783ff48bf5SDavid du Colombier if (tw->hwnd == NULL) {
3793ff48bf5SDavid du Colombier MessageBox((HWND)NULL,"Couldn't open text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
3803ff48bf5SDavid du Colombier return 1;
3813ff48bf5SDavid du Colombier }
3823ff48bf5SDavid du Colombier
3833ff48bf5SDavid du Colombier ShowWindow(tw->hwnd, tw->nCmdShow);
3843ff48bf5SDavid du Colombier sysmenu = GetSystemMenu(tw->hwnd,0); /* get the sysmenu */
3853ff48bf5SDavid du Colombier AppendMenu(sysmenu, MF_SEPARATOR, 0, NULL);
3863ff48bf5SDavid du Colombier AppendMenu(sysmenu, MF_STRING, M_COPY_CLIP, "Copy to Clip&board");
3873ff48bf5SDavid du Colombier AppendMenu(sysmenu, MF_STRING, M_PASTE_CLIP, "&Paste");
3883ff48bf5SDavid du Colombier
3893ff48bf5SDavid du Colombier return 0;
3903ff48bf5SDavid du Colombier }
3913ff48bf5SDavid du Colombier
3923ff48bf5SDavid du Colombier
3933ff48bf5SDavid du Colombier int
text_putch(TW * tw,int ch)3943ff48bf5SDavid du Colombier text_putch(TW *tw, int ch)
3953ff48bf5SDavid du Colombier {
3963ff48bf5SDavid du Colombier int pos;
3973ff48bf5SDavid du Colombier int n;
3983ff48bf5SDavid du Colombier if (tw->quitnow)
3993ff48bf5SDavid du Colombier return ch; /* don't write error message as we shut down */
4003ff48bf5SDavid du Colombier switch(ch) {
4013ff48bf5SDavid du Colombier case '\r':
4023ff48bf5SDavid du Colombier tw->CursorPos.x = 0;
4033ff48bf5SDavid du Colombier if (tw->CursorFlag)
4043ff48bf5SDavid du Colombier text_to_cursor(tw);
4053ff48bf5SDavid du Colombier break;
4063ff48bf5SDavid du Colombier case '\n':
4073ff48bf5SDavid du Colombier text_new_line(tw);
4083ff48bf5SDavid du Colombier break;
4093ff48bf5SDavid du Colombier case 7:
4103ff48bf5SDavid du Colombier MessageBeep(-1);
4113ff48bf5SDavid du Colombier if (tw->CursorFlag)
4123ff48bf5SDavid du Colombier text_to_cursor(tw);
4133ff48bf5SDavid du Colombier break;
4143ff48bf5SDavid du Colombier case '\t':
4153ff48bf5SDavid du Colombier {
4163ff48bf5SDavid du Colombier for (n = 8 - (tw->CursorPos.x % 8); n>0; n-- )
4173ff48bf5SDavid du Colombier text_putch(tw, ' ');
4183ff48bf5SDavid du Colombier }
4193ff48bf5SDavid du Colombier break;
4203ff48bf5SDavid du Colombier case 0x08:
4213ff48bf5SDavid du Colombier case 0x7f:
4223ff48bf5SDavid du Colombier tw->CursorPos.x--;
4233ff48bf5SDavid du Colombier if (tw->CursorPos.x < 0) {
4243ff48bf5SDavid du Colombier tw->CursorPos.x = tw->ScreenSize.x - 1;
4253ff48bf5SDavid du Colombier tw->CursorPos.y--;
4263ff48bf5SDavid du Colombier }
4273ff48bf5SDavid du Colombier if (tw->CursorPos.y < 0)
4283ff48bf5SDavid du Colombier tw->CursorPos.y = 0;
4293ff48bf5SDavid du Colombier break;
4303ff48bf5SDavid du Colombier default:
4313ff48bf5SDavid du Colombier pos = tw->CursorPos.y*tw->ScreenSize.x + tw->CursorPos.x;
4323ff48bf5SDavid du Colombier tw->ScreenBuffer[pos] = ch;
4333ff48bf5SDavid du Colombier text_update_text(tw, 1);
4343ff48bf5SDavid du Colombier }
4353ff48bf5SDavid du Colombier return ch;
4363ff48bf5SDavid du Colombier }
4373ff48bf5SDavid du Colombier
4383ff48bf5SDavid du Colombier void
text_write_buf(TW * tw,const char * str,int cnt)4393ff48bf5SDavid du Colombier text_write_buf(TW *tw, const char *str, int cnt)
4403ff48bf5SDavid du Colombier {
4413ff48bf5SDavid du Colombier BYTE *p;
4423ff48bf5SDavid du Colombier int count, limit;
4433ff48bf5SDavid du Colombier int n;
4443ff48bf5SDavid du Colombier if (tw->quitnow)
4453ff48bf5SDavid du Colombier return; /* don't write error message as we shut down */
4463ff48bf5SDavid du Colombier while (cnt>0) {
4473ff48bf5SDavid du Colombier p = tw->ScreenBuffer + tw->CursorPos.y*tw->ScreenSize.x + tw->CursorPos.x;
4483ff48bf5SDavid du Colombier limit = tw->ScreenSize.x - tw->CursorPos.x;
449*593dc095SDavid du Colombier for (count=0; (count < limit) && (cnt>0) &&
450*593dc095SDavid du Colombier (isprint((unsigned char)(*str)) || *str=='\t'); count++) {
4513ff48bf5SDavid du Colombier if (*str=='\t') {
4523ff48bf5SDavid du Colombier for (n = 8 - ((tw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ )
4533ff48bf5SDavid du Colombier *p++ = ' ';
4543ff48bf5SDavid du Colombier str++;
4553ff48bf5SDavid du Colombier count--;
4563ff48bf5SDavid du Colombier }
4573ff48bf5SDavid du Colombier else {
4583ff48bf5SDavid du Colombier *p++ = *str++;
4593ff48bf5SDavid du Colombier }
4603ff48bf5SDavid du Colombier cnt--;
4613ff48bf5SDavid du Colombier }
4623ff48bf5SDavid du Colombier if (count>0) {
4633ff48bf5SDavid du Colombier text_update_text(tw, count);
4643ff48bf5SDavid du Colombier }
4653ff48bf5SDavid du Colombier if (cnt > 0) {
4663ff48bf5SDavid du Colombier if (*str=='\n') {
4673ff48bf5SDavid du Colombier text_new_line(tw);
4683ff48bf5SDavid du Colombier str++;
4693ff48bf5SDavid du Colombier cnt--;
4703ff48bf5SDavid du Colombier }
471*593dc095SDavid du Colombier else if (!isprint((unsigned char)(*str)) && *str!='\t') {
4723ff48bf5SDavid du Colombier text_putch(tw, *str++);
4733ff48bf5SDavid du Colombier cnt--;
4743ff48bf5SDavid du Colombier }
4753ff48bf5SDavid du Colombier }
4763ff48bf5SDavid du Colombier }
4773ff48bf5SDavid du Colombier }
4783ff48bf5SDavid du Colombier
4793ff48bf5SDavid du Colombier /* Put string to window */
4803ff48bf5SDavid du Colombier void
text_puts(TW * tw,const char * str)4813ff48bf5SDavid du Colombier text_puts(TW *tw, const char *str)
4823ff48bf5SDavid du Colombier {
4833ff48bf5SDavid du Colombier text_write_buf(tw, str, strlen(str));
4843ff48bf5SDavid du Colombier }
4853ff48bf5SDavid du Colombier
4863ff48bf5SDavid du Colombier
4873ff48bf5SDavid du Colombier /* TRUE if key hit, FALSE if no key */
4883ff48bf5SDavid du Colombier int
text_kbhit(TW * tw)4893ff48bf5SDavid du Colombier text_kbhit(TW *tw)
4903ff48bf5SDavid du Colombier {
4913ff48bf5SDavid du Colombier return (tw->KeyBufIn != tw->KeyBufOut);
4923ff48bf5SDavid du Colombier }
4933ff48bf5SDavid du Colombier
4943ff48bf5SDavid du Colombier /* get character from keyboard, no echo */
4953ff48bf5SDavid du Colombier /* need to add extended codes */
4963ff48bf5SDavid du Colombier int
text_getch(TW * tw)4973ff48bf5SDavid du Colombier text_getch(TW *tw)
4983ff48bf5SDavid du Colombier {
4993ff48bf5SDavid du Colombier MSG msg;
5003ff48bf5SDavid du Colombier int ch;
5013ff48bf5SDavid du Colombier text_to_cursor(tw);
5023ff48bf5SDavid du Colombier tw->bGetCh = TRUE;
5033ff48bf5SDavid du Colombier if (tw->bFocus) {
5043ff48bf5SDavid du Colombier SetCaretPos(tw->CursorPos.x*tw->CharSize.x - tw->ScrollPos.x,
5053ff48bf5SDavid du Colombier tw->CursorPos.y*tw->CharSize.y + tw->CharAscent
5063ff48bf5SDavid du Colombier - tw->CaretHeight - tw->ScrollPos.y);
5073ff48bf5SDavid du Colombier ShowCaret(tw->hwnd);
5083ff48bf5SDavid du Colombier }
5093ff48bf5SDavid du Colombier
5103ff48bf5SDavid du Colombier while (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_NOREMOVE)) {
5113ff48bf5SDavid du Colombier if (GetMessage(&msg, (HWND)NULL, 0, 0)) {
5123ff48bf5SDavid du Colombier TranslateMessage(&msg);
5133ff48bf5SDavid du Colombier DispatchMessage(&msg);
5143ff48bf5SDavid du Colombier }
5153ff48bf5SDavid du Colombier }
5163ff48bf5SDavid du Colombier if (tw->quitnow)
5173ff48bf5SDavid du Colombier return EOF; /* window closed */
5183ff48bf5SDavid du Colombier
5193ff48bf5SDavid du Colombier while (!text_kbhit(tw)) {
5203ff48bf5SDavid du Colombier if (!tw->quitnow) {
5213ff48bf5SDavid du Colombier if (GetMessage(&msg, (HWND)NULL, 0, 0)) {
5223ff48bf5SDavid du Colombier TranslateMessage(&msg);
5233ff48bf5SDavid du Colombier DispatchMessage(&msg);
5243ff48bf5SDavid du Colombier }
5253ff48bf5SDavid du Colombier }
5263ff48bf5SDavid du Colombier else
5273ff48bf5SDavid du Colombier return EOF; /* window closed */
5283ff48bf5SDavid du Colombier }
5293ff48bf5SDavid du Colombier
5303ff48bf5SDavid du Colombier ch = *tw->KeyBufOut++;
5313ff48bf5SDavid du Colombier if (ch=='\r')
5323ff48bf5SDavid du Colombier ch = '\n';
5333ff48bf5SDavid du Colombier if (tw->KeyBufOut - tw->KeyBuf >= tw->KeyBufSize)
5343ff48bf5SDavid du Colombier tw->KeyBufOut = tw->KeyBuf; /* wrap around */
5353ff48bf5SDavid du Colombier if (tw->bFocus)
5363ff48bf5SDavid du Colombier HideCaret(tw->hwnd);
5373ff48bf5SDavid du Colombier tw->bGetCh = FALSE;
5383ff48bf5SDavid du Colombier return ch;
5393ff48bf5SDavid du Colombier }
5403ff48bf5SDavid du Colombier
5413ff48bf5SDavid du Colombier /* Read line from keyboard using buffered input
5423ff48bf5SDavid du Colombier * Return at most 'len' characters
5433ff48bf5SDavid du Colombier * Does NOT add null terminating character
5443ff48bf5SDavid du Colombier * This is NOT the same as fgets()
5453ff48bf5SDavid du Colombier * Do not mix this with calls to text_getch()
5463ff48bf5SDavid du Colombier */
5473ff48bf5SDavid du Colombier int
text_read_line(TW * tw,char * line,int len)5483ff48bf5SDavid du Colombier text_read_line(TW *tw, char *line, int len)
5493ff48bf5SDavid du Colombier {
5503ff48bf5SDavid du Colombier int ch;
5513ff48bf5SDavid du Colombier if (tw->line_eof)
5523ff48bf5SDavid du Colombier return 0;
5533ff48bf5SDavid du Colombier
5543ff48bf5SDavid du Colombier while (!tw->line_complete) {
5553ff48bf5SDavid du Colombier /* we have not yet collected a full line */
5563ff48bf5SDavid du Colombier ch = text_getch(tw);
5573ff48bf5SDavid du Colombier switch(ch) {
5583ff48bf5SDavid du Colombier case EOF:
5593ff48bf5SDavid du Colombier case 26: /* ^Z == EOF */
5603ff48bf5SDavid du Colombier tw->line_eof = TRUE;
5613ff48bf5SDavid du Colombier tw->line_complete = TRUE;
5623ff48bf5SDavid du Colombier break;
5633ff48bf5SDavid du Colombier case '\b': /* ^H */
5643ff48bf5SDavid du Colombier case 0x7f: /* DEL */
5653ff48bf5SDavid du Colombier if (tw->line_end) {
5663ff48bf5SDavid du Colombier text_putch(tw, '\b');
5673ff48bf5SDavid du Colombier text_putch(tw, ' ');
5683ff48bf5SDavid du Colombier text_putch(tw, '\b');
5693ff48bf5SDavid du Colombier --(tw->line_end);
5703ff48bf5SDavid du Colombier }
5713ff48bf5SDavid du Colombier break;
5723ff48bf5SDavid du Colombier case 21: /* ^U */
5733ff48bf5SDavid du Colombier while (tw->line_end) {
5743ff48bf5SDavid du Colombier text_putch(tw, '\b');
5753ff48bf5SDavid du Colombier text_putch(tw, ' ');
5763ff48bf5SDavid du Colombier text_putch(tw, '\b');
5773ff48bf5SDavid du Colombier --(tw->line_end);
5783ff48bf5SDavid du Colombier }
5793ff48bf5SDavid du Colombier break;
5803ff48bf5SDavid du Colombier case '\r':
5813ff48bf5SDavid du Colombier case '\n':
5823ff48bf5SDavid du Colombier tw->line_complete = TRUE;
5833ff48bf5SDavid du Colombier /* fall through */
5843ff48bf5SDavid du Colombier default:
5853ff48bf5SDavid du Colombier tw->line_buf[tw->line_end++] = ch;
5863ff48bf5SDavid du Colombier text_putch(tw, ch);
5873ff48bf5SDavid du Colombier break;
5883ff48bf5SDavid du Colombier }
5893ff48bf5SDavid du Colombier if (tw->line_end >= sizeof(tw->line_buf))
5903ff48bf5SDavid du Colombier tw->line_complete = TRUE;
5913ff48bf5SDavid du Colombier }
5923ff48bf5SDavid du Colombier
5933ff48bf5SDavid du Colombier if (tw->quitnow)
5943ff48bf5SDavid du Colombier return -1;
5953ff48bf5SDavid du Colombier
5963ff48bf5SDavid du Colombier if (tw->line_complete) {
5973ff48bf5SDavid du Colombier /* We either filled the buffer or got CR, LF or EOF */
5983ff48bf5SDavid du Colombier int count = min(len, tw->line_end - tw->line_start);
5993ff48bf5SDavid du Colombier memcpy(line, tw->line_buf + tw->line_start, count);
6003ff48bf5SDavid du Colombier tw->line_start += count;
6013ff48bf5SDavid du Colombier if (tw->line_start == tw->line_end) {
6023ff48bf5SDavid du Colombier tw->line_start = tw->line_end = 0;
6033ff48bf5SDavid du Colombier tw->line_complete = FALSE;
6043ff48bf5SDavid du Colombier }
6053ff48bf5SDavid du Colombier return count;
6063ff48bf5SDavid du Colombier }
6073ff48bf5SDavid du Colombier
6083ff48bf5SDavid du Colombier return 0;
6093ff48bf5SDavid du Colombier }
6103ff48bf5SDavid du Colombier
6113ff48bf5SDavid du Colombier /* Read a string from the keyboard, of up to len characters */
6123ff48bf5SDavid du Colombier /* (not including trailing NULL) */
6133ff48bf5SDavid du Colombier int
text_gets(TW * tw,char * line,int len)6143ff48bf5SDavid du Colombier text_gets(TW *tw, char *line, int len)
6153ff48bf5SDavid du Colombier {
6163ff48bf5SDavid du Colombier LPSTR dest = line;
6173ff48bf5SDavid du Colombier LPSTR limit = dest + len; /* don't leave room for '\0' */
6183ff48bf5SDavid du Colombier int ch;
6193ff48bf5SDavid du Colombier do {
6203ff48bf5SDavid du Colombier if (dest >= limit)
6213ff48bf5SDavid du Colombier break;
6223ff48bf5SDavid du Colombier ch = text_getch(tw);
6233ff48bf5SDavid du Colombier switch(ch) {
6243ff48bf5SDavid du Colombier case 26: /* ^Z == EOF */
6253ff48bf5SDavid du Colombier return 0;
6263ff48bf5SDavid du Colombier case '\b': /* ^H */
6273ff48bf5SDavid du Colombier case 0x7f: /* DEL */
6283ff48bf5SDavid du Colombier if (dest > line) {
6293ff48bf5SDavid du Colombier text_putch(tw, '\b');
6303ff48bf5SDavid du Colombier text_putch(tw, ' ');
6313ff48bf5SDavid du Colombier text_putch(tw, '\b');
6323ff48bf5SDavid du Colombier --dest;
6333ff48bf5SDavid du Colombier }
6343ff48bf5SDavid du Colombier break;
6353ff48bf5SDavid du Colombier case 21: /* ^U */
6363ff48bf5SDavid du Colombier while (dest > line) {
6373ff48bf5SDavid du Colombier text_putch(tw, '\b');
6383ff48bf5SDavid du Colombier text_putch(tw, ' ');
6393ff48bf5SDavid du Colombier text_putch(tw, '\b');
6403ff48bf5SDavid du Colombier --dest;
6413ff48bf5SDavid du Colombier }
6423ff48bf5SDavid du Colombier break;
6433ff48bf5SDavid du Colombier default:
6443ff48bf5SDavid du Colombier *dest++ = ch;
6453ff48bf5SDavid du Colombier text_putch(tw, ch);
6463ff48bf5SDavid du Colombier break;
6473ff48bf5SDavid du Colombier }
6483ff48bf5SDavid du Colombier } while (ch != '\n');
6493ff48bf5SDavid du Colombier
6503ff48bf5SDavid du Colombier *dest = '\0';
6513ff48bf5SDavid du Colombier return (dest-line);
6523ff48bf5SDavid du Colombier }
6533ff48bf5SDavid du Colombier
6543ff48bf5SDavid du Colombier
6553ff48bf5SDavid du Colombier /* Windows 3.1 drag-drop feature */
6563ff48bf5SDavid du Colombier void
text_drag_drop(TW * tw,HDROP hdrop)6573ff48bf5SDavid du Colombier text_drag_drop(TW *tw, HDROP hdrop)
6583ff48bf5SDavid du Colombier {
6593ff48bf5SDavid du Colombier char szFile[256];
6603ff48bf5SDavid du Colombier int i, cFiles;
6613ff48bf5SDavid du Colombier const char *p;
6623ff48bf5SDavid du Colombier if ( (tw->DragPre==NULL) || (tw->DragPost==NULL) )
6633ff48bf5SDavid du Colombier return;
6643ff48bf5SDavid du Colombier
6653ff48bf5SDavid du Colombier cFiles = DragQueryFile(hdrop, (UINT)(-1), (LPSTR)NULL, 0);
6663ff48bf5SDavid du Colombier for (i=0; i<cFiles; i++) {
6673ff48bf5SDavid du Colombier DragQueryFile(hdrop, i, szFile, 80);
6683ff48bf5SDavid du Colombier for (p=tw->DragPre; *p; p++)
6693ff48bf5SDavid du Colombier SendMessage(tw->hwnd,WM_CHAR,*p,1L);
6703ff48bf5SDavid du Colombier for (p=szFile; *p; p++) {
6713ff48bf5SDavid du Colombier if (*p == '\\')
6723ff48bf5SDavid du Colombier SendMessage(tw->hwnd,WM_CHAR,'/',1L);
6733ff48bf5SDavid du Colombier else
6743ff48bf5SDavid du Colombier SendMessage(tw->hwnd,WM_CHAR,*p,1L);
6753ff48bf5SDavid du Colombier }
6763ff48bf5SDavid du Colombier for (p=tw->DragPost; *p; p++)
6773ff48bf5SDavid du Colombier SendMessage(tw->hwnd,WM_CHAR,*p,1L);
6783ff48bf5SDavid du Colombier }
6793ff48bf5SDavid du Colombier DragFinish(hdrop);
6803ff48bf5SDavid du Colombier }
6813ff48bf5SDavid du Colombier
6823ff48bf5SDavid du Colombier
6833ff48bf5SDavid du Colombier void
text_copy_to_clipboard(TW * tw)6843ff48bf5SDavid du Colombier text_copy_to_clipboard(TW *tw)
6853ff48bf5SDavid du Colombier {
6863ff48bf5SDavid du Colombier int size, count;
6873ff48bf5SDavid du Colombier HGLOBAL hGMem;
6883ff48bf5SDavid du Colombier LPSTR cbuf, cp;
6893ff48bf5SDavid du Colombier TEXTMETRIC tm;
6903ff48bf5SDavid du Colombier UINT type;
6913ff48bf5SDavid du Colombier HDC hdc;
6923ff48bf5SDavid du Colombier int i;
6933ff48bf5SDavid du Colombier
6943ff48bf5SDavid du Colombier size = tw->ScreenSize.y * (tw->ScreenSize.x + 2) + 1;
6953ff48bf5SDavid du Colombier hGMem = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)size);
6963ff48bf5SDavid du Colombier cbuf = cp = (LPSTR)GlobalLock(hGMem);
6973ff48bf5SDavid du Colombier if (cp == (LPSTR)NULL)
6983ff48bf5SDavid du Colombier return;
6993ff48bf5SDavid du Colombier
7003ff48bf5SDavid du Colombier for (i=0; i<tw->ScreenSize.y; i++) {
7013ff48bf5SDavid du Colombier count = tw->ScreenSize.x;
7023ff48bf5SDavid du Colombier memcpy(cp, tw->ScreenBuffer + tw->ScreenSize.x*i, count);
7033ff48bf5SDavid du Colombier /* remove trailing spaces */
7043ff48bf5SDavid du Colombier for (count=count-1; count>=0; count--) {
7053ff48bf5SDavid du Colombier if (cp[count]!=' ')
7063ff48bf5SDavid du Colombier break;
7073ff48bf5SDavid du Colombier cp[count] = '\0';
7083ff48bf5SDavid du Colombier }
7093ff48bf5SDavid du Colombier cp[++count] = '\r';
7103ff48bf5SDavid du Colombier cp[++count] = '\n';
7113ff48bf5SDavid du Colombier cp[++count] = '\0';
7123ff48bf5SDavid du Colombier cp += count;
7133ff48bf5SDavid du Colombier }
7143ff48bf5SDavid du Colombier size = strlen(cbuf) + 1;
7153ff48bf5SDavid du Colombier GlobalUnlock(hGMem);
7163ff48bf5SDavid du Colombier hGMem = GlobalReAlloc(hGMem, (DWORD)size, GHND | GMEM_SHARE);
7173ff48bf5SDavid du Colombier /* find out what type to put into clipboard */
7183ff48bf5SDavid du Colombier hdc = GetDC(tw->hwnd);
7193ff48bf5SDavid du Colombier SelectFont(hdc, tw->hfont);
7203ff48bf5SDavid du Colombier GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
7213ff48bf5SDavid du Colombier if (tm.tmCharSet == OEM_CHARSET)
7223ff48bf5SDavid du Colombier type = CF_OEMTEXT;
7233ff48bf5SDavid du Colombier else
7243ff48bf5SDavid du Colombier type = CF_TEXT;
7253ff48bf5SDavid du Colombier ReleaseDC(tw->hwnd, hdc);
7263ff48bf5SDavid du Colombier /* give buffer to clipboard */
7273ff48bf5SDavid du Colombier OpenClipboard(tw->hwnd);
7283ff48bf5SDavid du Colombier EmptyClipboard();
7293ff48bf5SDavid du Colombier SetClipboardData(type, hGMem);
7303ff48bf5SDavid du Colombier CloseClipboard();
7313ff48bf5SDavid du Colombier }
7323ff48bf5SDavid du Colombier
7333ff48bf5SDavid du Colombier void
text_paste_from_clipboard(TW * tw)7343ff48bf5SDavid du Colombier text_paste_from_clipboard(TW *tw)
7353ff48bf5SDavid du Colombier {
7363ff48bf5SDavid du Colombier HGLOBAL hClipMemory;
7373ff48bf5SDavid du Colombier BYTE *p;
7383ff48bf5SDavid du Colombier long count;
7393ff48bf5SDavid du Colombier OpenClipboard(tw->hwnd);
7403ff48bf5SDavid du Colombier if (IsClipboardFormatAvailable(CF_TEXT)) {
7413ff48bf5SDavid du Colombier hClipMemory = GetClipboardData(CF_TEXT);
7423ff48bf5SDavid du Colombier p = GlobalLock(hClipMemory);
7433ff48bf5SDavid du Colombier while (*p) {
7443ff48bf5SDavid du Colombier /* transfer to keyboard circular buffer */
7453ff48bf5SDavid du Colombier count = tw->KeyBufIn - tw->KeyBufOut;
7463ff48bf5SDavid du Colombier if (count < 0)
7473ff48bf5SDavid du Colombier count += tw->KeyBufSize;
7483ff48bf5SDavid du Colombier if (count < tw->KeyBufSize-1) {
7493ff48bf5SDavid du Colombier *tw->KeyBufIn++ = *p;
7503ff48bf5SDavid du Colombier if (tw->KeyBufIn - tw->KeyBuf >= tw->KeyBufSize)
7513ff48bf5SDavid du Colombier tw->KeyBufIn = tw->KeyBuf; /* wrap around */
7523ff48bf5SDavid du Colombier }
7533ff48bf5SDavid du Colombier p++;
7543ff48bf5SDavid du Colombier }
7553ff48bf5SDavid du Colombier GlobalUnlock(hClipMemory);
7563ff48bf5SDavid du Colombier }
7573ff48bf5SDavid du Colombier CloseClipboard();
7583ff48bf5SDavid du Colombier }
7593ff48bf5SDavid du Colombier
7603ff48bf5SDavid du Colombier /* text window */
7613ff48bf5SDavid du Colombier LRESULT CALLBACK
WndTextProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)7623ff48bf5SDavid du Colombier WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
7633ff48bf5SDavid du Colombier {
7643ff48bf5SDavid du Colombier HDC hdc;
7653ff48bf5SDavid du Colombier PAINTSTRUCT ps;
7663ff48bf5SDavid du Colombier RECT rect;
7673ff48bf5SDavid du Colombier int nYinc, nXinc;
7683ff48bf5SDavid du Colombier TW *tw;
7693ff48bf5SDavid du Colombier if (message == WM_CREATE) {
7703ff48bf5SDavid du Colombier /* Object is stored in window extra data.
7713ff48bf5SDavid du Colombier * Nothing must try to use the object before WM_CREATE
7723ff48bf5SDavid du Colombier * initializes it here.
7733ff48bf5SDavid du Colombier */
7743ff48bf5SDavid du Colombier tw = (TW *)(((CREATESTRUCT FAR *)lParam)->lpCreateParams);
7753ff48bf5SDavid du Colombier SetWindowLong(hwnd, 0, (LONG)tw);
7763ff48bf5SDavid du Colombier }
7773ff48bf5SDavid du Colombier tw = (TW *)GetWindowLong(hwnd, 0);
7783ff48bf5SDavid du Colombier
7793ff48bf5SDavid du Colombier switch(message) {
7803ff48bf5SDavid du Colombier case WM_SYSCOMMAND:
7813ff48bf5SDavid du Colombier switch(LOWORD(wParam)) {
7823ff48bf5SDavid du Colombier case M_COPY_CLIP:
7833ff48bf5SDavid du Colombier text_copy_to_clipboard(tw);
7843ff48bf5SDavid du Colombier return 0;
7853ff48bf5SDavid du Colombier case M_PASTE_CLIP:
7863ff48bf5SDavid du Colombier text_paste_from_clipboard(tw);
7873ff48bf5SDavid du Colombier return 0;
7883ff48bf5SDavid du Colombier }
7893ff48bf5SDavid du Colombier break;
7903ff48bf5SDavid du Colombier case WM_SETFOCUS:
7913ff48bf5SDavid du Colombier tw->bFocus = TRUE;
7923ff48bf5SDavid du Colombier CreateCaret(hwnd, 0, tw->CharSize.x, 2+tw->CaretHeight);
7933ff48bf5SDavid du Colombier SetCaretPos(tw->CursorPos.x*tw->CharSize.x - tw->ScrollPos.x,
7943ff48bf5SDavid du Colombier tw->CursorPos.y*tw->CharSize.y + tw->CharAscent
7953ff48bf5SDavid du Colombier - tw->CaretHeight - tw->ScrollPos.y);
7963ff48bf5SDavid du Colombier if (tw->bGetCh)
7973ff48bf5SDavid du Colombier ShowCaret(hwnd);
7983ff48bf5SDavid du Colombier break;
7993ff48bf5SDavid du Colombier case WM_KILLFOCUS:
8003ff48bf5SDavid du Colombier DestroyCaret();
8013ff48bf5SDavid du Colombier tw->bFocus = FALSE;
8023ff48bf5SDavid du Colombier break;
8033ff48bf5SDavid du Colombier case WM_MOVE:
8043ff48bf5SDavid du Colombier if (!IsIconic(hwnd) && !IsZoomed(hwnd)) {
8053ff48bf5SDavid du Colombier GetWindowRect(hwnd, &rect);
8063ff48bf5SDavid du Colombier tw->x = rect.left;
8073ff48bf5SDavid du Colombier tw->y = rect.top;
8083ff48bf5SDavid du Colombier }
8093ff48bf5SDavid du Colombier break;
8103ff48bf5SDavid du Colombier case WM_SIZE:
8113ff48bf5SDavid du Colombier if (wParam == SIZE_MINIMIZED)
8123ff48bf5SDavid du Colombier return(0);
8133ff48bf5SDavid du Colombier
8143ff48bf5SDavid du Colombier /* remember current window size */
8153ff48bf5SDavid du Colombier if (wParam != SIZE_MAXIMIZED) {
8163ff48bf5SDavid du Colombier GetWindowRect(hwnd, &rect);
8173ff48bf5SDavid du Colombier tw->cx = rect.right - rect.left;
8183ff48bf5SDavid du Colombier tw->cy = rect.bottom - rect.top;
8193ff48bf5SDavid du Colombier tw->x = rect.left;
8203ff48bf5SDavid du Colombier tw->y = rect.top;
8213ff48bf5SDavid du Colombier }
8223ff48bf5SDavid du Colombier
8233ff48bf5SDavid du Colombier tw->ClientSize.y = HIWORD(lParam);
8243ff48bf5SDavid du Colombier tw->ClientSize.x = LOWORD(lParam);
8253ff48bf5SDavid du Colombier
8263ff48bf5SDavid du Colombier tw->ScrollMax.y = max(0, tw->CharSize.y*tw->ScreenSize.y - tw->ClientSize.y);
8273ff48bf5SDavid du Colombier tw->ScrollPos.y = min(tw->ScrollPos.y, tw->ScrollMax.y);
8283ff48bf5SDavid du Colombier
8293ff48bf5SDavid du Colombier SetScrollRange(hwnd, SB_VERT, 0, tw->ScrollMax.y, FALSE);
8303ff48bf5SDavid du Colombier SetScrollPos(hwnd, SB_VERT, tw->ScrollPos.y, TRUE);
8313ff48bf5SDavid du Colombier
8323ff48bf5SDavid du Colombier tw->ScrollMax.x = max(0, tw->CharSize.x*tw->ScreenSize.x - tw->ClientSize.x);
8333ff48bf5SDavid du Colombier tw->ScrollPos.x = min(tw->ScrollPos.x, tw->ScrollMax.x);
8343ff48bf5SDavid du Colombier
8353ff48bf5SDavid du Colombier SetScrollRange(hwnd, SB_HORZ, 0, tw->ScrollMax.x, FALSE);
8363ff48bf5SDavid du Colombier SetScrollPos(hwnd, SB_HORZ, tw->ScrollPos.x, TRUE);
8373ff48bf5SDavid du Colombier
8383ff48bf5SDavid du Colombier if (tw->bFocus && tw->bGetCh) {
8393ff48bf5SDavid du Colombier SetCaretPos(tw->CursorPos.x*tw->CharSize.x - tw->ScrollPos.x,
8403ff48bf5SDavid du Colombier tw->CursorPos.y*tw->CharSize.y + tw->CharAscent
8413ff48bf5SDavid du Colombier - tw->CaretHeight - tw->ScrollPos.y);
8423ff48bf5SDavid du Colombier ShowCaret(hwnd);
8433ff48bf5SDavid du Colombier }
8443ff48bf5SDavid du Colombier return(0);
8453ff48bf5SDavid du Colombier case WM_VSCROLL:
8463ff48bf5SDavid du Colombier switch(LOWORD(wParam)) {
8473ff48bf5SDavid du Colombier case SB_TOP:
8483ff48bf5SDavid du Colombier nYinc = -tw->ScrollPos.y;
8493ff48bf5SDavid du Colombier break;
8503ff48bf5SDavid du Colombier case SB_BOTTOM:
8513ff48bf5SDavid du Colombier nYinc = tw->ScrollMax.y - tw->ScrollPos.y;
8523ff48bf5SDavid du Colombier break;
8533ff48bf5SDavid du Colombier case SB_LINEUP:
8543ff48bf5SDavid du Colombier nYinc = -tw->CharSize.y;
8553ff48bf5SDavid du Colombier break;
8563ff48bf5SDavid du Colombier case SB_LINEDOWN:
8573ff48bf5SDavid du Colombier nYinc = tw->CharSize.y;
8583ff48bf5SDavid du Colombier break;
8593ff48bf5SDavid du Colombier case SB_PAGEUP:
8603ff48bf5SDavid du Colombier nYinc = min(-1,-tw->ClientSize.y);
8613ff48bf5SDavid du Colombier break;
8623ff48bf5SDavid du Colombier case SB_PAGEDOWN:
8633ff48bf5SDavid du Colombier nYinc = max(1,tw->ClientSize.y);
8643ff48bf5SDavid du Colombier break;
8653ff48bf5SDavid du Colombier case SB_THUMBPOSITION:
8663ff48bf5SDavid du Colombier nYinc = HIWORD(wParam) - tw->ScrollPos.y;
8673ff48bf5SDavid du Colombier break;
8683ff48bf5SDavid du Colombier default:
8693ff48bf5SDavid du Colombier nYinc = 0;
8703ff48bf5SDavid du Colombier }
8713ff48bf5SDavid du Colombier if ( (nYinc = max(-tw->ScrollPos.y,
8723ff48bf5SDavid du Colombier min(nYinc, tw->ScrollMax.y - tw->ScrollPos.y)))
8733ff48bf5SDavid du Colombier != 0 ) {
8743ff48bf5SDavid du Colombier tw->ScrollPos.y += nYinc;
8753ff48bf5SDavid du Colombier ScrollWindow(hwnd,0,-nYinc,NULL,NULL);
8763ff48bf5SDavid du Colombier SetScrollPos(hwnd,SB_VERT,tw->ScrollPos.y,TRUE);
8773ff48bf5SDavid du Colombier UpdateWindow(hwnd);
8783ff48bf5SDavid du Colombier }
8793ff48bf5SDavid du Colombier return(0);
8803ff48bf5SDavid du Colombier case WM_HSCROLL:
8813ff48bf5SDavid du Colombier switch(LOWORD(wParam)) {
8823ff48bf5SDavid du Colombier case SB_LINEUP:
8833ff48bf5SDavid du Colombier nXinc = -tw->CharSize.x;
8843ff48bf5SDavid du Colombier break;
8853ff48bf5SDavid du Colombier case SB_LINEDOWN:
8863ff48bf5SDavid du Colombier nXinc = tw->CharSize.x;
8873ff48bf5SDavid du Colombier break;
8883ff48bf5SDavid du Colombier case SB_PAGEUP:
8893ff48bf5SDavid du Colombier nXinc = min(-1,-tw->ClientSize.x);
8903ff48bf5SDavid du Colombier break;
8913ff48bf5SDavid du Colombier case SB_PAGEDOWN:
8923ff48bf5SDavid du Colombier nXinc = max(1,tw->ClientSize.x);
8933ff48bf5SDavid du Colombier break;
8943ff48bf5SDavid du Colombier case SB_THUMBPOSITION:
8953ff48bf5SDavid du Colombier nXinc = HIWORD(wParam) - tw->ScrollPos.x;
8963ff48bf5SDavid du Colombier break;
8973ff48bf5SDavid du Colombier default:
8983ff48bf5SDavid du Colombier nXinc = 0;
8993ff48bf5SDavid du Colombier }
9003ff48bf5SDavid du Colombier if ( (nXinc = max(-tw->ScrollPos.x,
9013ff48bf5SDavid du Colombier min(nXinc, tw->ScrollMax.x - tw->ScrollPos.x)))
9023ff48bf5SDavid du Colombier != 0 ) {
9033ff48bf5SDavid du Colombier tw->ScrollPos.x += nXinc;
9043ff48bf5SDavid du Colombier ScrollWindow(hwnd,-nXinc,0,NULL,NULL);
9053ff48bf5SDavid du Colombier SetScrollPos(hwnd,SB_HORZ,tw->ScrollPos.x,TRUE);
9063ff48bf5SDavid du Colombier UpdateWindow(hwnd);
9073ff48bf5SDavid du Colombier }
9083ff48bf5SDavid du Colombier return(0);
9093ff48bf5SDavid du Colombier case WM_KEYDOWN:
9103ff48bf5SDavid du Colombier switch(wParam) {
9113ff48bf5SDavid du Colombier case VK_HOME:
9123ff48bf5SDavid du Colombier SendMessage(hwnd, WM_VSCROLL, SB_TOP, (LPARAM)0);
9133ff48bf5SDavid du Colombier break;
9143ff48bf5SDavid du Colombier case VK_END:
9153ff48bf5SDavid du Colombier SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, (LPARAM)0);
9163ff48bf5SDavid du Colombier break;
9173ff48bf5SDavid du Colombier case VK_PRIOR:
9183ff48bf5SDavid du Colombier SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, (LPARAM)0);
9193ff48bf5SDavid du Colombier break;
9203ff48bf5SDavid du Colombier case VK_NEXT:
9213ff48bf5SDavid du Colombier SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, (LPARAM)0);
9223ff48bf5SDavid du Colombier break;
9233ff48bf5SDavid du Colombier case VK_UP:
9243ff48bf5SDavid du Colombier SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, (LPARAM)0);
9253ff48bf5SDavid du Colombier break;
9263ff48bf5SDavid du Colombier case VK_DOWN:
9273ff48bf5SDavid du Colombier SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, (LPARAM)0);
9283ff48bf5SDavid du Colombier break;
9293ff48bf5SDavid du Colombier case VK_LEFT:
9303ff48bf5SDavid du Colombier SendMessage(hwnd, WM_HSCROLL, SB_LINEUP, (LPARAM)0);
9313ff48bf5SDavid du Colombier break;
9323ff48bf5SDavid du Colombier case VK_RIGHT:
9333ff48bf5SDavid du Colombier SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, (LPARAM)0);
9343ff48bf5SDavid du Colombier break;
9353ff48bf5SDavid du Colombier }
9363ff48bf5SDavid du Colombier break;
9373ff48bf5SDavid du Colombier case WM_CHAR:
9383ff48bf5SDavid du Colombier { /* store key in circular buffer */
9393ff48bf5SDavid du Colombier long count = tw->KeyBufIn - tw->KeyBufOut;
9403ff48bf5SDavid du Colombier if (count < 0) count += tw->KeyBufSize;
9413ff48bf5SDavid du Colombier if (count < tw->KeyBufSize-1) {
9423ff48bf5SDavid du Colombier *tw->KeyBufIn++ = wParam;
9433ff48bf5SDavid du Colombier if (tw->KeyBufIn - tw->KeyBuf >= tw->KeyBufSize)
9443ff48bf5SDavid du Colombier tw->KeyBufIn = tw->KeyBuf; /* wrap around */
9453ff48bf5SDavid du Colombier }
9463ff48bf5SDavid du Colombier }
9473ff48bf5SDavid du Colombier return(0);
9483ff48bf5SDavid du Colombier case WM_PAINT:
9493ff48bf5SDavid du Colombier {
9503ff48bf5SDavid du Colombier POINT source, width, dest;
9513ff48bf5SDavid du Colombier hdc = BeginPaint(hwnd, &ps);
9523ff48bf5SDavid du Colombier SelectFont(hdc, tw->hfont);
9533ff48bf5SDavid du Colombier SetMapMode(hdc, MM_TEXT);
9543ff48bf5SDavid du Colombier SetBkMode(hdc,OPAQUE);
9553ff48bf5SDavid du Colombier GetClientRect(hwnd, &rect);
9563ff48bf5SDavid du Colombier source.x = (rect.left + tw->ScrollPos.x) / tw->CharSize.x; /* source */
9573ff48bf5SDavid du Colombier source.y = (rect.top + tw->ScrollPos.y) / tw->CharSize.y;
9583ff48bf5SDavid du Colombier dest.x = source.x * tw->CharSize.x - tw->ScrollPos.x; /* destination */
9593ff48bf5SDavid du Colombier dest.y = source.y * tw->CharSize.y - tw->ScrollPos.y;
9603ff48bf5SDavid du Colombier width.x = ((rect.right + tw->ScrollPos.x + tw->CharSize.x - 1) / tw->CharSize.x) - source.x; /* width */
9613ff48bf5SDavid du Colombier width.y = ((rect.bottom + tw->ScrollPos.y + tw->CharSize.y - 1) / tw->CharSize.y) - source.y;
9623ff48bf5SDavid du Colombier if (source.x < 0)
9633ff48bf5SDavid du Colombier source.x = 0;
9643ff48bf5SDavid du Colombier if (source.y < 0)
9653ff48bf5SDavid du Colombier source.y = 0;
9663ff48bf5SDavid du Colombier if (source.x+width.x > tw->ScreenSize.x)
9673ff48bf5SDavid du Colombier width.x = tw->ScreenSize.x - source.x;
9683ff48bf5SDavid du Colombier if (source.y+width.y > tw->ScreenSize.y)
9693ff48bf5SDavid du Colombier width.y = tw->ScreenSize.y - source.y;
9703ff48bf5SDavid du Colombier /* for each line */
9713ff48bf5SDavid du Colombier while (width.y>0) {
9723ff48bf5SDavid du Colombier TextOut(hdc,dest.x,dest.y,
9733ff48bf5SDavid du Colombier (LPSTR)(tw->ScreenBuffer + source.y*tw->ScreenSize.x + source.x),
9743ff48bf5SDavid du Colombier width.x);
9753ff48bf5SDavid du Colombier dest.y += tw->CharSize.y;
9763ff48bf5SDavid du Colombier source.y++;
9773ff48bf5SDavid du Colombier width.y--;
9783ff48bf5SDavid du Colombier }
9793ff48bf5SDavid du Colombier EndPaint(hwnd, &ps);
9803ff48bf5SDavid du Colombier return 0;
9813ff48bf5SDavid du Colombier }
9823ff48bf5SDavid du Colombier case WM_DROPFILES:
9833ff48bf5SDavid du Colombier text_drag_drop(tw, (HDROP)wParam);
9843ff48bf5SDavid du Colombier break;
9853ff48bf5SDavid du Colombier case WM_CREATE:
9863ff48bf5SDavid du Colombier {
9873ff48bf5SDavid du Colombier RECT crect, wrect;
9883ff48bf5SDavid du Colombier int cx, cy;
9893ff48bf5SDavid du Colombier
9903ff48bf5SDavid du Colombier tw->hwnd = hwnd;
9913ff48bf5SDavid du Colombier
9923ff48bf5SDavid du Colombier /* make window no larger than screen buffer */
9933ff48bf5SDavid du Colombier GetWindowRect(hwnd, &wrect);
9943ff48bf5SDavid du Colombier GetClientRect(hwnd, &crect);
9953ff48bf5SDavid du Colombier cx = min(tw->CharSize.x*tw->ScreenSize.x, crect.right);
9963ff48bf5SDavid du Colombier cy = min(tw->CharSize.y*tw->ScreenSize.y, crect.bottom);
9973ff48bf5SDavid du Colombier MoveWindow(hwnd, wrect.left, wrect.top,
9983ff48bf5SDavid du Colombier wrect.right-wrect.left + (cx - crect.right),
9993ff48bf5SDavid du Colombier wrect.bottom-wrect.top + (cy - crect.bottom),
10003ff48bf5SDavid du Colombier TRUE);
10013ff48bf5SDavid du Colombier
10023ff48bf5SDavid du Colombier if ( (tw->DragPre!=(LPSTR)NULL) && (tw->DragPost!=(LPSTR)NULL) )
10033ff48bf5SDavid du Colombier DragAcceptFiles(hwnd, TRUE);
10043ff48bf5SDavid du Colombier }
10053ff48bf5SDavid du Colombier break;
10063ff48bf5SDavid du Colombier case WM_CLOSE:
10073ff48bf5SDavid du Colombier /* Tell user that we heard them */
10083ff48bf5SDavid du Colombier if (!tw->quitnow) {
10093ff48bf5SDavid du Colombier char title[256];
10103ff48bf5SDavid du Colombier int count = GetWindowText(hwnd, title, sizeof(title)-11);
10113ff48bf5SDavid du Colombier strcpy(title+count, " - closing");
10123ff48bf5SDavid du Colombier SetWindowText(hwnd, title);
10133ff48bf5SDavid du Colombier }
10143ff48bf5SDavid du Colombier tw->quitnow = TRUE;
10153ff48bf5SDavid du Colombier /* wait until Ghostscript exits before destroying window */
10163ff48bf5SDavid du Colombier return 0;
10173ff48bf5SDavid du Colombier case WM_DESTROY:
10183ff48bf5SDavid du Colombier DragAcceptFiles(hwnd, FALSE);
10193ff48bf5SDavid du Colombier if (tw->hfont)
10203ff48bf5SDavid du Colombier DeleteFont(tw->hfont);
10213ff48bf5SDavid du Colombier tw->hfont = (HFONT)0;
10223ff48bf5SDavid du Colombier tw->quitnow = TRUE;
10233ff48bf5SDavid du Colombier PostQuitMessage(0);
10243ff48bf5SDavid du Colombier break;
10253ff48bf5SDavid du Colombier }
10263ff48bf5SDavid du Colombier return DefWindowProc(hwnd, message, wParam, lParam);
10273ff48bf5SDavid du Colombier }
10283ff48bf5SDavid du Colombier
10293ff48bf5SDavid du Colombier
text_get_handle(TW * tw)10303ff48bf5SDavid du Colombier HWND text_get_handle(TW *tw)
10313ff48bf5SDavid du Colombier {
10323ff48bf5SDavid du Colombier return tw->hwnd;
10333ff48bf5SDavid du Colombier }
10343ff48bf5SDavid du Colombier
10353ff48bf5SDavid du Colombier
10363ff48bf5SDavid du Colombier #ifdef NOTUSED
10373ff48bf5SDavid du Colombier /* test program */
10383ff48bf5SDavid du Colombier #pragma argsused
10393ff48bf5SDavid du Colombier
10403ff48bf5SDavid du Colombier int PASCAL
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int nCmdShow)10413ff48bf5SDavid du Colombier WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
10423ff48bf5SDavid du Colombier {
10433ff48bf5SDavid du Colombier
10443ff48bf5SDavid du Colombier /* make a test window */
10453ff48bf5SDavid du Colombier tw = text_new();
10463ff48bf5SDavid du Colombier
10473ff48bf5SDavid du Colombier if (!hPrevInstance) {
10483ff48bf5SDavid du Colombier HICON hicon = LoadIcon(NULL, IDI_APPLICATION);
10493ff48bf5SDavid du Colombier text_register_class(hicon);
10503ff48bf5SDavid du Colombier }
10513ff48bf5SDavid du Colombier text_font(tw, "Courier New", 10);
10523ff48bf5SDavid du Colombier text_size(tw, 80, 80);
10533ff48bf5SDavid du Colombier text_drag(tw, "(", ") run\r");
10543ff48bf5SDavid du Colombier
10553ff48bf5SDavid du Colombier /* show the text window */
10563ff48bf5SDavid du Colombier if (!text_create(tw, "Application Name", nCmdShow)) {
10573ff48bf5SDavid du Colombier /* do the real work here */
10583ff48bf5SDavid du Colombier /* TESTING */
10593ff48bf5SDavid du Colombier int ch;
10603ff48bf5SDavid du Colombier int len;
10613ff48bf5SDavid du Colombier char *line = new char[256];
10623ff48bf5SDavid du Colombier while ( (len = text_read_line(tw, line, 256-1)) != 0 ) {
10633ff48bf5SDavid du Colombier text_write_buf(tw, line, len);
10643ff48bf5SDavid du Colombier }
10653ff48bf5SDavid du Colombier /*
10663ff48bf5SDavid du Colombier while ( text_gets(tw, line, 256-1) ) {
10673ff48bf5SDavid du Colombier text_puts(tw, line);
10683ff48bf5SDavid du Colombier }
10693ff48bf5SDavid du Colombier */
10703ff48bf5SDavid du Colombier /*
10713ff48bf5SDavid du Colombier while ( (ch = text_getch(tw, )) != 4 )
10723ff48bf5SDavid du Colombier text_putch(tw, ch);
10733ff48bf5SDavid du Colombier */
10743ff48bf5SDavid du Colombier }
10753ff48bf5SDavid du Colombier else {
10763ff48bf5SDavid du Colombier
10773ff48bf5SDavid du Colombier }
10783ff48bf5SDavid du Colombier
10793ff48bf5SDavid du Colombier /* clean up */
10803ff48bf5SDavid du Colombier text_destroy(tw);
10813ff48bf5SDavid du Colombier
10823ff48bf5SDavid du Colombier /* end program */
10833ff48bf5SDavid du Colombier return 0;
10843ff48bf5SDavid du Colombier }
10853ff48bf5SDavid du Colombier #endif
1086