Initial revision
This commit is contained in:
366
gc/cord/de_win.c
Normal file
366
gc/cord/de_win.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (c) 1994 by Xerox Corporation. All rights reserved.
|
||||
*
|
||||
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
|
||||
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
|
||||
*
|
||||
* Permission is hereby granted to use or copy this program
|
||||
* for any purpose, provided the above notices are retained on all copies.
|
||||
* Permission to modify the code and to distribute modified code is granted,
|
||||
* provided the above notices are retained, and a notice that the code was
|
||||
* modified is included with the above copyright notice.
|
||||
*/
|
||||
/* Boehm, February 6, 1995 12:29 pm PST */
|
||||
|
||||
/*
|
||||
* The MS Windows specific part of de.
|
||||
* This started as the generic Windows application template
|
||||
* made available by Rob Haack (rhaack@polaris.unm.edu), but
|
||||
* significant parts didn't survive to the final version.
|
||||
*
|
||||
* This was written by a nonexpert windows programmer.
|
||||
*/
|
||||
|
||||
|
||||
#include "windows.h"
|
||||
#include "gc.h"
|
||||
#include "cord.h"
|
||||
#include "de_cmds.h"
|
||||
#include "de_win.h"
|
||||
|
||||
int LINES = 0;
|
||||
int COLS = 0;
|
||||
|
||||
char szAppName[] = "DE";
|
||||
char FullAppName[] = "Demonstration Editor";
|
||||
|
||||
HWND hwnd;
|
||||
|
||||
void de_error(char *s)
|
||||
{
|
||||
MessageBox( hwnd, (LPSTR) s,
|
||||
(LPSTR) FullAppName,
|
||||
MB_ICONINFORMATION | MB_OK );
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
}
|
||||
|
||||
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPSTR command_line, int nCmdShow)
|
||||
{
|
||||
MSG msg;
|
||||
WNDCLASS wndclass;
|
||||
HANDLE hAccel;
|
||||
|
||||
if (!hPrevInstance)
|
||||
{
|
||||
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wndclass.lpfnWndProc = WndProc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = DLGWINDOWEXTRA;
|
||||
wndclass.hInstance = hInstance;
|
||||
wndclass.hIcon = LoadIcon (hInstance, szAppName);
|
||||
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
wndclass.lpszMenuName = "DE";
|
||||
wndclass.lpszClassName = szAppName;
|
||||
|
||||
if (RegisterClass (&wndclass) == 0) {
|
||||
char buf[50];
|
||||
|
||||
sprintf(buf, "RegisterClass: error code: 0x%X", GetLastError());
|
||||
de_error(buf);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Empirically, the command line does not include the command name ...
|
||||
if (command_line != 0) {
|
||||
while (isspace(*command_line)) command_line++;
|
||||
while (*command_line != 0 && !isspace(*command_line)) command_line++;
|
||||
while (isspace(*command_line)) command_line++;
|
||||
} */
|
||||
|
||||
if (command_line == 0 || *command_line == 0) {
|
||||
de_error("File name argument required");
|
||||
return( 0 );
|
||||
} else {
|
||||
char *p = command_line;
|
||||
|
||||
while (*p != 0 && !isspace(*p)) p++;
|
||||
arg_file_name = CORD_to_char_star(
|
||||
CORD_substr(command_line, 0, p - command_line));
|
||||
}
|
||||
|
||||
hwnd = CreateWindow (szAppName,
|
||||
FullAppName,
|
||||
WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
|
||||
CW_USEDEFAULT, 0, /* default pos. */
|
||||
CW_USEDEFAULT, 0, /* default width, height */
|
||||
NULL, /* No parent */
|
||||
NULL, /* Window class menu */
|
||||
hInstance, NULL);
|
||||
if (hwnd == NULL) {
|
||||
char buf[50];
|
||||
|
||||
sprintf(buf, "CreateWindow: error code: 0x%X", GetLastError());
|
||||
de_error(buf);
|
||||
return(0);
|
||||
}
|
||||
|
||||
ShowWindow (hwnd, nCmdShow);
|
||||
|
||||
hAccel = LoadAccelerators( hInstance, szAppName );
|
||||
|
||||
while (GetMessage (&msg, NULL, 0, 0))
|
||||
{
|
||||
if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
|
||||
{
|
||||
TranslateMessage (&msg);
|
||||
DispatchMessage (&msg);
|
||||
}
|
||||
}
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
/* Return the argument with all control characters replaced by blanks. */
|
||||
char * plain_chars(char * text, size_t len)
|
||||
{
|
||||
char * result = GC_MALLOC_ATOMIC(len + 1);
|
||||
register size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (iscntrl(text[i])) {
|
||||
result[i] = ' ';
|
||||
} else {
|
||||
result[i] = text[i];
|
||||
}
|
||||
}
|
||||
result[len] = '\0';
|
||||
return(result);
|
||||
}
|
||||
|
||||
/* Return the argument with all non-control-characters replaced by */
|
||||
/* blank, and all control characters c replaced by c + 32. */
|
||||
char * control_chars(char * text, size_t len)
|
||||
{
|
||||
char * result = GC_MALLOC_ATOMIC(len + 1);
|
||||
register size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (iscntrl(text[i])) {
|
||||
result[i] = text[i] + 0x40;
|
||||
} else {
|
||||
result[i] = ' ';
|
||||
}
|
||||
}
|
||||
result[len] = '\0';
|
||||
return(result);
|
||||
}
|
||||
|
||||
int char_width;
|
||||
int char_height;
|
||||
|
||||
void get_line_rect(int line, int win_width, RECT * rectp)
|
||||
{
|
||||
rectp -> top = line * char_height;
|
||||
rectp -> bottom = rectp->top + char_height;
|
||||
rectp -> left = 0;
|
||||
rectp -> right = win_width;
|
||||
}
|
||||
|
||||
int caret_visible = 0; /* Caret is currently visible. */
|
||||
|
||||
int screen_was_painted = 0;/* Screen has been painted at least once. */
|
||||
|
||||
void update_cursor(void);
|
||||
|
||||
LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static FARPROC lpfnAboutBox;
|
||||
static HANDLE hInstance;
|
||||
HDC dc;
|
||||
PAINTSTRUCT ps;
|
||||
RECT client_area;
|
||||
RECT this_line;
|
||||
RECT dummy;
|
||||
TEXTMETRIC tm;
|
||||
register int i;
|
||||
int id;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
|
||||
lpfnAboutBox = MakeProcInstance( (FARPROC) AboutBox, hInstance );
|
||||
dc = GetDC(hwnd);
|
||||
SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
|
||||
GetTextMetrics(dc, &tm);
|
||||
ReleaseDC(hwnd, dc);
|
||||
char_width = tm.tmAveCharWidth;
|
||||
char_height = tm.tmHeight + tm.tmExternalLeading;
|
||||
GetClientRect(hwnd, &client_area);
|
||||
COLS = (client_area.right - client_area.left)/char_width;
|
||||
LINES = (client_area.bottom - client_area.top)/char_height;
|
||||
generic_init();
|
||||
return(0);
|
||||
|
||||
case WM_CHAR:
|
||||
if (wParam == QUIT) {
|
||||
SendMessage( hwnd, WM_CLOSE, 0, 0L );
|
||||
} else {
|
||||
do_command(wParam);
|
||||
}
|
||||
return(0);
|
||||
|
||||
case WM_SETFOCUS:
|
||||
CreateCaret(hwnd, NULL, char_width, char_height);
|
||||
ShowCaret(hwnd);
|
||||
caret_visible = 1;
|
||||
update_cursor();
|
||||
return(0);
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
HideCaret(hwnd);
|
||||
DestroyCaret();
|
||||
caret_visible = 0;
|
||||
return(0);
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
unsigned xpos = LOWORD(lParam); /* From left */
|
||||
unsigned ypos = HIWORD(lParam); /* from top */
|
||||
|
||||
set_position( xpos/char_width, ypos/char_height );
|
||||
return(0);
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
id = LOWORD(wParam);
|
||||
if (id & EDIT_CMD_FLAG) {
|
||||
if (id & REPEAT_FLAG) do_command(REPEAT);
|
||||
do_command(CHAR_CMD(id));
|
||||
return( 0 );
|
||||
} else {
|
||||
switch(id) {
|
||||
case IDM_FILEEXIT:
|
||||
SendMessage( hwnd, WM_CLOSE, 0, 0L );
|
||||
return( 0 );
|
||||
|
||||
case IDM_HELPABOUT:
|
||||
if( DialogBox( hInstance, "ABOUTBOX",
|
||||
hwnd, lpfnAboutBox ) );
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
return( 0 );
|
||||
case IDM_HELPCONTENTS:
|
||||
de_error(
|
||||
"Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"
|
||||
"Undo: ^U Write: ^W Quit:^D Repeat count: ^R[n]\n"
|
||||
"Top: ^T Locate (search, find): ^L text ^L\n");
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow( hwnd );
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage (0);
|
||||
GC_win32_free_heap();
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
dc = BeginPaint(hwnd, &ps);
|
||||
GetClientRect(hwnd, &client_area);
|
||||
COLS = (client_area.right - client_area.left)/char_width;
|
||||
LINES = (client_area.bottom - client_area.top)/char_height;
|
||||
SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
|
||||
for (i = 0; i < LINES; i++) {
|
||||
get_line_rect(i, client_area.right, &this_line);
|
||||
if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) {
|
||||
CORD raw_line = retrieve_screen_line(i);
|
||||
size_t len = CORD_len(raw_line);
|
||||
char * text = CORD_to_char_star(raw_line);
|
||||
/* May contain embedded NULLs */
|
||||
char * plain = plain_chars(text, len);
|
||||
char * blanks = CORD_to_char_star(CORD_chars(' ',
|
||||
COLS - len));
|
||||
char * control = control_chars(text, len);
|
||||
# define RED RGB(255,0,0)
|
||||
|
||||
SetBkMode(dc, OPAQUE);
|
||||
SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
|
||||
|
||||
TextOut(dc, this_line.left, this_line.top,
|
||||
plain, len);
|
||||
TextOut(dc, this_line.left + len * char_width, this_line.top,
|
||||
blanks, COLS - len);
|
||||
SetBkMode(dc, TRANSPARENT);
|
||||
SetTextColor(dc, RED);
|
||||
TextOut(dc, this_line.left, this_line.top,
|
||||
control, strlen(control));
|
||||
}
|
||||
}
|
||||
EndPaint(hwnd, &ps);
|
||||
screen_was_painted = 1;
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc (hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
int last_col;
|
||||
int last_line;
|
||||
|
||||
void move_cursor(int c, int l)
|
||||
{
|
||||
last_col = c;
|
||||
last_line = l;
|
||||
|
||||
if (caret_visible) update_cursor();
|
||||
}
|
||||
|
||||
void update_cursor(void)
|
||||
{
|
||||
SetCaretPos(last_col * char_width, last_line * char_height);
|
||||
ShowCaret(hwnd);
|
||||
}
|
||||
|
||||
void invalidate_line(int i)
|
||||
{
|
||||
RECT line;
|
||||
|
||||
if (!screen_was_painted) return;
|
||||
/* Invalidating a rectangle before painting seems result in a */
|
||||
/* major performance problem. */
|
||||
get_line_rect(i, COLS*char_width, &line);
|
||||
InvalidateRect(hwnd, &line, FALSE);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK AboutBox( HWND hDlg, UINT message,
|
||||
WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch( message )
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
SetFocus( GetDlgItem( hDlg, IDOK ) );
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch( wParam )
|
||||
{
|
||||
case IDOK:
|
||||
EndDialog( hDlg, TRUE );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
EndDialog( hDlg, TRUE );
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user