Annotation of OpenXM_contrib/gc/cord/de_win.c, Revision 1.1.1.1
1.1 maekawa 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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>