2004-11-08 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / boehm-gc / cord / de_win.c
blob0bbd676a3355d226eaf9e3d56895c7b9f6c95340
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.
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.
25 #include "windows.h"
26 #include "gc.h"
27 #include "cord.h"
28 #include "de_cmds.h"
29 #include "de_win.h"
31 int LINES = 0;
32 int COLS = 0;
34 char szAppName[] = "DE";
35 char FullAppName[] = "Demonstration Editor";
37 HWND hwnd;
39 void de_error(char *s)
41 MessageBox( hwnd, (LPSTR) s,
42 (LPSTR) FullAppName,
43 MB_ICONINFORMATION | MB_OK );
44 InvalidateRect(hwnd, NULL, TRUE);
47 int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
48 LPSTR command_line, int nCmdShow)
50 MSG msg;
51 WNDCLASS wndclass;
52 HANDLE hAccel;
54 if (!hPrevInstance)
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;
67 if (RegisterClass (&wndclass) == 0) {
68 char buf[50];
70 sprintf(buf, "RegisterClass: error code: 0x%X", GetLastError());
71 de_error(buf);
72 return(0);
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 } */
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;
89 while (*p != 0 && !isspace(*p)) p++;
90 arg_file_name = CORD_to_char_star(
91 CORD_substr(command_line, 0, p - command_line));
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];
105 sprintf(buf, "CreateWindow: error code: 0x%X", GetLastError());
106 de_error(buf);
107 return(0);
110 ShowWindow (hwnd, nCmdShow);
112 hAccel = LoadAccelerators( hInstance, szAppName );
114 while (GetMessage (&msg, NULL, 0, 0))
116 if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
118 TranslateMessage (&msg);
119 DispatchMessage (&msg);
122 return msg.wParam;
125 /* Return the argument with all control characters replaced by blanks. */
126 char * plain_chars(char * text, size_t len)
128 char * result = GC_MALLOC_ATOMIC(len + 1);
129 register size_t i;
131 for (i = 0; i < len; i++) {
132 if (iscntrl(text[i])) {
133 result[i] = ' ';
134 } else {
135 result[i] = text[i];
138 result[len] = '\0';
139 return(result);
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)
146 char * result = GC_MALLOC_ATOMIC(len + 1);
147 register size_t i;
149 for (i = 0; i < len; i++) {
150 if (iscntrl(text[i])) {
151 result[i] = text[i] + 0x40;
152 } else {
153 result[i] = ' ';
156 result[len] = '\0';
157 return(result);
160 int char_width;
161 int char_height;
163 void get_line_rect(int line, int win_width, RECT * rectp)
165 rectp -> top = line * char_height;
166 rectp -> bottom = rectp->top + char_height;
167 rectp -> left = 0;
168 rectp -> right = win_width;
171 int caret_visible = 0; /* Caret is currently visible. */
173 int screen_was_painted = 0;/* Screen has been painted at least once. */
175 void update_cursor(void);
177 LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
178 WPARAM wParam, LPARAM lParam)
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;
191 switch (message)
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);
208 case WM_CHAR:
209 if (wParam == QUIT) {
210 SendMessage( hwnd, WM_CLOSE, 0, 0L );
211 } else {
212 do_command(wParam);
214 return(0);
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);
223 case WM_KILLFOCUS:
224 HideCaret(hwnd);
225 DestroyCaret();
226 caret_visible = 0;
227 return(0);
229 case WM_LBUTTONUP:
231 unsigned xpos = LOWORD(lParam); /* From left */
232 unsigned ypos = HIWORD(lParam); /* from top */
234 set_position( xpos/char_width, ypos/char_height );
235 return(0);
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 );
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 );
263 break;
265 case WM_CLOSE:
266 DestroyWindow( hwnd );
267 return 0;
269 case WM_DESTROY:
270 PostQuitMessage (0);
271 GC_win32_free_heap();
272 return 0;
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)
293 SetBkMode(dc, OPAQUE);
294 SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
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));
306 EndPaint(hwnd, &ps);
307 screen_was_painted = 1;
308 return 0;
310 return DefWindowProc (hwnd, message, wParam, lParam);
313 int last_col;
314 int last_line;
316 void move_cursor(int c, int l)
318 last_col = c;
319 last_line = l;
321 if (caret_visible) update_cursor();
324 void update_cursor(void)
326 SetCaretPos(last_col * char_width, last_line * char_height);
327 ShowCaret(hwnd);
330 void invalidate_line(int i)
332 RECT line;
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);
341 LRESULT CALLBACK AboutBox( HWND hDlg, UINT message,
342 WPARAM wParam, LPARAM lParam )
344 switch( message )
346 case WM_INITDIALOG:
347 SetFocus( GetDlgItem( hDlg, IDOK ) );
348 break;
350 case WM_COMMAND:
351 switch( wParam )
353 case IDOK:
354 EndDialog( hDlg, TRUE );
355 break;
357 break;
359 case WM_CLOSE:
360 EndDialog( hDlg, TRUE );
361 return TRUE;
364 return FALSE;