summaryrefslogtreecommitdiff
path: root/erts/emulator/drivers/win32/win_con.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/drivers/win32/win_con.c')
-rw-r--r--erts/emulator/drivers/win32/win_con.c2355
1 files changed, 0 insertions, 2355 deletions
diff --git a/erts/emulator/drivers/win32/win_con.c b/erts/emulator/drivers/win32/win_con.c
deleted file mode 100644
index 2e3c12dc58..0000000000
--- a/erts/emulator/drivers/win32/win_con.c
+++ /dev/null
@@ -1,2355 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2021. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-#define UNICODE 1
-#define _UNICODE 1
-#include <tchar.h>
-#include <stdio.h>
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "sys.h"
-#include <windowsx.h>
-#include "resource.h"
-#include "erl_version.h"
-#include <commdlg.h>
-#include <commctrl.h>
-#include "erl_driver.h"
-#include "win_con.h"
-
-#define ALLOC(X) malloc(X)
-#define REALLOC(X,Y) realloc(X,Y)
-#define FREE(X) free(X)
-
-#if SIZEOF_VOID_P == 8
-#define WIN64 1
-#ifndef GCL_HBRBACKGROUND
-#define GCL_HBRBACKGROUND GCLP_HBRBACKGROUND
-#endif
-#define DIALOG_PROC_RET INT_PTR
-#define CF_HOOK_RET INT_PTR
-#define CC_HOOK_RET INT_PTR
-#define OFN_HOOK_RET INT_PTR
-#else
-#define DIALOG_PROC_RET BOOL
-#define CF_HOOK_RET UINT
-#define CC_HOOK_RET UINT
-#define OFN_HOOK_RET UINT
-#endif
-
-
-#ifndef STATE_SYSTEM_INVISIBLE
-/* Mingw problem with oleacc.h and WIN32_LEAN_AND_MEAN */
-#define STATE_SYSTEM_INVISIBLE 0x00008000
-#endif
-
-#define WM_CONTEXT (0x0401)
-#define WM_CONBEEP (0x0402)
-#define WM_SAVE_PREFS (0x0403)
-
-#define USER_KEY TEXT("Software\\Ericsson\\Erlang\\") TEXT(ERLANG_VERSION)
-
-#define FRAME_HEIGHT ((2*GetSystemMetrics(SM_CYEDGE))+(2*GetSystemMetrics(SM_CYFRAME))+GetSystemMetrics(SM_CYCAPTION))
-#define FRAME_WIDTH (2*GetSystemMetrics(SM_CXFRAME)+(2*GetSystemMetrics(SM_CXFRAME))+GetSystemMetrics(SM_CXVSCROLL))
-
-#define LINE_LENGTH canvasColumns
-#define COL(_l) ((_l) % LINE_LENGTH)
-#define LINE(_l) ((_l) / LINE_LENGTH)
-
-#ifdef UNICODE
-/*
- * We use a character in the invalid unicode range
- */
-#define SET_CURSOR (0xD8FF)
-#else
-/*
- * XXX There is no escape to send a character 0x80. Fortunately,
- * the ttsl driver currently replaces 0x80 with an octal sequence.
- */
-#define SET_CURSOR (0x80)
-#endif
-
-#define SCAN_CODE_BREAK 0x46 /* scan code for Ctrl-Break */
-
-
-typedef struct ScreenLine_s {
- struct ScreenLine_s* next;
- struct ScreenLine_s* prev;
- int width;
-#ifdef HARDDEBUG
- int allocated;
-#endif
- int newline; /* Ends with hard newline: 1, wrapped at end: 0 */
- TCHAR *text;
-} ScreenLine_t;
-
-extern Uint32 *lbuf; /* The current line buffer */
-extern int llen; /* The current line length */
-extern int lpos;
-
-HANDLE console_input_event;
-HANDLE console_thread = NULL;
-
-#define DEF_CANVAS_COLUMNS 80
-#define DEF_CANVAS_ROWS 26
-
-#define BUFSIZE 4096
-#define MAXBUFSIZE 32768
-typedef struct {
- TCHAR *data;
- int size;
- int wrPos;
- int rdPos;
-} buffer_t;
-
-static buffer_t inbuf;
-static buffer_t outbuf;
-
-static CHOOSEFONT cf;
-
-static TCHAR szFrameClass[] = TEXT("FrameClass");
-static TCHAR szClientClass[] = TEXT("ClientClass");
-static HWND hFrameWnd;
-static HWND hClientWnd;
-static HWND hTBWnd;
-static HWND hComboWnd;
-static HANDLE console_input;
-static HANDLE console_output;
-static int cxChar,cyChar, cxCharMax;
-static int cxClient,cyClient;
-static int cyToolBar;
-static int iVscrollPos,iHscrollPos;
-static int iVscrollMax,iHscrollMax;
-static int nBufLines;
-static int cur_x;
-static int cur_y;
-static int canvasColumns = DEF_CANVAS_COLUMNS;
-static int canvasRows = DEF_CANVAS_ROWS;
-static ScreenLine_t *buffer_top,*buffer_bottom;
-static ScreenLine_t* cur_line;
-static POINT editBeg,editEnd;
-static BOOL fSelecting = FALSE;
-static BOOL fTextSelected = FALSE;
-static HKEY key;
-static BOOL has_key = FALSE;
-static LOGFONT logfont;
-static DWORD fgColor;
-static DWORD bkgColor;
-static FILE *logfile = NULL;
-static RECT winPos;
-static BOOL toolbarVisible;
-static BOOL destroyed = FALSE;
-
-static int lines_to_save = 10000; /* Maximum number of screen lines to save. */
-
-#define TITLE_BUF_SZ 256
-
-struct title_buf {
- TCHAR *name;
- TCHAR buf[TITLE_BUF_SZ];
-};
-
-static TCHAR *erlang_window_title = TEXT("Erlang");
-
-static unsigned __stdcall ConThreadInit(LPVOID param);
-static LRESULT CALLBACK ClientWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
-static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
-static DIALOG_PROC_RET CALLBACK AboutDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam);
-static ScreenLine_t *ConNewLine(void);
-static void DeleteTopLine(void);
-static void ensure_line_below(void);
-static ScreenLine_t *GetLineFromY(int y);
-static void LoadUserPreferences(void);
-static void SaveUserPreferences(void);
-static void set_scroll_info(HWND hwnd);
-static void ConCarriageFeed(int);
-static void ConScrollScreen(void);
-static BOOL ConChooseFont(HWND hwnd);
-static void ConFontInitialize(HWND hwnd);
-static void ConSetFont(HWND hwnd);
-static void ConChooseColor(HWND hwnd);
-static void DrawSelection(HWND hwnd, POINT pt1, POINT pt2);
-static void InvertSelectionArea(HWND hwnd);
-static void OnEditCopy(HWND hwnd);
-static void OnEditPaste(HWND hwnd);
-static void OnEditSelAll(HWND hwnd);
-static void GetFileName(HWND hwnd, TCHAR *pFile);
-static void OpenLogFile(HWND hwnd);
-static void CloseLogFile(HWND hwnd);
-static void LogFileWrite(TCHAR *buf, int n);
-static int write_inbuf(TCHAR *data, int n);
-static void init_buffers(void);
-static void AddToCmdHistory(void);
-static int write_outbuf(TCHAR *data, int num_chars);
-static void ConDrawText(HWND hwnd);
-static BOOL (WINAPI *ctrl_handler)(DWORD);
-static HWND InitToolBar(HWND hwndParent);
-static void window_title(struct title_buf *);
-static void free_window_title(struct title_buf *);
-static void Client_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags);
-
-#ifdef HARDDEBUG
-/* For really hard GUI startup debugging, place DEBUGBOX() macros in code
- and get modal message boxes with the line number. */
-static void debug_box(int line) {
- TCHAR buff[1024];
- swprintf(buff,1024,TEXT("DBG:%d"),line);
- MessageBox(NULL,buff,TEXT("DBG"),MB_OK|MB_APPLMODAL);
-}
-
-#define DEBUGBOX() debug_box(__LINE__)
-#endif
-
-#define CON_VPRINTF_BUF_INC_SIZE 1024
-
-static erts_dsprintf_buf_t *
-grow_con_vprintf_buf(erts_dsprintf_buf_t *dsbufp, size_t need)
-{
- char *buf;
- size_t size;
-
- ASSERT(dsbufp);
-
- if (!dsbufp->str) {
- size = (((need + CON_VPRINTF_BUF_INC_SIZE - 1)
- / CON_VPRINTF_BUF_INC_SIZE)
- * CON_VPRINTF_BUF_INC_SIZE);
- buf = (char *) ALLOC(size * sizeof(char));
- }
- else {
- size_t free_size = dsbufp->size - dsbufp->str_len;
-
- if (need <= free_size)
- return dsbufp;
-
- size = need - free_size + CON_VPRINTF_BUF_INC_SIZE;
- size = (((size + CON_VPRINTF_BUF_INC_SIZE - 1)
- / CON_VPRINTF_BUF_INC_SIZE)
- * CON_VPRINTF_BUF_INC_SIZE);
- size += dsbufp->size;
- buf = (char *) REALLOC((void *) dsbufp->str,
- size * sizeof(char));
- }
- if (!buf)
- return NULL;
- if (buf != dsbufp->str)
- dsbufp->str = buf;
- dsbufp->size = size;
- return dsbufp;
-}
-
-static int con_vprintf(char *format, va_list arg_list)
-{
- int res,i;
- erts_dsprintf_buf_t dsbuf = ERTS_DSPRINTF_BUF_INITER(grow_con_vprintf_buf);
- res = erts_vdsprintf(&dsbuf, format, arg_list);
- if (res >= 0) {
- TCHAR *tmp = ALLOC(dsbuf.str_len*sizeof(TCHAR));
- for (i=0;i<dsbuf.str_len;++i) {
- tmp[i] = dsbuf.str[i];
- }
- write_outbuf(tmp, dsbuf.str_len);
- FREE(tmp);
- }
- if (dsbuf.str)
- FREE((void *) dsbuf.str);
- return res;
-}
-
-void
-ConInit(void)
-{
- unsigned tid;
-
- console_input = CreateSemaphore(NULL, 0, 1, NULL);
- console_output = CreateSemaphore(NULL, 0, 1, NULL);
- console_input_event = CreateManualEvent(FALSE);
- console_thread = (HANDLE *) _beginthreadex(NULL, 0,
- ConThreadInit,
- 0, 0, &tid);
-
- /* Make all erts_*printf on stdout and stderr use con_vprintf */
- erts_printf_stdout_func = con_vprintf;
- erts_printf_stderr_func = con_vprintf;
-}
-
-/*
- ConNormalExit() is called from erts_exit() when the emulator
- is stopping. If the exit has not been initiated by this
- console thread (WM_DESTROY or ID_BREAK), the function must
- invoke the console thread to save the user preferences.
-*/
-void
-ConNormalExit(void)
-{
- if (!destroyed)
- SendMessage(hFrameWnd, WM_SAVE_PREFS, 0L, 0L);
-}
-
-void
-ConWaitForExit(void)
-{
- ConPrintf("\n\nAbnormal termination\n");
- WaitForSingleObject(console_thread, INFINITE);
-}
-
-void ConSetCtrlHandler(BOOL (WINAPI *handler)(DWORD))
-{
- ctrl_handler = handler;
-}
-
-int ConPutChar(Uint32 c)
-{
- TCHAR sbuf[1];
-#ifdef HARDDEBUG
- fprintf(stderr,"ConPutChar: %d\n",(int) c);
- fflush(stderr);
-#endif
- sbuf[0] = c;
- write_outbuf(sbuf, 1);
- return 1;
-}
-
-static int GetXFromLine(HDC hdc, int hscroll, int xpos,ScreenLine_t *pLine)
-{
- SIZE size;
- int hscrollPix = hscroll * cxChar;
-
- if (pLine == NULL) {
- return 0;
- }
-
- if (pLine->width < xpos) {
- return (canvasColumns-hscroll)*cxChar;
- }
- /* Not needed (?): SelectObject(hdc,CreateFontIndirect(&logfont)); */
- if (GetTextExtentPoint32(hdc,pLine->text,xpos,&size)) {
-#ifdef HARDDEBUG
- fprintf(stderr,"size.cx:%d\n",(int)size.cx);
- fflush(stderr);
-#endif
- if (hscrollPix >= size.cx) {
- return 0;
- }
- return ((int) size.cx) - hscrollPix;
- } else {
- return (xpos-hscroll)*cxChar;
- }
-}
-
-static int GetXFromCurrentY(HDC hdc, int hscroll, int xpos) {
- return GetXFromLine(hdc, hscroll, xpos, GetLineFromY(cur_y));
-}
-
-void ConSetCursor(int from, int to)
-{ TCHAR cmd[9];
- int *p;
- //DebugBreak();
- cmd[0] = SET_CURSOR;
- /*
- * XXX Expect trouble on CPUs which don't allow misaligned read and writes.
- */
- p = (int *)&cmd[1];
- *p++ = from;
- *p = to;
- write_outbuf(cmd, 1 + (2*sizeof(int)/sizeof(TCHAR)));
-}
-
-void ConPrintf(char *format, ...)
-{
- va_list va;
-
- va_start(va, format);
- (void) con_vprintf(format, va);
- va_end(va);
-}
-
-void ConBeep(void)
-{
- SendMessage(hClientWnd, WM_CONBEEP, 0L, 0L);
-}
-
-int ConReadInput(Uint32 *data, int num_chars)
-{
- TCHAR *buf;
- int nread;
- WaitForSingleObject(console_input,INFINITE);
- nread = num_chars = min(num_chars,inbuf.wrPos-inbuf.rdPos);
- buf = &inbuf.data[inbuf.rdPos];
- inbuf.rdPos += nread;
- while (nread--)
- *data++ = *buf++;
- if (inbuf.rdPos >= inbuf.wrPos) {
- inbuf.rdPos = 0;
- inbuf.wrPos = 0;
- ResetEvent(console_input_event);
- }
- ReleaseSemaphore(console_input,1,NULL);
- return num_chars;
-}
-
-int ConGetKey(void)
-{
- Uint32 c;
- WaitForSingleObject(console_input,INFINITE);
- ResetEvent(console_input_event);
- inbuf.rdPos = inbuf.wrPos = 0;
- ReleaseSemaphore(console_input,1,NULL);
- WaitForSingleObject(console_input_event,INFINITE);
- ConReadInput(&c, 1);
- return (int) c;
-}
-
-int ConGetColumns(void)
-{
- return (int) canvasColumns; /* 32bit atomic on windows */
-}
-
-int ConGetRows(void) {
- return (int) canvasRows;
-}
-
-
-static HINSTANCE hInstance;
-extern HMODULE beam_module;
-
-static unsigned __stdcall
-ConThreadInit(LPVOID param)
-{
- MSG msg;
- WNDCLASSEX wndclass;
- int iCmdShow;
- STARTUPINFO StartupInfo;
- HACCEL hAccel;
- int x, y, w, h;
- struct title_buf title;
-
- /*DebugBreak();*/
-#ifdef HARDDEBUG
- if(AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
- freopen("CONOUT$", "w", stdout);
- freopen("CONOUT$", "w", stderr);
- }
-#endif
-
- hInstance = GetModuleHandle(NULL);
- StartupInfo.dwFlags = 0;
- GetStartupInfo(&StartupInfo);
- iCmdShow = StartupInfo.dwFlags & STARTF_USESHOWWINDOW ?
- StartupInfo.wShowWindow : SW_SHOWDEFAULT;
-
- LoadUserPreferences();
-
- /* frame window class */
- wndclass.cbSize = sizeof (wndclass);
- wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNCLIENT;
- wndclass.lpfnWndProc = FrameWndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(1));
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
- wndclass.hbrBackground = NULL;
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szFrameClass;
- wndclass.hIconSm = LoadIcon (hInstance, MAKEINTRESOURCE(1));
- RegisterClassExW (&wndclass);
-
- /* client window class */
- wndclass.cbSize = sizeof (wndclass);
- wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- wndclass.lpfnWndProc = ClientWndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(1));
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
- wndclass.hbrBackground = CreateSolidBrush(bkgColor);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szClientClass;
- wndclass.hIconSm = LoadIcon (hInstance, MAKEINTRESOURCE(1));
- RegisterClassExW (&wndclass);
-
- InitCommonControls();
- init_buffers();
-
- nBufLines = 0;
- buffer_top = cur_line = ConNewLine();
- cur_line->next = buffer_bottom = ConNewLine();
- buffer_bottom->prev = cur_line;
-
- /* Create Frame Window */
- window_title(&title);
- hFrameWnd = CreateWindowEx(0, szFrameClass, title.name,
- WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
- CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
- NULL,LoadMenu(beam_module,MAKEINTRESOURCE(1)),
- hInstance,NULL);
- free_window_title(&title);
-
- /* XXX OTP-5522:
- The window position is not saved correctly and if the window
- is closed when minimized, it's not possible to start werl again
- with the window open. Temporary fix so far is to ignore saved values
- and always start with initial settings. */
- /* Original: if (winPos.left == -1) { */
- /* Temporary: if (1) { */
- if (1) {
-
- /* initial window position */
- x = 0;
- y = 0;
- w = cxChar*LINE_LENGTH+FRAME_WIDTH+GetSystemMetrics(SM_CXVSCROLL);
- h = cyChar*30+FRAME_HEIGHT;
- } else {
- /* saved window position */
- x = winPos.left;
- y = winPos.top;
- w = winPos.right - x;
- h = winPos.bottom - y;
- }
- SetWindowPos(hFrameWnd, NULL, x, y, w, h, SWP_NOZORDER);
-
- ShowWindow(hFrameWnd, iCmdShow);
- UpdateWindow(hFrameWnd);
-
- hAccel = LoadAccelerators(beam_module,MAKEINTRESOURCE(1));
-
- ReleaseSemaphore(console_input, 1, NULL);
- ReleaseSemaphore(console_output, 1, NULL);
-
-
- /* Main message loop */
- while (GetMessage (&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator(hFrameWnd,hAccel,&msg))
- {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
- }
- /*
- PostQuitMessage() results in WM_QUIT which makes GetMessage()
- return 0 (which stops the main loop). Before we return from
- the console thread, the ctrl_handler is called to do erts_exit.
- */
- (*ctrl_handler)(CTRL_CLOSE_EVENT);
- return msg.wParam;
-}
-
-static LRESULT CALLBACK
-FrameWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
-{
- RECT r;
- int cy,i,bufsize;
- TCHAR c;
- unsigned long l;
- TCHAR buf[128];
- struct title_buf title;
-
- switch (iMsg) {
- case WM_CREATE:
- /* client window creation */
- window_title(&title);
- hClientWnd = CreateWindowEx(0, szClientClass, title.name,
- WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- hwnd, (HMENU)0, hInstance, NULL);
- free_window_title(&title);
- hTBWnd = InitToolBar(hwnd);
- UpdateWindow (hClientWnd);
- return 0;
- case WM_SIZE :
- if (IsWindowVisible(hTBWnd)) {
- SendMessage(hTBWnd,TB_AUTOSIZE,0,0L);
- GetWindowRect(hTBWnd,&r);
- cy = r.bottom-r.top;
- } else cy = 0;
- MoveWindow(hClientWnd,0,cy,LOWORD(lParam),HIWORD(lParam)-cy,TRUE);
- return 0;
- case WM_ERASEBKGND:
- return 1;
- case WM_SETFOCUS :
- CreateCaret(hClientWnd, NULL, cxChar, cyChar);
- SetCaretPos(GetXFromCurrentY(GetDC(hClientWnd),iHscrollPos,cur_x), (cur_y-iVscrollPos)*cyChar);
- ShowCaret(hClientWnd);
- return 0;
- case WM_KILLFOCUS:
- HideCaret(hClientWnd);
- DestroyCaret();
- return 0;
- case WM_INITMENUPOPUP :
- if (lParam == 0) /* File popup menu */
- {
- EnableMenuItem((HMENU)wParam, IDMENU_STARTLOG,
- logfile ? MF_GRAYED : MF_ENABLED);
- EnableMenuItem((HMENU)wParam, IDMENU_STOPLOG,
- logfile ? MF_ENABLED : MF_GRAYED);
- return 0;
- }
- else if (lParam == 1) /* Edit popup menu */
- {
- EnableMenuItem((HMENU)wParam, IDMENU_COPY,
- fTextSelected ? MF_ENABLED : MF_GRAYED);
- EnableMenuItem((HMENU)wParam, IDMENU_PASTE,
- IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED);
- return 0;
- }
- else if (lParam == 3) /* View popup menu */
- {
- CheckMenuItem((HMENU)wParam,IDMENU_TOOLBAR,
- IsWindowVisible(hTBWnd) ? MF_CHECKED : MF_UNCHECKED);
- return 0;
- }
- break;
- case WM_NOTIFY:
- switch (((LPNMHDR) lParam)->code) {
- case TTN_NEEDTEXT:
- {
- LPTOOLTIPTEXT lpttt;
- lpttt = (LPTOOLTIPTEXT) lParam;
- lpttt->hinst = hInstance;
- /* check for combobox handle */
- if (lpttt->uFlags&TTF_IDISHWND) {
- if ((lpttt->hdr.idFrom == (UINT_PTR) hComboWnd)) {
- lstrcpy(lpttt->lpszText,TEXT("Command History"));
- break;
- }
- }
- /* check for toolbar buttons */
- switch (lpttt->hdr.idFrom) {
- case IDMENU_COPY:
- lstrcpy(lpttt->lpszText,TEXT("Copy (Ctrl+C)"));
- break;
- case IDMENU_PASTE:
- lstrcpy(lpttt->lpszText,TEXT("Paste (Ctrl+V)"));
- break;
- case IDMENU_FONT:
- lstrcpy(lpttt->lpszText,TEXT("Fonts"));
- break;
- case IDMENU_ABOUT:
- lstrcpy(lpttt->lpszText,TEXT("Help"));
- break;
- }
- }
- }
- break;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDMENU_STARTLOG:
- OpenLogFile(hwnd);
- return 0;
- case IDMENU_STOPLOG:
- CloseLogFile(hwnd);
- return 0;
- case IDMENU_EXIT:
- SendMessage(hwnd, WM_CLOSE, 0, 0L);
- return 0;
- case IDMENU_COPY:
- if (fTextSelected)
- OnEditCopy(hClientWnd);
- return 0;
- case IDMENU_PASTE:
- OnEditPaste(hClientWnd);
- return 0;
- case IDMENU_SELALL:
- OnEditSelAll(hClientWnd);
- return 0;
- case IDMENU_FONT:
- if (ConChooseFont(hClientWnd)) {
- ConSetFont(hClientWnd);
- }
- SaveUserPreferences();
- return 0;
- case IDMENU_SELECTBKG:
- ConChooseColor(hClientWnd);
- SaveUserPreferences();
- return 0;
- case IDMENU_TOOLBAR:
- if (toolbarVisible) {
- ShowWindow(hTBWnd,SW_HIDE);
- toolbarVisible = FALSE;
- } else {
- ShowWindow(hTBWnd,SW_SHOW);
- toolbarVisible = TRUE;
- }
- GetClientRect(hwnd,&r);
- PostMessage(hwnd,WM_SIZE,0,MAKELPARAM(r.right,r.bottom));
- return 0;
- case IDMENU_ABOUT:
- DialogBox(beam_module,TEXT("AboutBox"),hwnd,AboutDlgProc);
- return 0;
- case ID_COMBOBOX:
- switch (HIWORD(wParam)) {
- case CBN_SELENDOK:
- i = SendMessage(hComboWnd,CB_GETCURSEL,0,0);
- if (i != CB_ERR) {
- buf[0] = 0x01; /* CTRL+A */
- buf[1] = 0x0B; /* CTRL+K */
- bufsize = SendMessage(hComboWnd,CB_GETLBTEXT,i,(LPARAM)&buf[2]);
- if (bufsize != CB_ERR)
- write_inbuf(buf,bufsize+2);
- SetFocus(hwnd);
- }
- break;
- case CBN_SELENDCANCEL:
- break;
- }
- break;
- case ID_BREAK: /* CTRL+BRK */
- /* pass on break char if the ctrl_handler is disabled */
- if ((*ctrl_handler)(CTRL_C_EVENT) == FALSE) {
- c = 0x03;
- write_inbuf(&c,1);
- }
- return 0;
- }
- break;
- case WM_KEYDOWN :
- switch (wParam) {
- case VK_UP: c = 'P'-'@'; break;
- case VK_DOWN : c = 'N'-'@'; break;
- case VK_RIGHT : c = 'F'-'@'; break;
- case VK_LEFT : c = 'B'-'@'; break;
- case VK_DELETE : c = 'D' -'@'; break;
- case VK_HOME : c = 'A'-'@'; break;
- case VK_END : c = 'E'-'@'; break;
- case VK_RETURN : AddToCmdHistory(); return 0;
- case VK_PRIOR : /* PageUp */
- PostMessage(hClientWnd, WM_VSCROLL, SB_PAGEUP, 0);
- return 0;
- case VK_NEXT : /* PageDown */
- PostMessage(hClientWnd, WM_VSCROLL, SB_PAGEDOWN, 0);
- return 0;
- default: return 0;
- }
- write_inbuf(&c, 1);
- return 0;
- case WM_MOUSEWHEEL:
- {
- int delta = GET_WHEEL_DELTA_WPARAM(wParam);
- if (delta < 0) {
- PostMessage(hClientWnd, WM_VSCROLL, MAKELONG(SB_THUMBTRACK,
- (iVscrollPos + 5)),0);
- } else {
- WORD pos = ((iVscrollPos - 5) < 0) ? 0 : (iVscrollPos - 5);
- PostMessage(hClientWnd, WM_VSCROLL, MAKELONG(SB_THUMBTRACK,pos),0);
- }
- return 0;
- }
- case WM_CHAR:
- c = (TCHAR)wParam;
- write_inbuf(&c,1);
- return 0;
- case WM_CLOSE :
- break;
- case WM_DESTROY :
- SaveUserPreferences();
- destroyed = TRUE;
- PostQuitMessage(0);
- return 0;
- case WM_SAVE_PREFS :
- SaveUserPreferences();
- return 0;
- }
- return DefWindowProc(hwnd, iMsg, wParam, lParam);
-}
-
-static BOOL
-Client_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
-{
- ConFontInitialize(hwnd);
- cur_x = cur_y = 0;
- iVscrollPos = 0;
- iHscrollPos = 0;
- return TRUE;
-}
-
-static void
-Client_OnPaint(HWND hwnd)
-{
- ScreenLine_t *pLine;
- int x,y,i,iTop,iBot;
- PAINTSTRUCT ps;
- RECT rcInvalid;
- HDC hdc;
-
- hdc = BeginPaint(hwnd, &ps);
- rcInvalid = ps.rcPaint;
- hdc = ps.hdc;
- iTop = max(0, iVscrollPos + rcInvalid.top/cyChar);
- iBot = min(nBufLines, iVscrollPos + rcInvalid.bottom/cyChar+1);
- pLine = GetLineFromY(iTop);
- for (i = iTop; i < iBot && pLine != NULL; i++) {
- y = cyChar*(i-iVscrollPos);
- x = -cxChar*iHscrollPos;
- TextOut(hdc, x, y, &pLine->text[0], pLine->width);
- pLine = pLine->next;
- }
- if (fTextSelected || fSelecting) {
- InvertSelectionArea(hwnd);
- }
- SetCaretPos(GetXFromCurrentY(hdc,iHscrollPos,cur_x), (cur_y-iVscrollPos)*cyChar);
- EndPaint(hwnd, &ps);
-}
-#ifdef HARDDEBUG
-static void dump_linebufs(void) {
- char *buff;
- ScreenLine_t *s = buffer_top;
- fprintf(stderr,"LinebufDump------------------------\n");
- while(s) {
- if (s == buffer_top) fprintf(stderr,"BT-> ");
- if (s == buffer_bottom) fprintf(stderr,"BB-> ");
- if (s == cur_line) fprintf(stderr,"CL-> ");
-
- buff = (char *) ALLOC(s->width+1);
- memcpy(buff,s->text,s->width);
- buff[s->width] = '\0';
- fprintf(stderr,"{\"%s\",%d,%d}\n",buff,s->newline,s->allocated);
- FREE(buff);
- s = s->next;
- }
- fprintf(stderr,"LinebufDumpEnd---------------------\n");
- fflush(stderr);
-}
-#endif
-
-static void reorganize_linebufs(HWND hwnd) {
- ScreenLine_t *otop = buffer_top;
- ScreenLine_t *obot = buffer_bottom;
- ScreenLine_t *next;
- int i,cpos;
-
- cpos = 0;
- i = nBufLines - cur_y;
- while (i > 1) {
- cpos += obot->width;
- obot = obot->prev;
- i--;
- }
- cpos += (obot->width - cur_x);
-#ifdef HARDDEBUG
- fprintf(stderr,"nBufLines = %d, cur_x = %d, cur_y = %d, cpos = %d\n",
- nBufLines,cur_x,cur_y,cpos);
- fflush(stderr);
-#endif
-
-
- nBufLines = 0;
- buffer_top = cur_line = ConNewLine();
- cur_line->next = buffer_bottom = ConNewLine();
- buffer_bottom->prev = cur_line;
-
- cur_x = cur_y = 0;
- iVscrollPos = 0;
- iHscrollPos = 0;
-
- while(otop) {
- for(i=0;i<otop->width;++i) {
- cur_line->text[cur_x] = otop->text[i];
- cur_x++;
- if (cur_x > cur_line->width)
- cur_line->width = cur_x;
- if (GetXFromCurrentY(GetDC(hwnd),0,cur_x) + cxChar >
- (LINE_LENGTH * cxChar)) {
- ConCarriageFeed(0);
- }
- }
- if (otop->newline) {
- ConCarriageFeed(1);
- /*ConScrollScreen();*/
- }
- next = otop->next;
- FREE(otop->text);
- FREE(otop);
- otop = next;
- }
- while (cpos) {
- cur_x--;
- if (cur_x < 0) {
- cur_y--;
- cur_line = cur_line->prev;
- cur_x = cur_line->width-1;
- }
- cpos--;
- }
- SetCaretPos(GetXFromCurrentY(GetDC(hwnd),iHscrollPos,cur_x), (cur_y-iVscrollPos)*cyChar);
-#ifdef HARDDEBUG
- fprintf(stderr,"canvasColumns = %d,nBufLines = %d, cur_x = %d, cur_y = %d\n",
- canvasColumns,nBufLines,cur_x,cur_y);
- fflush(stderr);
-#endif
-}
-
-
-static void
-Client_OnSize(HWND hwnd, UINT state, int cx, int cy)
-{
- RECT r;
- SCROLLBARINFO sbi;
- int w,h,columns;
- int scrollheight;
- cxClient = cx;
- cyClient = cy;
- set_scroll_info(hwnd);
- GetClientRect(hwnd,&r);
- w = r.right - r.left;
- h = r.bottom - r.top;
- sbi.cbSize = sizeof(SCROLLBARINFO);
- if (!GetScrollBarInfo(hwnd, OBJID_HSCROLL,&sbi) ||
- (sbi.rgstate[0] & STATE_SYSTEM_INVISIBLE)) {
- scrollheight = 0;
- } else {
- scrollheight = sbi.rcScrollBar.bottom - sbi.rcScrollBar.top;
- }
- canvasRows = (h - scrollheight) / cyChar;
- if (canvasRows < DEF_CANVAS_ROWS) {
- canvasRows = DEF_CANVAS_ROWS;
- }
- columns = (w - GetSystemMetrics(SM_CXVSCROLL)) /cxChar;
- if (columns < DEF_CANVAS_COLUMNS)
- columns = DEF_CANVAS_COLUMNS;
- if (columns != canvasColumns) {
- canvasColumns = columns;
- /*dump_linebufs();*/
- reorganize_linebufs(hwnd);
- fSelecting = fTextSelected = FALSE;
- InvalidateRect(hwnd, NULL, TRUE);
-#ifdef HARDDEBUG
- fprintf(stderr,"Paint: cols = %d, rows = %d\n",canvasColumns,canvasRows);
- fflush(stderr);
-#endif
- }
-
- SetCaretPos(GetXFromCurrentY(GetDC(hwnd),iHscrollPos,cur_x), (cur_y-iVscrollPos)*cyChar);
-}
-
-static void calc_charpoint_from_point(HDC dc, int x, int y, int y_offset, POINT *pt)
-{
- int r;
- int hscrollPix = iHscrollPos * cxChar;
-
- pt->y = y/cyChar + iVscrollPos + y_offset;
-
- if (x > (LINE_LENGTH-iHscrollPos) * cxChar) {
- x = (LINE_LENGTH-iHscrollPos) * cxChar;
- }
- if (pt->y - y_offset > 0 && GetLineFromY(pt->y - y_offset) == NULL) {
- pt->y = nBufLines - 1 + y_offset;
- pt->x = GetLineFromY(pt->y - y_offset)->width;
- } else {
- for (pt->x = 1;
- (r = GetXFromLine(dc, 0, pt->x, GetLineFromY(pt->y - y_offset))) != 0 &&
- (r - hscrollPix) < x;
- ++(pt->x))
- ;
- if ((r - hscrollPix) > x)
- --(pt->x);
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"pt->x = %d, iHscrollPos = %d\n",(int) pt->x, iHscrollPos);
- fflush(stderr);
-#endif
- if (pt->x <= 0) {
- pt->x = x/cxChar + iHscrollPos;
- }
- }
-}
-
-
-static void
-Client_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
-{
- int r;
- SetFocus(GetParent(hwnd)); /* In case combobox steals the focus */
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"OnLButtonDown fSelecting = %d, fTextSelected = %d:\n",
- fSelecting,fTextSelected);
- fflush(stderr);
-#endif
- if (fTextSelected) {
- InvertSelectionArea(hwnd);
- }
- fTextSelected = FALSE;
-
- calc_charpoint_from_point(GetDC(hwnd), x, y, 0, &editBeg);
-
- editEnd.x = editBeg.x;
- editEnd.y = editBeg.y + 1;
- fSelecting = TRUE;
- SetCapture(hwnd);
-}
-
-static void
-Client_OnRButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
-{
- if (fTextSelected) {
- fSelecting = TRUE;
- Client_OnMouseMove(hwnd,x,y,keyFlags);
- fSelecting = FALSE;
- }
-}
-
-static void
-Client_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
-{
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"OnLButtonUp fSelecting = %d, fTextSelected = %d:\n",
- fSelecting,fTextSelected);
- fprintf(stderr,"(Beg.x = %d, Beg.y = %d, "
- "End.x = %d, End.y = %d)\n",editBeg.x,editBeg.y,
- editEnd.x,editEnd.y);
-#endif
- if (fSelecting &&
- !(editBeg.x == editEnd.x && editBeg.y == (editEnd.y - 1))) {
- fTextSelected = TRUE;
- }
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"OnLButtonUp fTextSelected = %d:\n",
- fTextSelected);
- fflush(stderr);
-#endif
- fSelecting = FALSE;
- ReleaseCapture();
-}
-
-#define EMPTY_RECT(R) \
-(((R).bottom - (R).top == 0) || ((R).right - (R).left == 0))
-#define ABS(X) (((X)< 0) ? -1 * (X) : X)
-#define DIFF(A,B) ABS(((int)(A)) - ((int)(B)))
-
-static int diff_sel_area(RECT old[3], RECT new[3], RECT result[6])
-{
- int absposold = old[0].left + old[0].top * canvasColumns;
- int absposnew = new[0].left + new[0].top * canvasColumns;
- int absendold = absposold, absendnew = absposnew;
- int i, x, ret = 0;
- int abspos[2],absend[2];
- for(i = 0; i < 3; ++i) {
- if (!EMPTY_RECT(old[i])) {
- absendold += (old[i].right - old[i].left) *
- (old[i].bottom - old[i].top);
- }
- if (!EMPTY_RECT(new[i])) {
- absendnew += (new[i].right - new[i].left) *
- (new[i].bottom - new[i].top);
- }
- }
- abspos[0] = min(absposold, absposnew);
- absend[0] = DIFF(absposold, absposnew) + abspos[0];
- abspos[1] = min(absendold, absendnew);
- absend[1] = DIFF(absendold, absendnew) + abspos[1];
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"abspos[0] = %d, absend[0] = %d, abspos[1] = %d, absend[1] = %d\n",abspos[0],absend[0],abspos[1],absend[1]);
- fflush(stderr);
-#endif
- i = 0;
- for (x = 0; x < 2; ++x) {
- if (abspos[x] != absend[x]) {
- int consumed = 0;
- result[i].left = abspos[x] % canvasColumns;
- result[i].top = abspos[x] / canvasColumns;
- result[i].bottom = result[i].top + 1;
- if ((absend[x] - abspos[x]) + result[i].left < canvasColumns) {
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"Nowrap, %d < canvasColumns\n",
- (absend[x] - abspos[x]) + result[i].left);
- fflush(stderr);
-#endif
- result[i].right = (absend[x] - abspos[x]) + result[i].left;
- consumed += result[i].right - result[i].left;
- } else {
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"Wrap, %d >= canvasColumns\n",
- (absend[x] - abspos[x]) + result[i].left);
- fflush(stderr);
-#endif
- result[i].right = canvasColumns;
- consumed += result[i].right - result[i].left;
- if (absend[x] - abspos[x] - consumed >= canvasColumns) {
- ++i;
- result[i].top = result[i-1].bottom;
- result[i].left = 0;
- result[i].right = canvasColumns;
- result[i].bottom = (absend[x] - abspos[x] - consumed) / canvasColumns + result[i].top;
- consumed += (result[i].bottom - result[i].top) * canvasColumns;
- }
- if (absend[x] - abspos[x] - consumed > 0) {
- ++i;
- result[i].top = result[i-1].bottom;
- result[i].bottom = result[i].top + 1;
- result[i].left = 0;
- result[i].right = absend[x] - abspos[x] - consumed;
- }
- }
- ++i;
- }
- }
-#ifdef HARD_SEL_DEBUG
- if (i > 2) {
- int x;
- fprintf(stderr,"i = %d\n",i);
- fflush(stderr);
- for (x = 0; x < i; ++x) {
- fprintf(stderr, "result[%d]: top = %d, left = %d, "
- "bottom = %d. right = %d\n",
- x, result[x].top, result[x].left,
- result[x].bottom, result[x].right);
- }
- }
-#endif
- return i;
-}
-
-
-
-static void calc_sel_area(RECT rects[3], POINT beg, POINT end)
-{
- /* These are not really rects and points, these are character
- based positions, need to be multiplied by cxChar and cyChar to
- make up canvas coordinates */
- memset(rects,0,3*sizeof(RECT));
- rects[0].left = beg.x;
- rects[0].top = beg.y;
- rects[0].bottom = beg.y+1;
- if (end.y - beg.y == 1) { /* Only one row */
- rects[0].right = end.x;
- goto out;
- }
- rects[0].right = canvasColumns;
- if (end.y - beg.y > 2) {
- rects[1].left = 0;
- rects[1].top = rects[0].bottom;
- rects[1].right = canvasColumns;
- rects[1].bottom = end.y - 1;
- }
- rects[2].left = 0;
- rects[2].top = end.y - 1;
- rects[2].bottom = end.y;
- rects[2].right = end.x;
-
- out:
-#ifdef HARD_SEL_DEBUG
- {
- int i;
- fprintf(stderr,"beg.x = %d, beg.y = %d, end.x = %d, end.y = %d\n",
- beg.x,beg.y,end.x,end.y);
- for (i = 0; i < 3; ++i) {
- fprintf(stderr,"[%d] left = %d, top = %d, "
- "right = %d, bottom = %d\n",
- i, rects[i].left, rects[i].top,
- rects[i].right, rects[i].bottom);
- }
- fflush(stderr);
- }
-#endif
- return;
-}
-
-static void calc_sel_area_turned(RECT rects[3], POINT eBeg, POINT eEnd) {
- POINT from,to;
- if (eBeg.y >= eEnd.y ||
- (eBeg.y == eEnd.y - 1 && eBeg.x > eEnd.x)) {
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"Reverting (Beg.x = %d, Beg.y = %d, "
- "End.x = %d, End.y = %d)\n",eBeg.x,eBeg.y,
- eEnd.x,eEnd.y);
- fflush(stderr);
-#endif
- from.x = eEnd.x;
- from.y = eEnd.y - 1;
- to.x = eBeg.x;
- to.y = eBeg.y + 1;
- calc_sel_area(rects,from,to);
- } else {
- calc_sel_area(rects,eBeg,eEnd);
- }
-}
-
-
-static void InvertSelectionArea(HWND hwnd)
-{
- RECT rects[3];
- POINT from,to;
- int i;
- calc_sel_area_turned(rects,editBeg,editEnd);
- for (i = 0; i < 3; ++i) {
- if (!EMPTY_RECT(rects[i])) {
- from.x = rects[i].left;
- to.x = rects[i].right;
- from.y = rects[i].top;
- to.y = rects[i].bottom;
- DrawSelection(hwnd,from,to);
- }
- }
-}
-
-static void
-Client_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
-{
- if (fSelecting) {
- RECT rold[3], rnew[3], rupdate[6];
- int num_updates,i,r;
- POINT from,to;
- calc_sel_area_turned(rold,editBeg,editEnd);
-
- calc_charpoint_from_point(GetDC(hwnd), x, y, 1, &editEnd);
-
- calc_sel_area_turned(rnew,editBeg,editEnd);
- num_updates = diff_sel_area(rold,rnew,rupdate);
- for (i = 0; i < num_updates;++i) {
- from.x = rupdate[i].left;
- to.x = rupdate[i].right;
- from.y = rupdate[i].top;
- to.y = rupdate[i].bottom;
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"from: x=%d,y=%d, to: x=%d, y=%d\n",
- from.x, from.y,to.x,to.y);
- fflush(stderr);
-#endif
- DrawSelection(hwnd,from,to);
- }
- }
-}
-
-static void
-Client_OnVScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos)
-{
- int iVscroll;
-
- switch(code) {
- case SB_LINEDOWN:
- iVscroll = 1;
- break;
- case SB_LINEUP:
- iVscroll = -1;
- break;
- case SB_PAGEDOWN:
- iVscroll = max(1, cyClient/cyChar);
- break;
- case SB_PAGEUP:
- iVscroll = min(-1, -cyClient/cyChar);
- break;
- case SB_THUMBTRACK:
- iVscroll = pos - iVscrollPos;
- break;
- default:
- iVscroll = 0;
- }
- iVscroll = max(-iVscrollPos, min(iVscroll, iVscrollMax-iVscrollPos));
- if (iVscroll != 0) {
- iVscrollPos += iVscroll;
- ScrollWindowEx(hwnd, 0, -cyChar*iVscroll, NULL, NULL,
- NULL, NULL, SW_ERASE | SW_INVALIDATE);
- SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);
- iVscroll = GetScrollPos(hwnd, SB_VERT);
- UpdateWindow(hwnd);
- }
-}
-
-static void
-Client_OnHScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos)
-{
- int iHscroll, curCharWidth = cxClient/cxChar;
-
- switch(code) {
- case SB_LINEDOWN:
- iHscroll = 1;
- break;
- case SB_LINEUP:
- iHscroll = -1;
- break;
- case SB_PAGEDOWN:
- iHscroll = max(1,curCharWidth-1);
- break;
- case SB_PAGEUP:
- iHscroll = min(-1,-(curCharWidth-1));
- break;
- case SB_THUMBTRACK:
- iHscroll = pos - iHscrollPos;
- break;
- default:
- iHscroll = 0;
- }
- iHscroll = max(-iHscrollPos, min(iHscroll, iHscrollMax-iHscrollPos-(curCharWidth-1)));
- if (iHscroll != 0) {
- iHscrollPos += iHscroll;
- ScrollWindow(hwnd, -cxChar*iHscroll, 0, NULL, NULL);
- SetScrollPos(hwnd, SB_HORZ, iHscrollPos, TRUE);
- UpdateWindow(hwnd);
- }
-}
-
-static LRESULT CALLBACK
-ClientWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (iMsg) {
- HANDLE_MSG(hwnd, WM_CREATE, Client_OnCreate);
- HANDLE_MSG(hwnd, WM_SIZE, Client_OnSize);
- HANDLE_MSG(hwnd, WM_PAINT, Client_OnPaint);
- HANDLE_MSG(hwnd, WM_LBUTTONDOWN, Client_OnLButtonDown);
- HANDLE_MSG(hwnd, WM_RBUTTONDOWN, Client_OnRButtonDown);
- HANDLE_MSG(hwnd, WM_LBUTTONUP, Client_OnLButtonUp);
- HANDLE_MSG(hwnd, WM_MOUSEMOVE, Client_OnMouseMove);
- HANDLE_MSG(hwnd, WM_VSCROLL, Client_OnVScroll);
- HANDLE_MSG(hwnd, WM_HSCROLL, Client_OnHScroll);
- case WM_CONBEEP:
- if (0) Beep(440, 400);
- return 0;
- case WM_CONTEXT:
- ConDrawText(hwnd);
- return 0;
- case WM_CLOSE:
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc (hwnd, iMsg, wParam, lParam);
-}
-
-static void
-LoadUserPreferences(void)
-{
- DWORD size;
- DWORD res;
- DWORD type;
- HFONT hfont;
- /* default prefs */
- hfont = CreateFont(0,0, 0,0, 0, FALSE,FALSE,FALSE,
- ANSI_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS,
- CLEARTYPE_QUALITY, FIXED_PITCH, TEXT("Consolas"));
- if(hfont) {
- GetObject(hfont, sizeof(LOGFONT), (PSTR)&logfont);
- DeleteObject(hfont);
- } else {
- GetObject(GetStockObject(SYSTEM_FIXED_FONT),sizeof(LOGFONT),(PSTR)&logfont);
- }
- fgColor = GetSysColor(COLOR_WINDOWTEXT);
- bkgColor = GetSysColor(COLOR_WINDOW);
- winPos.left = -1;
- toolbarVisible = FALSE;
-
- if (RegCreateKeyEx(HKEY_CURRENT_USER, USER_KEY, 0, 0,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
- &key, &res) != ERROR_SUCCESS)
- return;
- has_key = TRUE;
- if (res == REG_CREATED_NEW_KEY)
- return;
- size = sizeof(logfont);
- res = RegQueryValueEx(key,TEXT("Font"),NULL,&type,(LPBYTE)&logfont,&size);
- size = sizeof(fgColor);
- res = RegQueryValueEx(key,TEXT("FgColor"),NULL,&type,(LPBYTE)&fgColor,&size);
- size = sizeof(bkgColor);
- res = RegQueryValueEx(key,TEXT("BkColor"),NULL,&type,(LPBYTE)&bkgColor,&size);
- size = sizeof(winPos);
- res = RegQueryValueEx(key,TEXT("Pos"),NULL,&type,(LPBYTE)&winPos,&size);
- size = sizeof(toolbarVisible);
- res = RegQueryValueEx(key,TEXT("Toolbar"),NULL,&type,(LPBYTE)&toolbarVisible,&size);
-}
-
-static void
-SaveUserPreferences(void)
-{
- WINDOWPLACEMENT wndPlace;
-
- if (has_key == TRUE) {
- RegSetValueEx(key,TEXT("Font"),0,REG_BINARY,(CONST BYTE *)&logfont,sizeof(LOGFONT));
- RegSetValueEx(key,TEXT("FgColor"),0,REG_DWORD,(CONST BYTE *)&fgColor,sizeof(fgColor));
- RegSetValueEx(key,TEXT("BkColor"),0,REG_DWORD,(CONST BYTE *)&bkgColor,sizeof(bkgColor));
- RegSetValueEx(key,TEXT("Toolbar"),0,REG_DWORD,(CONST BYTE *)&toolbarVisible,sizeof(toolbarVisible));
-
- wndPlace.length = sizeof(WINDOWPLACEMENT);
- GetWindowPlacement(hFrameWnd,&wndPlace);
- /* If wndPlace.showCmd == SW_MINIMIZE, then the window is minimized.
- We don't care, wndPlace.rcNormalPosition always holds the last known position. */
- winPos = wndPlace.rcNormalPosition;
- RegSetValueEx(key,TEXT("Pos"),0,REG_BINARY,(CONST BYTE *)&winPos,sizeof(winPos));
- }
-}
-
-
-static void
-set_scroll_info(HWND hwnd)
-{
- SCROLLINFO info;
- int hScrollBy;
- /*
- * Set vertical scrolling range and scroll box position.
- */
-
- iVscrollMax = nBufLines-1;
- iVscrollPos = min(iVscrollPos, iVscrollMax);
- info.cbSize = sizeof(info);
- info.fMask = SIF_PAGE|SIF_RANGE|SIF_POS;
- info.nMin = 0;
- info.nPos = iVscrollPos;
- info.nPage = min(cyClient/cyChar, iVscrollMax);
- info.nMax = iVscrollMax;
- SetScrollInfo(hwnd, SB_VERT, &info, TRUE);
-
- /*
- * Set horizontal scrolling range and scroll box position.
- */
-
- iHscrollMax = LINE_LENGTH-1;
- hScrollBy = max(0, (iHscrollPos - (iHscrollMax-cxClient/cxChar))*cxChar);
- iHscrollPos = min(iHscrollPos, iHscrollMax);
- info.nPos = iHscrollPos;
- info.nPage = cxClient/cxChar;
- info.nMax = iHscrollMax;
- SetScrollInfo(hwnd, SB_HORZ, &info, TRUE);
- /*ScrollWindow(hwnd, hScrollBy, 0, NULL, NULL);*/
-}
-
-
-static void
-ensure_line_below(void)
-{
- if (cur_line->next == NULL) {
- if (nBufLines >= lines_to_save) {
- ScreenLine_t* pLine = buffer_top->next;
- FREE(buffer_top->text);
- FREE(buffer_top);
- buffer_top = pLine;
- buffer_top->prev = NULL;
- nBufLines--;
- }
- cur_line->next = ConNewLine();
- cur_line->next->prev = cur_line;
- buffer_bottom = cur_line->next;
- set_scroll_info(hClientWnd);
- }
-}
-
-static ScreenLine_t*
-ConNewLine(void)
-{
- ScreenLine_t *pLine;
-
- pLine = (ScreenLine_t *)ALLOC(sizeof(ScreenLine_t));
- if (!pLine)
- return NULL;
- pLine->text = (TCHAR *) ALLOC(canvasColumns * sizeof(TCHAR));
-#ifdef HARDDEBUG
- pLine->allocated = canvasColumns;
-#endif
- pLine->width = 0;
- pLine->prev = pLine->next = NULL;
- pLine->newline = 0;
- nBufLines++;
- return pLine;
-}
-
-static ScreenLine_t*
-GetLineFromY(int y)
-{
- ScreenLine_t *pLine = buffer_top;
- int i;
-
- for (i = 0; i < nBufLines && pLine != NULL; i++) {
- if (i == y)
- return pLine;
- pLine = pLine->next;
- }
- return NULL;
-}
-
-void ConCarriageFeed(int hard_newline)
-{
- cur_x = 0;
- ensure_line_below();
- cur_line->newline = hard_newline;
- cur_line = cur_line->next;
- if (cur_y < nBufLines-1) {
- cur_y++;
- } else if (iVscrollPos > 0) {
- iVscrollPos--;
- }
-}
-
-/*
- * Scroll screen if cursor is not visible.
- */
-static void
-ConScrollScreen(void)
-{
- if (cur_y >= iVscrollPos + cyClient/cyChar) {
- int iVscroll;
-
- iVscroll = cur_y - iVscrollPos - cyClient/cyChar + 1;
- iVscrollPos += iVscroll;
- ScrollWindowEx(hClientWnd, 0, -cyChar*iVscroll, NULL, NULL,
- NULL, NULL, SW_ERASE | SW_INVALIDATE);
- SetScrollPos(hClientWnd, SB_VERT, iVscrollPos, TRUE);
- UpdateWindow(hClientWnd);
- }
-}
-
-static void
-DrawSelection(HWND hwnd, POINT pt1, POINT pt2)
-{
- HDC hdc;
- int width,height;
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"pt1.x = %d, pt1.y = %d, pt2.x = %d, pt2.y = %d\n",
- (int) pt1.x, (int) pt1.y, (int) pt2.x, (int) pt2.y);
-#endif
- pt1.x = GetXFromLine(GetDC(hwnd),iHscrollPos,pt1.x,GetLineFromY(pt1.y));
- pt2.x = GetXFromLine(GetDC(hwnd),iHscrollPos,pt2.x,GetLineFromY(pt2.y-1));
- pt1.y -= iVscrollPos;
- pt2.y -= iVscrollPos;
- pt1.y *= cyChar;
- pt2.y *= cyChar;
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"pt1.x = %d, pt1.y = %d, pt2.x = %d, pt2.y = %d\n",
- (int) pt1.x, (int) pt1.y, (int) pt2.x, (int) pt2.y);
- fflush(stderr);
-#endif
- width = pt2.x-pt1.x;
- height = pt2.y - pt1.y;
- hdc = GetDC(hwnd);
- PatBlt(hdc,pt1.x,pt1.y,width,height,DSTINVERT);
- ReleaseDC(hwnd,hdc);
-}
-
-static void
-OnEditCopy(HWND hwnd)
-{
- HGLOBAL hMem;
- TCHAR *pMem;
- ScreenLine_t *pLine;
- RECT rects[3];
- POINT from,to;
- int i,j,sum,len;
- if (editBeg.y >= editEnd.y ||
- (editBeg.y == editEnd.y - 1 && editBeg.x > editEnd.x)) {
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"CopyReverting (Beg.x = %d, Beg.y = %d, "
- "End.x = %d, End.y = %d)\n",editBeg.x,editBeg.y,
- editEnd.x,editEnd.y);
- fflush(stderr);
-#endif
- from.x = editEnd.x;
- from.y = editEnd.y - 1;
- to.x = editBeg.x;
- to.y = editBeg.y + 1;
- calc_sel_area(rects,from,to);
- } else {
- calc_sel_area(rects,editBeg,editEnd);
- }
- sum = 1;
- for (i = 0; i < 3; ++i) {
- if (!EMPTY_RECT(rects[i])) {
- pLine = GetLineFromY(rects[i].top);
- for (j = rects[i].top; j < rects[i].bottom ;++j) {
- if (pLine == NULL) {
- sum += 2;
- break;
- }
- if (pLine->width > rects[i].left) {
- sum += (pLine->width < rects[i].right) ?
- pLine->width - rects[i].left :
- rects[i].right - rects[i].left;
- }
- if(pLine->newline && rects[i].right >= pLine->width) {
- sum += 2;
- }
- pLine = pLine->next;
- }
- }
- }
-#ifdef HARD_SEL_DEBUG
- fprintf(stderr,"sum = %d\n",sum);
- fflush(stderr);
-#endif
- hMem = GlobalAlloc(GHND, sum * sizeof(TCHAR));
- pMem = GlobalLock(hMem);
- for (i = 0; i < 3; ++i) {
- if (!EMPTY_RECT(rects[i])) {
- pLine = GetLineFromY(rects[i].top);
- for (j = rects[i].top; j < rects[i].bottom; ++j) {
- if (pLine == NULL) {
- memcpy(pMem,TEXT("\r\n"),2 * sizeof(TCHAR));
- pMem += 2;
- break;
- }
- if (pLine->width > rects[i].left) {
- len = (pLine->width < rects[i].right) ?
- pLine->width - rects[i].left :
- rects[i].right - rects[i].left;
- memcpy(pMem,pLine->text + rects[i].left,len * sizeof(TCHAR));
- pMem +=len;
- }
- if(pLine->newline && rects[i].right >= pLine->width) {
- memcpy(pMem,TEXT("\r\n"),2 * sizeof(TCHAR));
- pMem += 2;
- }
- pLine = pLine->next;
- }
- }
- }
- *pMem = TEXT('\0');
- /* Flash de selection area to give user feedback about copying */
- InvertSelectionArea(hwnd);
- Sleep(100);
- InvertSelectionArea(hwnd);
-
- OpenClipboard(hwnd);
- EmptyClipboard();
- GlobalUnlock(hMem);
- SetClipboardData(CF_UNICODETEXT,hMem);
- CloseClipboard();
-}
-
-/* XXX:PaN Tchar or char? */
-static void
-OnEditPaste(HWND hwnd)
-{
- HANDLE hClipMem;
- TCHAR *pClipMem,*pMem,*pMem2;
- if (!OpenClipboard(hwnd))
- return;
- if ((hClipMem = GetClipboardData(CF_UNICODETEXT)) != NULL) {
- pClipMem = GlobalLock(hClipMem);
- pMem = (TCHAR *)ALLOC(GlobalSize(hClipMem) * sizeof(TCHAR));
- pMem2 = pMem;
- while ((*pMem2 = *pClipMem) != TEXT('\0')) {
- if (*pClipMem == TEXT('\r'))
- *pMem2 = TEXT('\n');
- ++pMem2;
- ++pClipMem;
- }
- GlobalUnlock(hClipMem);
- write_inbuf(pMem, _tcsclen(pMem));
- }
- CloseClipboard();
-}
-
-static void
-OnEditSelAll(HWND hwnd)
-{
- editBeg.x = 0;
- editBeg.y = 0;
- editEnd.x = LINE_LENGTH-1;
- editEnd.y = cur_y;
- fTextSelected = TRUE;
- InvalidateRect(hwnd, NULL, TRUE);
-}
-
-CF_HOOK_RET APIENTRY CFHookProc(HWND hDlg,UINT iMsg,WPARAM wParam,LPARAM lParam)
-{
- /* Hook procedure for font dialog box */
- HWND hOwner;
- RECT rc,rcOwner,rcDlg;
- switch (iMsg) {
- case WM_INITDIALOG:
- /* center dialogbox within its owner window */
- if ((hOwner = GetParent(hDlg)) == NULL)
- hOwner = GetDesktopWindow();
- GetWindowRect(hOwner, &rcOwner);
- GetWindowRect(hDlg, &rcDlg);
- CopyRect(&rc, &rcOwner);
- OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
- OffsetRect(&rc, -rc.left, -rc.top);
- OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
- SetWindowPos(hDlg,HWND_TOP,rcOwner.left + (rc.right / 2),
- rcOwner.top + (rc.bottom / 2),0,0,SWP_NOSIZE);
- return (CF_HOOK_RET) 1;
- default:
- break;
- }
- return (CF_HOOK_RET) 0; /* Let the default procedure process the message */
-}
-
-static BOOL
-ConChooseFont(HWND hwnd)
-{
- HDC hdc;
- hdc = GetDC(hwnd);
- cf.lStructSize = sizeof(CHOOSEFONT);
- cf.hwndOwner = hwnd;
- cf.hDC = NULL;
- cf.lpLogFont = &logfont;
- cf.iPointSize = 0;
- cf.Flags = CF_INITTOLOGFONTSTRUCT|CF_SCREENFONTS|CF_FIXEDPITCHONLY|CF_EFFECTS|CF_ENABLEHOOK;
- cf.rgbColors = GetTextColor(hdc);
- cf.lCustData = 0L;
- cf.lpfnHook = CFHookProc;
- cf.lpTemplateName = NULL;
- cf.hInstance = NULL;
- cf.lpszStyle = NULL;
- cf.nFontType = 0;
- cf.nSizeMin = 0;
- cf.nSizeMax = 0;
- ReleaseDC(hwnd,hdc);
- return ChooseFont(&cf);
-}
-
-static void
-ConFontInitialize(HWND hwnd)
-{
- HDC hdc;
- TEXTMETRIC tm;
- HFONT hFont;
-
- hFont = CreateFontIndirect(&logfont);
- hdc = GetDC(hwnd);
- SelectObject(hdc, hFont);
- SetTextColor(hdc,fgColor);
- SetBkColor(hdc,bkgColor);
- GetTextMetrics(hdc, &tm);
- cxChar = tm.tmAveCharWidth;
- cxCharMax = tm.tmMaxCharWidth;
- cyChar = tm.tmHeight + tm.tmExternalLeading;
- ReleaseDC(hwnd, hdc);
-}
-
-static void
-ConSetFont(HWND hwnd)
-{
- HDC hdc;
- TEXTMETRIC tm;
- HFONT hFontNew;
-
- hFontNew = CreateFontIndirect(&logfont);
- SendMessage(hComboWnd,WM_SETFONT,(WPARAM)hFontNew,
- MAKELPARAM(1,0));
- hdc = GetDC(hwnd);
- DeleteObject(SelectObject(hdc, hFontNew));
- GetTextMetrics(hdc, &tm);
- cxChar = tm.tmAveCharWidth;
- cxCharMax = tm.tmMaxCharWidth;
- cyChar = tm.tmHeight + tm.tmExternalLeading;
- fgColor = cf.rgbColors;
- SetTextColor(hdc,fgColor);
- ReleaseDC(hwnd, hdc);
- set_scroll_info(hwnd);
- HideCaret(hwnd);
- if (DestroyCaret()) {
- CreateCaret(hwnd, NULL, cxChar, cyChar);
- SetCaretPos(GetXFromCurrentY(hdc,iHscrollPos,cur_x), (cur_y-iVscrollPos)*cyChar);
- }
- ShowCaret(hwnd);
- InvalidateRect(hwnd, NULL, TRUE);
-}
-
-CC_HOOK_RET APIENTRY
-CCHookProc(HWND hDlg,UINT iMsg,WPARAM wParam,LPARAM lParam)
-{
- /* Hook procedure for choose color dialog box */
- HWND hOwner;
- RECT rc,rcOwner,rcDlg;
- switch (iMsg) {
- case WM_INITDIALOG:
- /* center dialogbox within its owner window */
- if ((hOwner = GetParent(hDlg)) == NULL)
- hOwner = GetDesktopWindow();
- GetWindowRect(hOwner, &rcOwner);
- GetWindowRect(hDlg, &rcDlg);
- CopyRect(&rc, &rcOwner);
- OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
- OffsetRect(&rc, -rc.left, -rc.top);
- OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
- SetWindowPos(hDlg,HWND_TOP,rcOwner.left + (rc.right / 2),
- rcOwner.top + (rc.bottom / 2),0,0,SWP_NOSIZE);
- return (CC_HOOK_RET) 1;
- default:
- break;
- }
- return (CC_HOOK_RET) 0; /* Let the default procedure process the message */
-}
-
-void ConChooseColor(HWND hwnd)
-{
- CHOOSECOLOR cc;
- static COLORREF acrCustClr[16];
- HBRUSH hbrush;
- HDC hdc;
-
- /* Initialize CHOOSECOLOR */
- ZeroMemory(&cc, sizeof(CHOOSECOLOR));
- cc.lStructSize = sizeof(CHOOSECOLOR);
- cc.hwndOwner = hwnd;
- cc.lpCustColors = (LPDWORD) acrCustClr;
- cc.rgbResult = bkgColor;
- cc.lpfnHook = CCHookProc;
- cc.Flags = CC_FULLOPEN|CC_RGBINIT|CC_SOLIDCOLOR|CC_ENABLEHOOK;
-
- if (ChooseColor(&cc)==TRUE) {
- bkgColor = cc.rgbResult;
- hdc = GetDC(hwnd);
- SetBkColor(hdc,bkgColor);
- ReleaseDC(hwnd,hdc);
- hbrush = CreateSolidBrush(bkgColor);
- DeleteObject((HBRUSH)SetClassLongPtr(hClientWnd,GCL_HBRBACKGROUND,(LONG_PTR)hbrush));
- InvalidateRect(hwnd,NULL,TRUE);
- }
-}
-
-OFN_HOOK_RET APIENTRY OFNHookProc(HWND hwndDlg,UINT iMsg,
- WPARAM wParam,LPARAM lParam)
-{
- /* Hook procedure for open file dialog box */
- HWND hOwner,hDlg;
- RECT rc,rcOwner,rcDlg;
- hDlg = GetParent(hwndDlg);
- switch (iMsg) {
- case WM_INITDIALOG:
- /* center dialogbox within its owner window */
- if ((hOwner = GetParent(hDlg)) == NULL)
- hOwner = GetDesktopWindow();
- GetWindowRect(hOwner, &rcOwner);
- GetWindowRect(hDlg, &rcDlg);
- CopyRect(&rc, &rcOwner);
- OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
- OffsetRect(&rc, -rc.left, -rc.top);
- OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
- SetWindowPos(hDlg,HWND_TOP,rcOwner.left + (rc.right / 2),
- rcOwner.top + (rc.bottom / 2),0,0,SWP_NOSIZE);
- return (OFN_HOOK_RET) 1;
- default:
- break;
- }
- return (OFN_HOOK_RET) 0; /* the let default procedure process the message */
-}
-
-static void
-GetFileName(HWND hwnd, TCHAR *pFile)
-{
- /* Open the File Open dialog box and */
- /* retrieve the file name */
- OPENFILENAME ofn;
- TCHAR szFilterSpec [128] = TEXT("logfiles (*.log)\0*.log\0All files (*.*)\0*.*\0\0");
- #define MAXFILENAME 256
- TCHAR szFileName[MAXFILENAME];
- TCHAR szFileTitle[MAXFILENAME];
-
- /* these need to be filled in */
- _tcscpy(szFileName, TEXT("erlshell.log"));
- _tcscpy(szFileTitle, TEXT("")); /* must be NULL */
-
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = NULL;
- ofn.lpstrFilter = szFilterSpec;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.nFilterIndex = 0;
- ofn.lpstrFile = szFileName;
- ofn.nMaxFile = MAXFILENAME;
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrFileTitle = szFileTitle;
- ofn.nMaxFileTitle = MAXFILENAME;
- ofn.lpstrTitle = TEXT("Open logfile");
- ofn.lpstrDefExt = TEXT("log");
- ofn.Flags = OFN_CREATEPROMPT|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_ENABLEHOOK|OFN_NOCHANGEDIR; /* OFN_NOCHANGEDIR only works in Vista :( */
- ofn.lpfnHook = OFNHookProc;
-
- if (!GetOpenFileName ((LPOPENFILENAME)&ofn)){
- *pFile = TEXT('\0');
- } else {
- _tcscpy(pFile, ofn.lpstrFile);
- }
-}
-
-void OpenLogFile(HWND hwnd)
-{
- /* open a file for logging */
- TCHAR filename[_MAX_PATH];
-
- GetFileName(hwnd, filename);
- if (filename[0] == '\0')
- return;
- if (NULL == (logfile = _tfopen(filename,TEXT("w,ccs=UNICODE"))))
- return;
-}
-
-void CloseLogFile(HWND hwnd)
-{
- /* close log file */
- fclose(logfile);
- logfile = NULL;
-}
-
-void LogFileWrite(TCHAR *buf, int num_chars)
-{
- /* write to logfile */
- int from,to;
- while (num_chars-- > 0) {
- switch (*buf) {
- case SET_CURSOR:
- buf++;
- from = *((int *)buf);
- buf += sizeof(int)/sizeof(TCHAR);
- to = *((int *)buf);
- buf += (sizeof(int)/sizeof(TCHAR))-1;
- num_chars -= 2 * (sizeof(int)/sizeof(TCHAR));
- // Won't seek in Unicode file, sorry...
- // fseek(logfile,to-from *sizeof(TCHAR),SEEK_CUR);
- break;
- default:
- _fputtc(*buf,logfile);
- break;
- }
- buf++;
- }
-}
-
-static void
-init_buffers(void)
-{
- inbuf.data = (TCHAR *) ALLOC(BUFSIZE * sizeof(TCHAR));
- outbuf.data = (TCHAR *) ALLOC(BUFSIZE * sizeof(TCHAR));
- inbuf.size = BUFSIZE;
- inbuf.rdPos = inbuf.wrPos = 0;
- outbuf.size = BUFSIZE;
- outbuf.rdPos = outbuf.wrPos = 0;
-}
-
-static int
-check_realloc(buffer_t *buf, int num_chars)
-{
- if (buf->wrPos + num_chars >= buf->size) {
- if (buf->size > MAXBUFSIZE)
- return 0;
- buf->size += num_chars + BUFSIZE;
- if (!(buf->data = (TCHAR *)REALLOC(buf->data, buf->size * sizeof(TCHAR)))) {
- buf->size = buf->rdPos = buf->wrPos = 0;
- return 0;
- }
- }
- return 1;
-}
-
-static int
-write_inbuf(TCHAR *data, int num_chars)
-{
- TCHAR *buf;
- int nwrite;
- WaitForSingleObject(console_input,INFINITE);
- if (!check_realloc(&inbuf,num_chars)) {
- ReleaseSemaphore(console_input,1,NULL);
- return -1;
- }
- buf = &inbuf.data[inbuf.wrPos];
- inbuf.wrPos += num_chars;
- nwrite = num_chars;
- while (nwrite--)
- *buf++ = *data++;
- SetEvent(console_input_event);
- ReleaseSemaphore(console_input,1,NULL);
- return num_chars;
-}
-
-static int
-write_outbuf(TCHAR *data, int num_chars)
-{
- TCHAR *buf;
- int nwrite;
-
- WaitForSingleObject(console_output,INFINITE);
- if (!check_realloc(&outbuf, num_chars)) {
- ReleaseSemaphore(console_output,1,NULL);
- return -1;
- }
- if (outbuf.rdPos == outbuf.wrPos)
- PostMessage(hClientWnd, WM_CONTEXT, 0L, 0L);
- buf = &outbuf.data[outbuf.wrPos];
- outbuf.wrPos += num_chars;
- nwrite = num_chars;
- while (nwrite--)
- *buf++ = *data++;
- ReleaseSemaphore(console_output,1,NULL);
- return num_chars;
-}
-
-DIALOG_PROC_RET CALLBACK AboutDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
-{
- HWND hOwner;
- RECT rc,rcOwner,rcDlg;
-
- switch (iMsg) {
- case WM_INITDIALOG:
- /* center dialogbox within its owner window */
- if ((hOwner = GetParent(hDlg)) == NULL)
- hOwner = GetDesktopWindow();
- GetWindowRect(hOwner, &rcOwner);
- GetWindowRect(hDlg, &rcDlg);
- CopyRect(&rc, &rcOwner);
- OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
- OffsetRect(&rc, -rc.left, -rc.top);
- OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
- SetWindowPos(hDlg,HWND_TOP,rcOwner.left + (rc.right / 2),
- rcOwner.top + (rc.bottom / 2),0,0,SWP_NOSIZE);
- SetDlgItemText(hDlg, ID_OTP_VERSIONSTRING,
- TEXT("OTP version ") TEXT(ERLANG_OTP_VERSION));
- SetDlgItemText(hDlg, ID_ERTS_VERSIONSTRING,
- TEXT("Erlang emulator version ") TEXT(ERLANG_VERSION));
- return (DIALOG_PROC_RET) TRUE;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- case IDCANCEL:
- EndDialog(hDlg,0);
- return (DIALOG_PROC_RET) TRUE;
- }
- break;
- }
- return (DIALOG_PROC_RET) FALSE;
-}
-
-static void
-ConDrawText(HWND hwnd)
-{
- int num_chars;
- int nchars;
- TCHAR *buf;
- int from, to;
- int dl;
- int dc;
- RECT rc;
-
- WaitForSingleObject(console_output, INFINITE);
- nchars = 0;
- num_chars = outbuf.wrPos - outbuf.rdPos;
- buf = &outbuf.data[outbuf.rdPos];
- if (logfile != NULL)
- LogFileWrite(buf, num_chars);
-
-
-#ifdef HARDDEBUG
- {
- TCHAR *bu = (TCHAR *) ALLOC((num_chars+1) * sizeof(TCHAR));
- memcpy(bu,buf,num_chars * sizeof(TCHAR));
- bu[num_chars]='\0';
- fprintf(stderr,"ConDrawText\"%S\"\n",bu);
- FREE(bu);
- fflush(stderr);
- }
-#endif
- /*
- * Don't draw any text in the window; just update the line buffers
- * and invalidate the appropriate part of the window. The window
- * will be updated on the next WM_PAINT message.
- */
-
- while (num_chars-- > 0) {
- switch (*buf) {
- case '\r':
- break;
- case '\n':
- if (nchars > 0) {
- rc.left = GetXFromCurrentY(GetDC(hwnd),iHscrollPos,cur_x - nchars);
- rc.right = rc.left + cxCharMax*nchars;
- rc.top = cyChar * (cur_y-iVscrollPos);
- rc.bottom = rc.top + cyChar;
- InvalidateRect(hwnd, &rc, TRUE);
- nchars = 0;
- }
- ConCarriageFeed(1);
- ConScrollScreen();
- break;
- case SET_CURSOR:
- if (nchars > 0) {
- rc.left = GetXFromCurrentY(GetDC(hwnd),iHscrollPos,cur_x - nchars);
- rc.right = rc.left + cxCharMax*nchars;
- rc.top = cyChar * (cur_y-iVscrollPos);
- rc.bottom = rc.top + cyChar;
- InvalidateRect(hwnd, &rc, TRUE);
- nchars = 0;
- }
- buf++;
- from = *((int *)buf);
- buf += sizeof(int)/sizeof(TCHAR);
- to = *((int *)buf);
- buf += (sizeof(int)/sizeof(TCHAR))-1;
- num_chars -= 2 * (sizeof(int)/sizeof(TCHAR));
- while (to > from) {
- cur_x++;
- if (GetXFromCurrentY(GetDC(hwnd),0,cur_x)+cxChar >
- (LINE_LENGTH * cxChar)) {
- cur_x = 0;
- cur_y++;
- ensure_line_below();
- cur_line = cur_line->next;
- }
- from++;
- }
- while (to < from) {
- cur_x--;
- if (cur_x < 0) {
- cur_y--;
- cur_line = cur_line->prev;
- cur_x = cur_line->width-1;
- }
- from--;
- }
-
- break;
- default:
- nchars++;
- cur_line->text[cur_x] = *buf;
- cur_x++;
- if (cur_x > cur_line->width)
- cur_line->width = cur_x;
- if (GetXFromCurrentY(GetDC(hwnd),0,cur_x)+cxChar >
- (LINE_LENGTH * cxChar)) {
- if (nchars > 0) {
- rc.left = GetXFromCurrentY(GetDC(hwnd),iHscrollPos,cur_x - nchars);
- rc.right = rc.left + cxCharMax*nchars;
- rc.top = cyChar * (cur_y-iVscrollPos);
- rc.bottom = rc.top + cyChar;
- InvalidateRect(hwnd, &rc, TRUE);
- }
- ConCarriageFeed(0);
- nchars = 0;
- }
- }
- buf++;
- }
- if (nchars > 0) {
- rc.left = GetXFromCurrentY(GetDC(hwnd),iHscrollPos,cur_x - nchars);
- rc.right = rc.left + cxCharMax*nchars;
- rc.top = cyChar * (cur_y-iVscrollPos);
- rc.bottom = rc.top + cyChar;
- InvalidateRect(hwnd, &rc, TRUE);
- }
- ConScrollScreen();
- SetCaretPos(GetXFromCurrentY(GetDC(hwnd),iHscrollPos,cur_x), (cur_y-iVscrollPos)*cyChar);
- outbuf.wrPos = outbuf.rdPos = 0;
- ReleaseSemaphore(console_output, 1, NULL);
-}
-
-static void
-AddToCmdHistory(void)
-{
- int i;
- int size;
- Uint32 *buf;
- wchar_t cmdBuf[128];
-
- if (llen != 0) {
- for (i = 0, size = 0; i < llen-1; i++) {
- /*
- * Find end of prompt.
- */
- if ((lbuf[i] == '>') && lbuf[i+1] == ' ') {
- buf = &lbuf[i+2];
- size = llen-i-2;
- break;
- }
- }
- if (size > 0 && size < 128) {
- for (i = 0;i < size; ++i) {
- cmdBuf[i] = (wchar_t) buf[i];
- }
- cmdBuf[size] = 0;
- SendMessage(hComboWnd,CB_INSERTSTRING,0,(LPARAM)cmdBuf);
- }
- }
-}
-
-/*static TBBUTTON tbb[] =
-{
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 0, IDMENU_COPY, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, 0, 0, 0, 0,
- 1, IDMENU_PASTE, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, 0, 0, 0, 0,
- 2, IDMENU_FONT, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, 0, 0, 0, 0,
- 3, IDMENU_ABOUT, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, 0, 0, 0, 0,
- 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- };*/
-static TBBUTTON tbb[] =
-{
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
- {0, IDMENU_COPY, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE},
- {1, IDMENU_PASTE, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE},
- {2, IDMENU_FONT, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE},
- {3, IDMENU_ABOUT, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE},
- {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP}
-};
-
-static TBADDBITMAP tbbitmap =
-{
- HINST_COMMCTRL, IDB_STD_SMALL_COLOR,
-};
-
-
-static HWND
-InitToolBar(HWND hwndParent)
-{
- int x,y,cx;
- HWND hwndTB,hwndTT;
- RECT r;
- TOOLINFO ti;
- HFONT hFontNew;
- DWORD backgroundColor = GetSysColor(COLOR_BTNFACE);
- COLORMAP colorMap;
- colorMap.from = RGB(192, 192, 192);
- colorMap.to = backgroundColor;
- /* Create toolbar window with tooltips */
- hwndTB = CreateWindowEx(0,TOOLBARCLASSNAME,(TCHAR *)NULL,
- WS_CHILD|CCS_TOP|WS_CLIPSIBLINGS|TBSTYLE_TOOLTIPS,
- 0,0,0,0,hwndParent,
- (HMENU)2,hInstance,NULL);
- SendMessage(hwndTB,TB_BUTTONSTRUCTSIZE,
- (WPARAM) sizeof(TBBUTTON),0);
- tbbitmap.hInst = NULL;
- tbbitmap.nID = (UINT_PTR) CreateMappedBitmap(beam_module, 1,0, &colorMap, 1);
- SendMessage(hwndTB, TB_ADDBITMAP, (WPARAM) 4,
- (LPARAM) &tbbitmap);
-
- SendMessage(hwndTB,TB_ADDBUTTONS, (WPARAM) 30,
- (LPARAM) tbb);
- if (toolbarVisible)
- ShowWindow(hwndTB, SW_SHOW);
-
- /* Create combobox window */
- SendMessage(hwndTB,TB_GETITEMRECT,0,(LPARAM)&r);
- x = r.left; y = r.top;
- SendMessage(hwndTB,TB_GETITEMRECT,23,(LPARAM)&r);
- cx = r.right - x + 1;
- hComboWnd = CreateWindow(TEXT("combobox"),NULL,WS_VSCROLL|WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,
- x,y,cx,100,hwndParent,(HMENU)ID_COMBOBOX, hInstance,NULL);
- SetParent(hComboWnd,hwndTB);
- hFontNew = CreateFontIndirect(&logfont);
- SendMessage(hComboWnd,WM_SETFONT,(WPARAM)hFontNew,
- MAKELPARAM(1,0));
-
- /* Add tooltip for combo box */
- ZeroMemory(&ti,sizeof(TOOLINFO));
- ti.cbSize = sizeof(TOOLINFO);
- ti.uFlags = TTF_IDISHWND|TTF_CENTERTIP|TTF_SUBCLASS;
- ti.hwnd = hwndTB;;
- ti.uId = (UINT_PTR)hComboWnd;
- ti.lpszText = LPSTR_TEXTCALLBACK;
- hwndTT = (HWND)SendMessage(hwndTB,TB_GETTOOLTIPS,0,0);
- SendMessage(hwndTT,TTM_ADDTOOL,0,(LPARAM)&ti);
-
- return hwndTB;
-}
-
-static void
-window_title(struct title_buf *tbuf)
-{
- int res, i;
- size_t bufsz = TITLE_BUF_SZ;
- unsigned char charbuff[TITLE_BUF_SZ];
-
- res = erl_drv_getenv("ERL_WINDOW_TITLE", charbuff, &bufsz);
- if (res < 0)
- tbuf->name = erlang_window_title;
- else if (res == 0) {
- for (i = 0; i < bufsz; ++i) {
- tbuf->buf[i] = charbuff[i];
- }
- tbuf->buf[bufsz - 1] = 0;
- tbuf->name = &tbuf->buf[0];
- } else {
- char *buf = ALLOC(bufsz);
- if (!buf)
- tbuf->name = erlang_window_title;
- else {
- while (1) {
- char *newbuf;
- res = erl_drv_getenv("ERL_WINDOW_TITLE", buf, &bufsz);
- if (res <= 0) {
- if (res == 0) {
- TCHAR *wbuf = ALLOC(bufsz *sizeof(TCHAR));
- for (i = 0; i < bufsz ; ++i) {
- wbuf[i] = buf[i];
- }
- wbuf[bufsz - 1] = 0;
- FREE(buf);
- tbuf->name = wbuf;
- } else {
- tbuf->name = erlang_window_title;
- FREE(buf);
- }
- break;
- }
- newbuf = REALLOC(buf, bufsz);
- if (newbuf)
- buf = newbuf;
- else {
- tbuf->name = erlang_window_title;
- FREE(buf);
- break;
- }
- }
- }
- }
-}
-
-static void
-free_window_title(struct title_buf *tbuf)
-{
- if (tbuf->name != erlang_window_title && tbuf->name != &tbuf->buf[0])
- FREE(tbuf->name);
-}