Annotation of OpenXM_contrib/gc/cord/de_win.c, Revision 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>