summaryrefslogtreecommitdiff
path: root/ocaml-binary-annot/otherlibs/win32graph/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml-binary-annot/otherlibs/win32graph/open.c')
-rw-r--r--ocaml-binary-annot/otherlibs/win32graph/open.c364
1 files changed, 364 insertions, 0 deletions
diff --git a/ocaml-binary-annot/otherlibs/win32graph/open.c b/ocaml-binary-annot/otherlibs/win32graph/open.c
new file mode 100644
index 0000000000..2797bc669a
--- /dev/null
+++ b/ocaml-binary-annot/otherlibs/win32graph/open.c
@@ -0,0 +1,364 @@
+/***********************************************************************/
+/* */
+/* Objective Caml */
+/* */
+/* Developed by Jacob Navia, based on code by J-M Geffroy and X Leroy */
+/* Copyright 2001 Institut National de Recherche en Informatique et */
+/* en Automatique. All rights reserved. This file is distributed */
+/* under the terms of the GNU Library General Public License, with */
+/* the special exception on linking described in file ../../LICENSE. */
+/* */
+/***********************************************************************/
+
+/* $Id$ */
+
+#include <fcntl.h>
+#include <signal.h>
+#include "mlvalues.h"
+#include "fail.h"
+#include "libgraph.h"
+#include "callback.h"
+#include <windows.h>
+
+static value gr_reset(void);
+static long tid;
+static HANDLE threadHandle;
+HWND grdisplay = NULL;
+int grscreen;
+COLORREF grwhite, grblack;
+COLORREF grbackground;
+int grCurrentColor;
+struct canvas grbstore;
+BOOL grdisplay_mode;
+BOOL grremember_mode;
+int grx, gry;
+int grcolor;
+extern HFONT * grfont;
+MSG msg;
+
+static char *szOcamlWindowClass = "OcamlWindowClass";
+static BOOL gr_initialized = 0;
+CAMLprim value caml_gr_clear_graph(void);
+HANDLE hInst;
+
+HFONT CreationFont(char *name)
+{
+ LOGFONT CurrentFont;
+ memset(&CurrentFont, 0, sizeof(LOGFONT));
+ CurrentFont.lfCharSet = ANSI_CHARSET;
+ CurrentFont.lfWeight = FW_NORMAL;
+ CurrentFont.lfHeight = grwindow.CurrentFontSize;
+ CurrentFont.lfPitchAndFamily = (BYTE) (FIXED_PITCH | FF_MODERN);
+ strcpy(CurrentFont.lfFaceName, name); /* Courier */
+ return (CreateFontIndirect(&CurrentFont));
+}
+
+void SetCoordinates(HWND hwnd)
+{
+ RECT rc;
+
+ GetClientRect(hwnd,&rc);
+ grwindow.width = rc.right;
+ grwindow.height = rc.bottom;
+ gr_reset();
+}
+
+void ResetForClose(HWND hwnd)
+{
+ DeleteDC(grwindow.tempDC);
+ DeleteDC(grwindow.gcBitmap);
+ DeleteObject(grwindow.hBitmap);
+ memset(&grwindow,0,sizeof(grwindow));
+ gr_initialized = 0;
+}
+
+
+
+static LRESULT CALLBACK GraphicsWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ switch (msg) {
+ // Create the MDI client invisible window
+ case WM_CREATE:
+ break;
+ case WM_PAINT:
+ hdc = BeginPaint(hwnd,&ps);
+ BitBlt(hdc,0,0,grwindow.width,grwindow.height,
+ grwindow.gcBitmap,0,0,SRCCOPY);
+ EndPaint(hwnd,&ps);
+ break;
+ // Move the child windows
+ case WM_SIZE:
+ // Position the MDI client window between the tool and status bars
+ if (wParam != SIZE_MINIMIZED) {
+ SetCoordinates(hwnd);
+ }
+
+ return 0;
+ // End application
+ case WM_DESTROY:
+ ResetForClose(hwnd);
+ break;
+ }
+ caml_gr_handle_event(msg, wParam, lParam);
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+int DoRegisterClass(void)
+{
+ WNDCLASS wc;
+
+ memset(&wc,0,sizeof(WNDCLASS));
+ wc.style = CS_HREDRAW|CS_VREDRAW |CS_DBLCLKS|CS_OWNDC ;
+ wc.lpfnWndProc = (WNDPROC)GraphicsWndProc;
+ wc.hInstance = hInst;
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wc.lpszClassName = szOcamlWindowClass;
+ wc.lpszMenuName = 0;
+ wc.hCursor = LoadCursor(NULL,IDC_ARROW);
+ wc.hIcon = 0;
+ return RegisterClass(&wc);
+}
+
+static value gr_reset(void)
+{
+ RECT rc;
+ int screenx,screeny;
+
+ screenx = GetSystemMetrics(SM_CXSCREEN);
+ screeny = GetSystemMetrics(SM_CYSCREEN);
+ GetClientRect(grwindow.hwnd,&rc);
+ grwindow.gc = GetDC(grwindow.hwnd);
+ grwindow.width = rc.right;
+ grwindow.height = rc.bottom;
+ if (grwindow.gcBitmap == (HDC)0) {
+ grwindow.hBitmap = CreateCompatibleBitmap(grwindow.gc,screenx,screeny);
+ grwindow.gcBitmap = CreateCompatibleDC(grwindow.gc);
+ grwindow.tempDC = CreateCompatibleDC(grwindow.gc);
+ SelectObject(grwindow.gcBitmap,grwindow.hBitmap);
+ SetMapMode(grwindow.gcBitmap,MM_TEXT);
+ MoveToEx(grwindow.gcBitmap,0,grwindow.height-1,0);
+ BitBlt(grwindow.gcBitmap,0,0,screenx,screeny,
+ grwindow.gcBitmap,0,0,WHITENESS);
+ grwindow.CurrentFontSize = 15;
+ grwindow.CurrentFont = CreationFont("Courier");
+ }
+ grwindow.CurrentColor = GetSysColor(COLOR_WINDOWTEXT);
+ grwindow.grx = 0;
+ grwindow.gry = 0;
+ grwindow.CurrentPen = SelectObject(grwindow.gc,GetStockObject(WHITE_PEN));
+ SelectObject(grwindow.gc,grwindow.CurrentPen);
+ SelectObject(grwindow.gcBitmap,grwindow.CurrentPen);
+ grwindow.CurrentBrush = SelectObject(grwindow.gc,GetStockObject(WHITE_BRUSH));
+ SelectObject(grwindow.gc,grwindow.CurrentBrush);
+ SelectObject(grwindow.gcBitmap,grwindow.CurrentBrush);
+ caml_gr_set_color(Val_long(0));
+ SelectObject(grwindow.gc,grwindow.CurrentFont);
+ SelectObject(grwindow.gcBitmap,grwindow.CurrentFont);
+ grdisplay_mode = grremember_mode = 1;
+ MoveToEx(grwindow.gc,0,grwindow.height-1,0);
+ MoveToEx(grwindow.gcBitmap,0,grwindow.height-1,0);
+ SetTextAlign(grwindow.gcBitmap,TA_BOTTOM);
+ SetTextAlign(grwindow.gc,TA_BOTTOM);
+ return Val_unit;
+}
+
+void SuspendGraphicThread(void)
+{
+ SuspendThread(threadHandle);
+}
+
+void ResumeGraphicThread(void)
+{
+ ResumeThread(threadHandle);
+}
+
+/* For handshake between the event handling thread and the main thread */
+static char * open_graph_errmsg;
+static HANDLE open_graph_event;
+
+static DWORD WINAPI gr_open_graph_internal(value arg)
+{
+ RECT rc;
+ int ret;
+ int event;
+ int x, y, w, h;
+ int screenx,screeny;
+ int attributes;
+ static int registered;
+ MSG msg;
+
+ gr_initialized = TRUE;
+ hInst = GetModuleHandle(NULL);
+ x = y = w = h = CW_USEDEFAULT;
+ sscanf(String_val(arg), "%dx%d+%d+%d", &w, &h, &x, &y);
+
+ /* Open the display */
+ if (grwindow.hwnd == NULL || !IsWindow(grwindow.hwnd)) {
+ if (!registered) {
+ registered = DoRegisterClass();
+ if (!registered) {
+ open_graph_errmsg = "Cannot register the window class";
+ SetEvent(open_graph_event);
+ return 1;
+ }
+ }
+ grwindow.hwnd = CreateWindow(szOcamlWindowClass,
+ WINDOW_NAME,
+ WS_OVERLAPPEDWINDOW,
+ x,y,
+ w,h,
+ NULL,0,hInst,NULL);
+ if (grwindow.hwnd == NULL) {
+ open_graph_errmsg = "Cannot create window";
+ SetEvent(open_graph_event);
+ return 1;
+ }
+#if 0
+ if (x != CW_USEDEFAULT) {
+ rc.left = 0;
+ rc.top = 0;
+ rc.right = w;
+ rc.bottom = h;
+ AdjustWindowRect(&rc,GetWindowLong(grwindow.hwnd,GWL_STYLE),0);
+ MoveWindow(grwindow.hwnd,x,y,rc.right-rc.left,rc.bottom-rc.top,1);
+ }
+#endif
+ }
+ gr_reset();
+ ShowWindow(grwindow.hwnd,SW_SHOWNORMAL);
+
+ /* Position the current point at origin */
+ grwindow.grx = 0;
+ grwindow.gry = 0;
+
+ caml_gr_init_event_queue();
+
+ /* The global data structures are now correctly initialized.
+ Restart the Caml main thread. */
+ open_graph_errmsg = NULL;
+ SetEvent(open_graph_event);
+
+ /* Enter the message handling loop */
+ while (GetMessage(&msg,NULL,0,0)) {
+ TranslateMessage(&msg); // Translates virtual key codes
+ DispatchMessage(&msg); // Dispatches message to window
+ if (!IsWindow(grwindow.hwnd))
+ break;
+ }
+ return 0;
+}
+
+CAMLprim value caml_gr_open_graph(value arg)
+{
+ long tid;
+ if (gr_initialized) return Val_unit;
+ open_graph_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ threadHandle =
+ CreateThread(NULL,0,
+ (LPTHREAD_START_ROUTINE)gr_open_graph_internal,(void **)arg,
+ 0,
+ &tid);
+ WaitForSingleObject(open_graph_event, INFINITE);
+ CloseHandle(open_graph_event);
+ if (open_graph_errmsg != NULL) gr_fail("%s", open_graph_errmsg);
+ return Val_unit;
+}
+
+CAMLprim value caml_gr_close_graph(void)
+{
+ if (gr_initialized) {
+ PostMessage(grwindow.hwnd, WM_CLOSE, 0, 0);
+ WaitForSingleObject(threadHandle, INFINITE);
+ }
+ return Val_unit;
+}
+
+CAMLprim value caml_gr_clear_graph(void)
+{
+ gr_check_open();
+ if(grremember_mode) {
+ BitBlt(grwindow.gcBitmap,0,0,grwindow.width,grwindow.height,
+ grwindow.gcBitmap,0,0,WHITENESS);
+ }
+ if(grdisplay_mode) {
+ BitBlt(grwindow.gc,0,0,grwindow.width,grwindow.height,
+ grwindow.gc,0,0,WHITENESS);
+ }
+ return Val_unit;
+}
+
+CAMLprim value caml_gr_size_x(void)
+{
+ gr_check_open();
+ return Val_int(grwindow.width);
+}
+
+CAMLprim value caml_gr_size_y(void)
+{
+ gr_check_open();
+ return Val_int(grwindow.height);
+}
+
+CAMLprim value caml_gr_resize_window (value vx, value vy)
+{
+ gr_check_open ();
+
+ /* FIXME TODO implement this function... */
+
+ return Val_unit;
+}
+
+CAMLprim value caml_gr_synchronize(void)
+{
+ gr_check_open();
+ BitBlt(grwindow.gc,0,0,grwindow.width,grwindow.height,
+ grwindow.gcBitmap,0,0,SRCCOPY);
+ return Val_unit ;
+}
+
+CAMLprim value caml_gr_display_mode(value flag)
+{
+ grdisplay_mode = (Int_val(flag)) ? 1 : 0;
+ return Val_unit ;
+}
+
+CAMLprim value caml_gr_remember_mode(value flag)
+{
+ grremember_mode = (Int_val(flag)) ? 1 : 0;
+ return Val_unit ;
+}
+
+CAMLprim value caml_gr_sigio_signal(value unit)
+{
+ return Val_unit;
+}
+
+CAMLprim value caml_gr_sigio_handler(void)
+{
+ return Val_unit;
+}
+
+
+/* Processing of graphic errors */
+
+static value * graphic_failure_exn = NULL;
+void gr_fail(char *fmt, char *arg)
+{
+ char buffer[1024];
+
+ if (graphic_failure_exn == NULL) {
+ graphic_failure_exn = caml_named_value("Graphics.Graphic_failure");
+ if (graphic_failure_exn == NULL)
+ invalid_argument("Exception Graphics.Graphic_failure not initialized, must link graphics.cma");
+ }
+ sprintf(buffer, fmt, arg);
+ raise_with_string(*graphic_failure_exn, buffer);
+}
+
+void gr_check_open(void)
+{
+ if (!gr_initialized) gr_fail("graphic screen not opened", NULL);
+}