aboutsummaryrefslogtreecommitdiffstats
path: root/gc/cord/de_win.c
diff options
context:
space:
mode:
Diffstat (limited to 'gc/cord/de_win.c')
-rw-r--r--gc/cord/de_win.c366
1 files changed, 366 insertions, 0 deletions
diff --git a/gc/cord/de_win.c b/gc/cord/de_win.c
new file mode 100644
index 0000000..fedbfbe
--- /dev/null
+++ b/gc/cord/de_win.c
@@ -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;
+}
+