summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--win32caml/Makefile10
-rw-r--r--win32caml/inria.h2
-rw-r--r--win32caml/inriares.h1
-rw-r--r--win32caml/menu.c79
-rw-r--r--win32caml/ocaml.c153
-rw-r--r--win32caml/ocaml.rc1
-rw-r--r--win32caml/startocaml.c11
7 files changed, 185 insertions, 72 deletions
diff --git a/win32caml/Makefile b/win32caml/Makefile
index b5aca8e6e..04037b5ac 100644
--- a/win32caml/Makefile
+++ b/win32caml/Makefile
@@ -5,10 +5,10 @@ OBJS=startocaml.obj ocaml.res ocaml.obj menu.obj
LIBS=kernel32.lib advapi32.lib gdi32.lib user32.lib comdlg32.lib comctl32.lib
-all: ocaml.exe
+all: ocamlwin.exe
-ocaml.exe: $(OBJS)
- $(CC) $(CFLAGS) -o ocaml.exe $(OBJS) $(LIBS)
+ocamlwin.exe: $(OBJS)
+ $(CC) $(CFLAGS) -o ocamlwin.exe $(OBJS) $(LIBS)
ocaml.res: ocaml.rc ocaml.ico
rc ocaml.rc
@@ -16,10 +16,10 @@ ocaml.res: ocaml.rc ocaml.ico
$(OBJS): inria.h inriares.h
clean:
- rm -f ocaml.exe ocaml.res *.obj
+ rm -f ocamlwin.exe ocaml.res *.obj
install:
- cp ocaml.exe $(PREFIX)
+ cp ocamlwin.exe $(PREFIX)/OCamlWin.exe
.SUFFIXES: .c .obj
diff --git a/win32caml/inria.h b/win32caml/inria.h
index 8ac701e41..fb996b9c4 100644
--- a/win32caml/inria.h
+++ b/win32caml/inria.h
@@ -110,3 +110,5 @@ typedef struct tagHistory {
extern void *SafeMalloc(int);
extern HISTORYLINE *History; // The root of the history lines
+#define IDEDITCONTROL 15432
+
diff --git a/win32caml/inriares.h b/win32caml/inriares.h
index 45d835211..520ac3cb1 100644
--- a/win32caml/inriares.h
+++ b/win32caml/inriares.h
@@ -12,6 +12,7 @@
#define IDM_EXIT 270
#define IDM_HISTORY 281
#define IDM_GC 282
+#define IDCTRLC 283
#define IDD_HISTORY 300
#define IDLIST 301
#define IDM_EDITUNDO 310
diff --git a/win32caml/menu.c b/win32caml/menu.c
index d0ffbc7e0..318cb9f1f 100644
--- a/win32caml/menu.c
+++ b/win32caml/menu.c
@@ -13,6 +13,7 @@
#include <stdio.h>
#include <windows.h>
+#include <Richedit.h>
#include "inria.h"
#include "inriares.h"
@@ -298,6 +299,12 @@ void ForceRepaint(void)
InvalidateRect(hwndEdit,NULL,1);
}
+static void Add_Char_To_Queue(int c)
+{
+ HWND hwndEdit = (HWND)GetWindowLong(hwndSession,DWL_USER);
+ SendMessage(hwndEdit,WM_CHAR,c,1);
+}
+
/*------------------------------------------------------------------------
Procedure: AddLineToControl ID:1
Purpose: It will ad the given text at the end of the edit
@@ -423,6 +430,60 @@ static void SaveText(char *fname)
free(buf);
}
+
+static void Add_Clipboard_To_Queue(void)
+{
+ if (IsClipboardFormatAvailable(CF_TEXT) &&
+ OpenClipboard(hwndMain))
+ {
+ HANDLE hClipData = GetClipboardData(CF_TEXT);
+
+ if (hClipData)
+ {
+ char *str = GlobalLock(hClipData);
+
+ if (str)
+ while (*str)
+ {
+ if (*str != '\r')
+ Add_Char_To_Queue(*str);
+ str++;
+ }
+ GlobalUnlock(hClipData);
+ }
+ CloseClipboard();
+ }
+
+}
+
+static void CopyToClipboard(HWND hwnd)
+{
+ HWND hwndEdit = (HWND)GetWindowLong(hwndSession,DWL_USER);
+ SendMessage(hwndEdit,WM_COPY,0,0);
+}
+
+int ResetText(void)
+{
+ HWND hwndEdit = (HWND) GetWindowLong(hwndSession,DWL_USER);
+ TEXTRANGE cr;
+ int len = SendMessage(hwndEdit,WM_GETTEXTLENGTH,0,0);
+ char *tmp = malloc(len+10),*p;
+
+ memset(tmp,0,len+10);
+ cr.chrg.cpMin = 0;
+ cr.chrg.cpMax = -1;
+ cr.lpstrText = tmp;
+ SendMessage(hwndEdit,EM_GETTEXTRANGE,0,(LPARAM)&cr);
+ p = tmp+len/2;
+ while (*p && *p != '\r')
+ p++;
+ SendMessage(hwndEdit,EM_SETSEL,0,(LPARAM)-1);
+ SendMessage(hwndEdit,EM_REPLACESEL,0,(LPARAM)p);
+ InvalidateRect(hwndEdit,0,1);
+ free(tmp);
+ return 0;
+}
+
/*------------------------------------------------------------------------
Procedure: HandleCommand ID:1
Purpose: Handles all menu commands.
@@ -456,6 +517,15 @@ void HandleCommand(HWND hwnd, WPARAM wParam,LPARAM lParam)
case IDM_GC:
AddLineToControl("Gc.full_major();;");
break;
+ case IDCTRLC:
+ InterruptOcaml();
+ break;
+ case IDM_EDITPASTE:
+ Add_Clipboard_To_Queue();
+ break;
+ case IDM_EDITCOPY:
+ CopyToClipboard(hwnd);
+ break;
case IDM_SAVE:
fname = SafeMalloc(512);
if (GetSaveName(fname,512)) {
@@ -503,6 +573,15 @@ void HandleCommand(HWND hwnd, WPARAM wParam,LPARAM lParam)
case IDM_ABOUT:
CallDlgProc(AboutDlgProc,IDD_ABOUT);
break;
+ default:
+ if (LOWORD(wParam) >= IDEDITCONTROL && LOWORD(wParam) < IDEDITCONTROL+5) {
+ switch (HIWORD(wParam)) {
+ case EN_ERRSPACE:
+ ResetText();
+ break;
+ }
+ }
+ break;
}
}
diff --git a/win32caml/ocaml.c b/win32caml/ocaml.c
index cddbbcbe8..9a9f257e6 100644
--- a/win32caml/ocaml.c
+++ b/win32caml/ocaml.c
@@ -25,7 +25,7 @@
#include <Richedit.h>
#include "inriares.h"
#include "inria.h"
-int EditControls = 10000;
+int EditControls = IDEDITCONTROL;
static WNDPROC lpEProc;
static char lineBuffer[1024*32];
int ReadToLineBuffer(void);
@@ -530,74 +530,85 @@ static LRESULT CALLBACK MdiChildWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM
HDC hDC;
switch(msg) {
- case WM_CREATE:
- GetClientRect(hwnd,&rc);
- hwndChild= CreateWindow("EDIT",
- NULL,
- WS_CHILD | WS_VISIBLE |
- ES_MULTILINE |
- WS_VSCROLL | WS_HSCROLL |
- ES_AUTOHSCROLL | ES_AUTOVSCROLL,
- 0,
- 0,
- (rc.right-rc.left),
- (rc.bottom-rc.top),
- hwnd,
- (HMENU) EditControls++,
- hInst,
- NULL);
- SetWindowLong(hwnd, DWL_USER, (DWORD) hwndChild);
- SendMessage(hwndChild, WM_SETFONT, (WPARAM) ProgramParams.hFont, 0L);
- SubClassEditField(hwndChild);
- break;
- // Resize the edit control
- case WM_SIZE:
- hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
- MoveWindow(hwndChild, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE);
- break;
- // Always set the focus to the edit control.
- case WM_SETFOCUS:
- hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
- SetFocus(hwndChild);
- break;
- // Repainting of the edit control about to happen.
- // Set the text color and the background color
- case WM_CTLCOLOREDIT:
- hDC = (HDC)wparam;
- SetTextColor(hDC,ProgramParams.TextColor);
- SetBkColor(hDC,BackColor);
- return (LRESULT)BackgroundBrush;
- // Take care of erasing the background color to avoid flicker
- case WM_ERASEBKGND:
- GetWindowRect(hwnd,&rc);
- hDC = (HDC)wparam;
- FillRect(hDC,&rc,BackgroundBrush);
- return 1;
- // A carriage return has been pressed. Send the data to the interpreted.
- // This message is posted by the subclassed edit field.
- case WM_NEWLINE:
- if (busy)
- break;
- hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
- SendLastLine(hwndChild);
- break;
- // The timer will call us 4 times a second. Look if the interpreter
- // has written something in its end of the pipe.
- case WM_TIMERTICK:
- hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
- if (ReadToLineBuffer()) {
- char *p;
+ case WM_CREATE:
+ GetClientRect(hwnd,&rc);
+ hwndChild= CreateWindow("EDIT",
+ NULL,
+ WS_CHILD | WS_VISIBLE |
+ ES_MULTILINE |
+ WS_VSCROLL | WS_HSCROLL |
+ ES_AUTOHSCROLL | ES_AUTOVSCROLL,
+ 0,
+ 0,
+ (rc.right-rc.left),
+ (rc.bottom-rc.top),
+ hwnd,
+ (HMENU) EditControls++,
+ hInst,
+ NULL);
+ SetWindowLong(hwnd, DWL_USER, (DWORD) hwndChild);
+ SendMessage(hwndChild, WM_SETFONT, (WPARAM) ProgramParams.hFont, 0L);
+ SendMessage(hwndChild,EM_LIMITTEXT,0xffffffff,0);
+ SubClassEditField(hwndChild);
+ break;
+ // Resize the edit control
+ case WM_SIZE:
+ hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
+ MoveWindow(hwndChild, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE);
+ break;
+ // Always set the focus to the edit control.
+ case WM_SETFOCUS:
+ hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
+ SetFocus(hwndChild);
+ break;
+ // Repainting of the edit control about to happen.
+ // Set the text color and the background color
+ case WM_CTLCOLOREDIT:
+ hDC = (HDC)wparam;
+ SetTextColor(hDC,ProgramParams.TextColor);
+ SetBkColor(hDC,BackColor);
+ return (LRESULT)BackgroundBrush;
+ // Take care of erasing the background color to avoid flicker
+ case WM_ERASEBKGND:
+ GetWindowRect(hwnd,&rc);
+ hDC = (HDC)wparam;
+ FillRect(hDC,&rc,BackgroundBrush);
+ return 1;
+ // A carriage return has been pressed. Send the data to the interpreted.
+ // This message is posted by the subclassed edit field.
+ case WM_COMMAND:
+ if (LOWORD(wparam) >= IDEDITCONTROL && LOWORD(wparam) < IDEDITCONTROL+5) {
+ switch (HIWORD(wparam)) {
+ case EN_ERRSPACE:
+ case EN_MAXTEXT:
+ ResetText();
+ break;
+ }
+ }
+ break;
+ case WM_NEWLINE:
+ if (busy)
+ break;
+ hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
+ SendLastLine(hwndChild);
+ break;
+ // The timer will call us 4 times a second. Look if the interpreter
+ // has written something in its end of the pipe.
+ case WM_TIMERTICK:
+ hwndChild = (HWND) GetWindowLong(hwnd, DWL_USER);
+ if (ReadToLineBuffer()) {
+ char *p;
// Ok we read something. Display it.
- AddLineBuffer();
- p = strrchr(lineBuffer,'\r');
- if (p && !strcmp(p,"\r\n# ")) {
- if (p[4] == 0) {
- SetLastPrompt(hwndChild);
- }
- }
+ AddLineBuffer();
+ p = strrchr(lineBuffer,'\r');
+ if (p && !strcmp(p,"\r\n# ")) {
+ if (p[4] == 0) {
+ SetLastPrompt(hwndChild);
+ }
+ }
- }
- break;
+ }
+ break;
}
return DefMDIChildProc(hwnd, msg, wparam, lparam);
@@ -753,12 +764,20 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
{
MSG msg;
HANDLE hAccelTable;
+ char consoleTitle[512];
+ HWND hwndConsole;
// Setup the hInst global
hInst = hInstance;
// Do the setup
if (!Setup(&hAccelTable))
return 0;
+ // Need to set up a console so that we can send ctrl-break signal
+ // to inferior Caml
+ AllocConsole();
+ GetConsoleTitle(consoleTitle,sizeof(consoleTitle));
+ hwndConsole = FindWindow(NULL,consoleTitle);
+ ShowWindow(hwndConsole,SW_HIDE);
// Create main window and exit if this fails
if ((hwndMain = CreateinriaWndClassWnd()) == (HWND)0)
return 0;
diff --git a/win32caml/ocaml.rc b/win32caml/ocaml.rc
index 7865b1b40..4fd1640b4 100644
--- a/win32caml/ocaml.rc
+++ b/win32caml/ocaml.rc
@@ -47,6 +47,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "&History", IDM_HISTORY
MENUITEM "&Garbage collect", IDM_GC
+ MENUITEM "&Interrupt", IDCTRLC
END
POPUP "&Window"
BEGIN
diff --git a/win32caml/startocaml.c b/win32caml/startocaml.c
index 7d3d12f2d..ac99bf909 100644
--- a/win32caml/startocaml.c
+++ b/win32caml/startocaml.c
@@ -315,3 +315,14 @@ error:
goto error;
return result;
}
+
+
+void InterruptOcaml(void)
+{
+ if (! GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pi.dwProcessId)) {
+ char message[1024];
+ sprintf(message, "GenerateConsole failed: %d\n", GetLastError());
+ MessageBox(NULL, message, "Ocaml", MB_OK);
+ }
+ WriteToPipe(" ");
+}