root/gc/cord/de_win.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. de_error
  2. WinMain
  3. plain_chars
  4. control_chars
  5. get_line_rect
  6. WndProc
  7. move_cursor
  8. update_cursor
  9. invalidate_line
  10. AboutBox

   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 

/* [<][>][^][v][top][bottom][index][help] */