Import boehm-gc snapshot, taken from
[official-gcc.git] / boehm-gc / cord / tests / de_win.c
blob1179b8f7e52d0df5f0f5bd9ddd7f8b784773446d
1 /*
2 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
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.
15 * The MS Windows specific part of de.
16 * This started as the generic Windows application template
17 * but significant parts didn't survive to the final version.
19 * This was written by a nonexpert windows programmer.
22 #include "windows.h"
23 #include "gc.h"
24 #include "cord.h"
25 #include "de_cmds.h"
26 #include "de_win.h"
28 int LINES = 0;
29 int COLS = 0;
31 char szAppName[] = "DE";
32 char FullAppName[] = "Demonstration Editor";
34 HWND hwnd;
36 void de_error(char *s)
38 MessageBox( hwnd, (LPSTR) s,
39 (LPSTR) FullAppName,
40 MB_ICONINFORMATION | MB_OK );
41 InvalidateRect(hwnd, NULL, TRUE);
44 int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
45 LPSTR command_line, int nCmdShow)
47 MSG msg;
48 WNDCLASS wndclass;
49 HANDLE hAccel;
51 # ifdef THREAD_LOCAL_ALLOC
52 GC_INIT(); /* Required if GC is built with THREAD_LOCAL_ALLOC */
53 /* Always safe, but this is used as a GC test. */
54 # endif
56 if (!hPrevInstance)
58 wndclass.style = CS_HREDRAW | CS_VREDRAW;
59 wndclass.lpfnWndProc = WndProc;
60 wndclass.cbClsExtra = 0;
61 wndclass.cbWndExtra = DLGWINDOWEXTRA;
62 wndclass.hInstance = hInstance;
63 wndclass.hIcon = LoadIcon (hInstance, szAppName);
64 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
65 wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
66 wndclass.lpszMenuName = "DE";
67 wndclass.lpszClassName = szAppName;
69 if (RegisterClass (&wndclass) == 0) {
70 char buf[50];
72 sprintf(buf, "RegisterClass: error code: 0x%X",
73 (unsigned)GetLastError());
74 de_error(buf);
75 return(0);
79 /* Empirically, the command line does not include the command name ...
80 if (command_line != 0) {
81 while (isspace(*command_line)) command_line++;
82 while (*command_line != 0 && !isspace(*command_line)) command_line++;
83 while (isspace(*command_line)) command_line++;
84 } */
86 if (command_line == 0 || *command_line == 0) {
87 de_error("File name argument required");
88 return( 0 );
89 } else {
90 char *p = command_line;
92 while (*p != 0 && !isspace(*p)) p++;
93 arg_file_name = CORD_to_char_star(
94 CORD_substr(command_line, 0, p - command_line));
97 hwnd = CreateWindow (szAppName,
98 FullAppName,
99 WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
100 CW_USEDEFAULT, 0, /* default pos. */
101 CW_USEDEFAULT, 0, /* default width, height */
102 NULL, /* No parent */
103 NULL, /* Window class menu */
104 hInstance, NULL);
105 if (hwnd == NULL) {
106 char buf[50];
108 sprintf(buf, "CreateWindow: error code: 0x%X",
109 (unsigned)GetLastError());
110 de_error(buf);
111 return(0);
114 ShowWindow (hwnd, nCmdShow);
116 hAccel = LoadAccelerators( hInstance, szAppName );
118 while (GetMessage (&msg, NULL, 0, 0))
120 if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
122 TranslateMessage (&msg);
123 DispatchMessage (&msg);
126 return msg.wParam;
129 /* Return the argument with all control characters replaced by blanks. */
130 char * plain_chars(char * text, size_t len)
132 char * result = GC_MALLOC_ATOMIC(len + 1);
133 register size_t i;
135 for (i = 0; i < len; i++) {
136 if (iscntrl(text[i])) {
137 result[i] = ' ';
138 } else {
139 result[i] = text[i];
142 result[len] = '\0';
143 return(result);
146 /* Return the argument with all non-control-characters replaced by */
147 /* blank, and all control characters c replaced by c + 32. */
148 char * control_chars(char * text, size_t len)
150 char * result = GC_MALLOC_ATOMIC(len + 1);
151 register size_t i;
153 for (i = 0; i < len; i++) {
154 if (iscntrl(text[i])) {
155 result[i] = text[i] + 0x40;
156 } else {
157 result[i] = ' ';
160 result[len] = '\0';
161 return(result);
164 int char_width;
165 int char_height;
167 void get_line_rect(int line, int win_width, RECT * rectp)
169 rectp -> top = line * char_height;
170 rectp -> bottom = rectp->top + char_height;
171 rectp -> left = 0;
172 rectp -> right = win_width;
175 int caret_visible = 0; /* Caret is currently visible. */
177 int screen_was_painted = 0;/* Screen has been painted at least once. */
179 void update_cursor(void);
181 INT_PTR CALLBACK AboutBoxCallback( HWND hDlg, UINT message,
182 WPARAM wParam, LPARAM lParam )
184 (void)lParam;
185 switch( message )
187 case WM_INITDIALOG:
188 SetFocus( GetDlgItem( hDlg, IDOK ) );
189 break;
191 case WM_COMMAND:
192 switch( wParam )
194 case IDOK:
195 EndDialog( hDlg, TRUE );
196 break;
198 break;
200 case WM_CLOSE:
201 EndDialog( hDlg, TRUE );
202 return TRUE;
205 return FALSE;
208 LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
209 WPARAM wParam, LPARAM lParam)
211 static HANDLE hInstance;
212 HDC dc;
213 PAINTSTRUCT ps;
214 RECT client_area;
215 RECT this_line;
216 RECT dummy;
217 TEXTMETRIC tm;
218 register int i;
219 int id;
221 switch (message)
223 case WM_CREATE:
224 hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
225 dc = GetDC(hwnd);
226 SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
227 GetTextMetrics(dc, &tm);
228 ReleaseDC(hwnd, dc);
229 char_width = tm.tmAveCharWidth;
230 char_height = tm.tmHeight + tm.tmExternalLeading;
231 GetClientRect(hwnd, &client_area);
232 COLS = (client_area.right - client_area.left)/char_width;
233 LINES = (client_area.bottom - client_area.top)/char_height;
234 generic_init();
235 return(0);
237 case WM_CHAR:
238 if (wParam == QUIT) {
239 SendMessage( hwnd, WM_CLOSE, 0, 0L );
240 } else {
241 do_command((int)wParam);
243 return(0);
245 case WM_SETFOCUS:
246 CreateCaret(hwnd, NULL, char_width, char_height);
247 ShowCaret(hwnd);
248 caret_visible = 1;
249 update_cursor();
250 return(0);
252 case WM_KILLFOCUS:
253 HideCaret(hwnd);
254 DestroyCaret();
255 caret_visible = 0;
256 return(0);
258 case WM_LBUTTONUP:
260 unsigned xpos = LOWORD(lParam); /* From left */
261 unsigned ypos = HIWORD(lParam); /* from top */
263 set_position( xpos/char_width, ypos/char_height );
264 return(0);
267 case WM_COMMAND:
268 id = LOWORD(wParam);
269 if (id & EDIT_CMD_FLAG) {
270 if (id & REPEAT_FLAG) do_command(REPEAT);
271 do_command(CHAR_CMD(id));
272 return( 0 );
273 } else {
274 switch(id) {
275 case IDM_FILEEXIT:
276 SendMessage( hwnd, WM_CLOSE, 0, 0L );
277 return( 0 );
279 case IDM_HELPABOUT:
280 if( DialogBox( hInstance, "ABOUTBOX",
281 hwnd, AboutBoxCallback ) )
282 InvalidateRect( hwnd, NULL, TRUE );
283 return( 0 );
284 case IDM_HELPCONTENTS:
285 de_error(
286 "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"
287 "Undo: ^U Write: ^W Quit:^D Repeat count: ^R[n]\n"
288 "Top: ^T Locate (search, find): ^L text ^L\n");
289 return( 0 );
292 break;
294 case WM_CLOSE:
295 DestroyWindow( hwnd );
296 return 0;
298 case WM_DESTROY:
299 PostQuitMessage (0);
300 GC_win32_free_heap();
301 return 0;
303 case WM_PAINT:
304 dc = BeginPaint(hwnd, &ps);
305 GetClientRect(hwnd, &client_area);
306 COLS = (client_area.right - client_area.left)/char_width;
307 LINES = (client_area.bottom - client_area.top)/char_height;
308 SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
309 for (i = 0; i < LINES; i++) {
310 get_line_rect(i, client_area.right, &this_line);
311 if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) {
312 CORD raw_line = retrieve_screen_line(i);
313 size_t len = CORD_len(raw_line);
314 char * text = CORD_to_char_star(raw_line);
315 /* May contain embedded NULLs */
316 char * plain = plain_chars(text, len);
317 char * blanks = CORD_to_char_star(CORD_chars(' ',
318 COLS - len));
319 char * control = control_chars(text, len);
320 # define RED RGB(255,0,0)
322 SetBkMode(dc, OPAQUE);
323 SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
325 TextOut(dc, this_line.left, this_line.top,
326 plain, (int)len);
327 TextOut(dc, this_line.left + (int)len * char_width,
328 this_line.top,
329 blanks, (int)(COLS - len));
330 SetBkMode(dc, TRANSPARENT);
331 SetTextColor(dc, RED);
332 TextOut(dc, this_line.left, this_line.top,
333 control, (int)strlen(control));
336 EndPaint(hwnd, &ps);
337 screen_was_painted = 1;
338 return 0;
340 return DefWindowProc (hwnd, message, wParam, lParam);
343 int last_col;
344 int last_line;
346 void move_cursor(int c, int l)
348 last_col = c;
349 last_line = l;
351 if (caret_visible) update_cursor();
354 void update_cursor(void)
356 SetCaretPos(last_col * char_width, last_line * char_height);
357 ShowCaret(hwnd);
360 void invalidate_line(int i)
362 RECT line;
364 if (!screen_was_painted) return;
365 /* Invalidating a rectangle before painting seems result in a */
366 /* major performance problem. */
367 get_line_rect(i, COLS*char_width, &line);
368 InvalidateRect(hwnd, &line, FALSE);