OSDN Git Service

2011-02-08 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / boehm-gc / cord / de_win.c
1 /*
2  * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
3  *
4  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
6  *
7  * Permission is hereby granted to use or copy this program
8  * for any purpose,  provided the above notices are retained on all copies.
9  * Permission to modify the code and to distribute modified code is granted,
10  * provided the above notices are retained, and a notice that the code was
11  * modified is included with the above copyright notice.
12  */
13 /* Boehm, February 6, 1995 12:29 pm PST */
14
15 /*
16  * The MS Windows specific part of de.  
17  * This started as the generic Windows application template
18  * made available by Rob Haack (rhaack@polaris.unm.edu), but
19  * significant parts didn't survive to the final version.
20  *
21  * This was written by a nonexpert windows programmer.
22  */
23
24
25 #include "windows.h"
26 #include "gc.h"
27 #include "cord.h"
28 #include "de_cmds.h"
29 #include "de_win.h"
30
31 int LINES = 0;
32 int COLS = 0;
33
34 char       szAppName[]     = "DE";
35 char       FullAppName[]   = "Demonstration Editor";
36
37 HWND        hwnd;
38
39 void de_error(char *s)
40 {
41     MessageBox( hwnd, (LPSTR) s,
42                 (LPSTR) FullAppName,
43                 MB_ICONINFORMATION | MB_OK );
44     InvalidateRect(hwnd, NULL, TRUE);
45 }
46
47 int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
48                       LPSTR command_line, int nCmdShow)
49 {
50    MSG         msg;
51    WNDCLASS    wndclass;
52    HANDLE      hAccel;
53
54    if (!hPrevInstance)
55    {
56       wndclass.style          = CS_HREDRAW | CS_VREDRAW;
57       wndclass.lpfnWndProc    = WndProc;
58       wndclass.cbClsExtra     = 0;
59       wndclass.cbWndExtra     = DLGWINDOWEXTRA;
60       wndclass.hInstance      = hInstance;
61       wndclass.hIcon          = LoadIcon (hInstance, szAppName);
62       wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
63       wndclass.hbrBackground  = GetStockObject(WHITE_BRUSH);
64       wndclass.lpszMenuName   = "DE";
65       wndclass.lpszClassName  = szAppName;
66
67       if (RegisterClass (&wndclass) == 0) {
68           char buf[50];
69         
70           sprintf(buf, "RegisterClass: error code: 0x%X", GetLastError());
71           de_error(buf);
72           return(0);
73       }
74    }
75    
76    /* Empirically, the command line does not include the command name ...
77    if (command_line != 0) {
78        while (isspace(*command_line)) command_line++;
79        while (*command_line != 0 && !isspace(*command_line)) command_line++;
80        while (isspace(*command_line)) command_line++;
81    } */
82    
83    if (command_line == 0 || *command_line == 0) {
84         de_error("File name argument required");
85         return( 0 );
86    } else {
87         char *p = command_line;
88         
89         while (*p != 0 && !isspace(*p)) p++;
90         arg_file_name = CORD_to_char_star(
91                             CORD_substr(command_line, 0, p - command_line));
92    }
93
94    hwnd = CreateWindow (szAppName,
95                         FullAppName,
96                         WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
97                         CW_USEDEFAULT, 0, /* default pos. */
98                         CW_USEDEFAULT, 0, /* default width, height */
99                         NULL,   /* No parent */
100                         NULL,   /* Window class menu */
101                         hInstance, NULL);
102    if (hwnd == NULL) {
103         char buf[50];
104         
105         sprintf(buf, "CreateWindow: error code: 0x%X", GetLastError());
106         de_error(buf);
107         return(0);
108    }
109
110    ShowWindow (hwnd, nCmdShow);
111
112    hAccel = LoadAccelerators( hInstance, szAppName );
113    
114    while (GetMessage (&msg, NULL, 0, 0))
115    {
116       if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
117       {
118          TranslateMessage (&msg);
119          DispatchMessage (&msg);
120       }
121    }
122    return msg.wParam;
123 }
124
125 /* Return the argument with all control characters replaced by blanks.  */
126 char * plain_chars(char * text, size_t len)
127 {
128     char * result = GC_MALLOC_ATOMIC(len + 1);
129     register size_t i;
130     
131     for (i = 0; i < len; i++) {
132        if (iscntrl(text[i])) {
133            result[i] = ' ';
134        } else {
135            result[i] = text[i];
136        }
137     }
138     result[len] = '\0';
139     return(result);
140 }
141
142 /* Return the argument with all non-control-characters replaced by      */
143 /* blank, and all control characters c replaced by c + 32.              */
144 char * control_chars(char * text, size_t len)
145 {
146     char * result = GC_MALLOC_ATOMIC(len + 1);
147     register size_t i;
148     
149     for (i = 0; i < len; i++) {
150        if (iscntrl(text[i])) {
151            result[i] = text[i] + 0x40;
152        } else {
153            result[i] = ' ';
154        }
155     }
156     result[len] = '\0';
157     return(result);
158 }
159
160 int char_width;
161 int char_height;
162
163 void get_line_rect(int line, int win_width, RECT * rectp)
164 {
165     rectp -> top = line * char_height;
166     rectp -> bottom = rectp->top + char_height;
167     rectp -> left = 0;
168     rectp -> right = win_width;
169 }
170
171 int caret_visible = 0;  /* Caret is currently visible.  */
172
173 int screen_was_painted = 0;/* Screen has been painted at least once.    */
174
175 void update_cursor(void);
176
177 LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
178                           WPARAM wParam, LPARAM lParam)
179 {
180    static FARPROC lpfnAboutBox;
181    static HANDLE  hInstance;
182    HDC dc;
183    PAINTSTRUCT ps;
184    RECT client_area;
185    RECT this_line;
186    RECT dummy;
187    TEXTMETRIC tm;
188    register int i;
189    int id;
190
191    switch (message)
192    {
193       case WM_CREATE:
194            hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
195            lpfnAboutBox = MakeProcInstance( (FARPROC) AboutBox, hInstance );
196            dc = GetDC(hwnd);
197            SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
198            GetTextMetrics(dc, &tm);
199            ReleaseDC(hwnd, dc);
200            char_width = tm.tmAveCharWidth;
201            char_height = tm.tmHeight + tm.tmExternalLeading;
202            GetClientRect(hwnd, &client_area);
203            COLS = (client_area.right - client_area.left)/char_width;
204            LINES = (client_area.bottom - client_area.top)/char_height;
205            generic_init();
206            return(0);
207
208       case WM_CHAR:
209            if (wParam == QUIT) {
210                SendMessage( hwnd, WM_CLOSE, 0, 0L );
211            } else {
212                do_command(wParam);
213            }
214            return(0);
215       
216       case WM_SETFOCUS:
217            CreateCaret(hwnd, NULL, char_width, char_height);
218            ShowCaret(hwnd);
219            caret_visible = 1;
220            update_cursor();
221            return(0);
222            
223       case WM_KILLFOCUS:
224            HideCaret(hwnd);
225            DestroyCaret();
226            caret_visible = 0;
227            return(0);
228            
229       case WM_LBUTTONUP:
230            {
231                unsigned xpos = LOWORD(lParam);  /* From left    */
232                unsigned ypos = HIWORD(lParam);  /* from top */
233                
234                set_position( xpos/char_width, ypos/char_height );
235                return(0);
236            }
237            
238       case WM_COMMAND:
239            id = LOWORD(wParam);
240            if (id & EDIT_CMD_FLAG) {
241                if (id & REPEAT_FLAG) do_command(REPEAT);
242                do_command(CHAR_CMD(id));
243                return( 0 );
244            } else {
245              switch(id) {
246                case IDM_FILEEXIT:
247                   SendMessage( hwnd, WM_CLOSE, 0, 0L );
248                   return( 0 );
249
250                case IDM_HELPABOUT:
251                   if( DialogBox( hInstance, "ABOUTBOX",
252                                  hwnd, lpfnAboutBox ) )
253                      InvalidateRect( hwnd, NULL, TRUE );
254                   return( 0 );
255                case IDM_HELPCONTENTS:
256                   de_error(
257                        "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"
258                        "Undo: ^U    Write: ^W   Quit:^D  Repeat count: ^R[n]\n"
259                        "Top: ^T   Locate (search, find): ^L text ^L\n");
260                   return( 0 );
261              }
262            }
263            break;
264
265       case WM_CLOSE:
266            DestroyWindow( hwnd );
267            return 0;
268
269       case WM_DESTROY:
270            PostQuitMessage (0);
271            GC_win32_free_heap();
272            return 0;
273       
274       case WM_PAINT:
275            dc = BeginPaint(hwnd, &ps);
276            GetClientRect(hwnd, &client_area);
277            COLS = (client_area.right - client_area.left)/char_width;
278            LINES = (client_area.bottom - client_area.top)/char_height;
279            SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
280            for (i = 0; i < LINES; i++) {
281                get_line_rect(i, client_area.right, &this_line);
282                if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) {
283                    CORD raw_line = retrieve_screen_line(i);
284                    size_t len = CORD_len(raw_line);
285                    char * text = CORD_to_char_star(raw_line);
286                                 /* May contain embedded NULLs   */
287                    char * plain = plain_chars(text, len);
288                    char * blanks = CORD_to_char_star(CORD_chars(' ',
289                                                                 COLS - len));
290                    char * control = control_chars(text, len);
291 #                  define RED RGB(255,0,0)
292                    
293                    SetBkMode(dc, OPAQUE);
294                    SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
295                    
296                    TextOut(dc, this_line.left, this_line.top,
297                            plain, len);
298                    TextOut(dc, this_line.left + len * char_width, this_line.top,
299                            blanks, COLS - len);
300                    SetBkMode(dc, TRANSPARENT);
301                    SetTextColor(dc, RED);
302                    TextOut(dc, this_line.left, this_line.top,
303                            control, strlen(control));
304                }
305            }
306            EndPaint(hwnd, &ps);
307            screen_was_painted = 1;
308            return 0;
309    }
310    return DefWindowProc (hwnd, message, wParam, lParam);
311 }
312
313 int last_col;
314 int last_line;
315
316 void move_cursor(int c, int l)
317 {
318     last_col = c;
319     last_line = l;
320     
321     if (caret_visible) update_cursor();
322 }
323
324 void update_cursor(void)
325 {
326     SetCaretPos(last_col * char_width, last_line * char_height);
327     ShowCaret(hwnd);
328 }
329
330 void invalidate_line(int i)
331 {
332     RECT line;
333     
334     if (!screen_was_painted) return;
335         /* Invalidating a rectangle before painting seems result in a   */
336         /* major performance problem.                                   */
337     get_line_rect(i, COLS*char_width, &line);
338     InvalidateRect(hwnd, &line, FALSE);
339 }
340
341 LRESULT CALLBACK AboutBox( HWND hDlg, UINT message,
342                            WPARAM wParam, LPARAM lParam )
343 {
344    switch( message )
345    {
346       case WM_INITDIALOG:
347            SetFocus( GetDlgItem( hDlg, IDOK ) );
348            break;
349
350       case WM_COMMAND:
351            switch( wParam )
352            {
353               case IDOK:
354                    EndDialog( hDlg, TRUE );
355                    break;
356            }
357            break;
358
359       case WM_CLOSE:
360            EndDialog( hDlg, TRUE );
361            return TRUE;
362
363    }
364    return FALSE;
365 }
366