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.
13 /* Boehm, February 6, 1995 12:29 pm PST */
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.
21 * This was written by a nonexpert windows programmer.
34 char szAppName[] = "DE";
35 char FullAppName[] = "Demonstration Editor";
39 void de_error(char *s)
41 MessageBox( hwnd, (LPSTR) s,
43 MB_ICONINFORMATION | MB_OK );
44 InvalidateRect(hwnd, NULL, TRUE);
47 int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
48 LPSTR command_line, int nCmdShow)
54 # ifdef THREAD_LOCAL_ALLOC
55 GC_INIT(); /* Required if GC is built with THREAD_LOCAL_ALLOC */
56 /* Always safe, but this is used as a GC test. */
61 wndclass.style = CS_HREDRAW | CS_VREDRAW;
62 wndclass.lpfnWndProc = WndProc;
63 wndclass.cbClsExtra = 0;
64 wndclass.cbWndExtra = DLGWINDOWEXTRA;
65 wndclass.hInstance = hInstance;
66 wndclass.hIcon = LoadIcon (hInstance, szAppName);
67 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
68 wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
69 wndclass.lpszMenuName = "DE";
70 wndclass.lpszClassName = szAppName;
72 if (RegisterClass (&wndclass) == 0) {
75 sprintf(buf, "RegisterClass: error code: 0x%X", GetLastError());
81 /* Empirically, the command line does not include the command name ...
82 if (command_line != 0) {
83 while (isspace(*command_line)) command_line++;
84 while (*command_line != 0 && !isspace(*command_line)) command_line++;
85 while (isspace(*command_line)) command_line++;
88 if (command_line == 0 || *command_line == 0) {
89 de_error("File name argument required");
92 char *p = command_line;
94 while (*p != 0 && !isspace(*p)) p++;
95 arg_file_name = CORD_to_char_star(
96 CORD_substr(command_line, 0, p - command_line));
99 hwnd = CreateWindow (szAppName,
101 WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
102 CW_USEDEFAULT, 0, /* default pos. */
103 CW_USEDEFAULT, 0, /* default width, height */
104 NULL, /* No parent */
105 NULL, /* Window class menu */
110 sprintf(buf, "CreateWindow: error code: 0x%X", GetLastError());
115 ShowWindow (hwnd, nCmdShow);
117 hAccel = LoadAccelerators( hInstance, szAppName );
119 while (GetMessage (&msg, NULL, 0, 0))
121 if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
123 TranslateMessage (&msg);
124 DispatchMessage (&msg);
130 /* Return the argument with all control characters replaced by blanks. */
131 char * plain_chars(char * text, size_t len)
133 char * result = GC_MALLOC_ATOMIC(len + 1);
136 for (i = 0; i < len; i++) {
137 if (iscntrl(text[i])) {
147 /* Return the argument with all non-control-characters replaced by */
148 /* blank, and all control characters c replaced by c + 32. */
149 char * control_chars(char * text, size_t len)
151 char * result = GC_MALLOC_ATOMIC(len + 1);
154 for (i = 0; i < len; i++) {
155 if (iscntrl(text[i])) {
156 result[i] = text[i] + 0x40;
168 void get_line_rect(int line, int win_width, RECT * rectp)
170 rectp -> top = line * char_height;
171 rectp -> bottom = rectp->top + char_height;
173 rectp -> right = win_width;
176 int caret_visible = 0; /* Caret is currently visible. */
178 int screen_was_painted = 0;/* Screen has been painted at least once. */
180 void update_cursor(void);
182 INT_PTR CALLBACK AboutBoxCallback( HWND hDlg, UINT message,
183 WPARAM wParam, LPARAM lParam )
188 SetFocus( GetDlgItem( hDlg, IDOK ) );
195 EndDialog( hDlg, TRUE );
201 EndDialog( hDlg, TRUE );
208 LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
209 WPARAM wParam, LPARAM lParam)
211 static HANDLE hInstance;
224 hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
226 SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
227 GetTextMetrics(dc, &tm);
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;
238 if (wParam == QUIT) {
239 SendMessage( hwnd, WM_CLOSE, 0, 0L );
241 do_command((int)wParam);
246 CreateCaret(hwnd, NULL, char_width, char_height);
260 unsigned xpos = LOWORD(lParam); /* From left */
261 unsigned ypos = HIWORD(lParam); /* from top */
263 set_position( xpos/char_width, ypos/char_height );
269 if (id & EDIT_CMD_FLAG) {
270 if (id & REPEAT_FLAG) do_command(REPEAT);
271 do_command(CHAR_CMD(id));
276 SendMessage( hwnd, WM_CLOSE, 0, 0L );
280 if( DialogBox( hInstance, "ABOUTBOX",
281 hwnd, AboutBoxCallback ) )
282 InvalidateRect( hwnd, NULL, TRUE );
284 case IDM_HELPCONTENTS:
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");
295 DestroyWindow( hwnd );
300 GC_win32_free_heap();
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(' ',
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,
327 TextOut(dc, this_line.left + (int)len * char_width,
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));
337 screen_was_painted = 1;
340 return DefWindowProc (hwnd, message, wParam, lParam);
346 void move_cursor(int c, int l)
351 if (caret_visible) update_cursor();
354 void update_cursor(void)
356 SetCaretPos(last_col * char_width, last_line * char_height);
360 void invalidate_line(int i)
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);