home *** CD-ROM | disk | FTP | other *** search
- #if defined(__MWERKS__) || defined (THINK_C)
- #ifdef THINK_C
- #include <MacHeaders>
- #endif
- #include <Sound.h>
- #include <Palettes.h>
- #include "mlvalues.h"
- #include "alloc.h"
- #include "memory.h"
- #include "fail.h"
- #include "str.h"
- #include "ui.h"
- #else
- /* MPW ? */
- #include <Events.h>
- #include <Fonts.h>
- #include <math.h>
- #include <Memory.h>
- #include <OSUtils.h>
- #include <QuickDraw.h>
- #include <Sound.h>
- #include "::runtime:mlvalues.h"
- #include "::runtime:alloc.h"
- #include "::runtime:memory.h"
- #include "::runtime:fail.h"
- #include "::runtime:str.h"
- #include "ui.h"
- #endif
-
- extern void enter_blocking_section (void);
- extern void leave_blocking_section (void);
-
- #define SBWIDTH 16 /* largeur scroll bar */
- #define Visible 0xFF /* controle visible */
- #define inVisible 0 /* controle invisible */
- #define FONTSIZE 9 /* taille des caracteres */
- #define WMINSIZE 70 /* minimum taille d'une fenetre */
- #define MARGINDRAG 4 /* marge limite pour drag */
- #define SIZEX 480 /* taille par defaut CamlGraph */
- #define SIZEY 280 /* taille par defaut CamlGraph */
-
- #define grafpk ((graphPeek) CAMLOffScreen)
- #define offset_x (grafpk->destRect.left - grafpk->viewRect.left)
- #define offset_y (grafpk->destRect.top - grafpk->viewRect.top)
- #define Short_val(x) ((short) Long_val(x))
- #define convert_y(y) (CAMLOffScreen->portRect.bottom - 1 - Short_val(y))
-
- #define Begin_offscreen \
- { GDHandle old_device; \
- if (color_qd){ \
- old_device = GetGDevice (); \
- SetGDevice (CAMLGDevice); \
- SetPort (CAMLOffScreen); \
- }
-
- #define End_offscreen \
- if (color_qd){ \
- SetGDevice (old_device); \
- } \
- }
-
- typedef struct graph {
- GrafPort offScreen;
- Rect destRect;
- Rect viewRect;
- Rect destRectZoom;
- } graphRecord, *graphPeek;
-
- #define gp ((graphPeek) CAMLOffScreen)
-
- int color_qd = 0;
- int max_depth = 1;
- GDHandle CAMLGDevice = nil;
- WindowPtr CAMLGraph = nil;
- WindowPtr CAMLOffScreen = nil;
-
- #define N_graph_events 20
- static EventRecord graph_event_queue [N_graph_events];
- static int graph_event_head = 0;
- static int graph_event_tail = 0;
-
- #define Incr(x) (x) = ((x) + 1) % N_graph_events
-
- static void push_graph_event (EventRecord *event)
- { graph_event_queue [graph_event_head] = *event;
- Incr (graph_event_head);
- if (graph_event_head == graph_event_tail) Incr (graph_event_tail);
- }
-
- static void copy_bits (const BitMap *srcBits, const BitMap *dstBits, const Rect *srcRect,
- const Rect *dstRect, short mode, RgnHandle maskRgn)
- {
- if (color_qd){
- RGBColor fore, back;
- RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
- RGBColor black = {0, 0, 0};
-
- GetForeColor (&fore);
- GetBackColor (&back);
- RGBForeColor (&black);
- RGBBackColor (&white);
- CopyBits (srcBits, dstBits, srcRect, dstRect, mode, maskRgn);
- RGBForeColor (&fore);
- RGBBackColor (&back);
- }else{
- CopyBits (srcBits, dstBits, srcRect, dstRect, mode, maskRgn);
- }
- }
-
- static void copy_mask (const BitMap *srcBits, const BitMap *maskBits, const BitMap *dstBits,
- const Rect *srcRect, const Rect *maskRect, const Rect *dstRect)
- {
- if (color_qd){
- RGBColor fore, back;
- RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
- RGBColor black = {0, 0, 0};
-
- GetForeColor (&fore);
- GetBackColor (&back);
- RGBForeColor (&black);
- RGBBackColor (&white);
- CopyMask (srcBits, maskBits, dstBits, srcRect, maskRect, dstRect);
- RGBForeColor (&fore);
- RGBBackColor (&back);
- }else{
- CopyMask (srcBits, maskBits, dstBits, srcRect, maskRect, dstRect);
- }
- }
-
- static void DoClose(WindowPtr window)
- {
- if (window && window == CAMLGraph)
- { /* GetWindowPos(CAMLGraph, &Pref->GrWindowRect); */
- if (color_qd){
- if ((*((CGrafPtr) CAMLOffScreen)->portPixMap)->baseAddr != nil)
- DisposePtr ((*((CGrafPtr) CAMLOffScreen)->portPixMap)->baseAddr);
- CloseCPort ((CGrafPtr) CAMLOffScreen);
- DisposeGDevice (CAMLGDevice);
- CAMLGDevice = nil;
- }else{
- if (CAMLOffScreen->portBits.baseAddr != nil)
- DisposePtr(CAMLOffScreen->portBits.baseAddr);
- ClosePort(CAMLOffScreen);
- }
- DisposePtr((Ptr) CAMLOffScreen);
- /* DisableItem(GetMHandle(mCaml), iShowGraph); */
- CAMLGraph = nil;
- CAMLOffScreen = nil;
- }
- CloseWindow(window);
- DisposePtr((Ptr) window);
- }
-
- typedef struct data {
- WindowRecord window;
- ControlHandle vSBar;
- ControlHandle hSBar;
- graphPeek h;
- } dataRecord, *dataPeek;
-
- static void FixViewRect(WindowPtr window)
- {
- Rect viewRect;
-
- viewRect = window->portRect;
- viewRect.right -= SBWIDTH - 1;
- viewRect.bottom -= SBWIDTH - 1;
- ((graphPeek )CAMLOffScreen)->viewRect = viewRect;
- }
-
- static void SetScrollBar(ControlHandle control, short max, short value)
- {
- unsigned char state;
-
- if (max < value)
- max = value;
- if ((max != GetControlMaximum(control)) || (value != GetControlValue(control))) {
- state = (*control)->contrlVis;
- (*control)->contrlVis = inVisible; /* empeche SetCtl... de dessiner la scroll bar */
- SetControlMaximum(control, max); /* pour pouvoir le faire seulement sur demande */
- SetControlValue(control, value); /* (ca sert pour DoGrowWindow...) */
- if (state == Visible)
- ShowControl(control);
- }
- }
-
- static void FixScrollBar(dataPeek doc)
- {
- Rect r;
-
- r = ((WindowPtr) doc)->portRect;
- (*doc->vSBar)->contrlVis = inVisible;
- (*doc->hSBar)->contrlVis = inVisible;
- SizeControl(doc->vSBar, SBWIDTH, r.bottom - r.top - SBWIDTH + 3);
- MoveControl(doc->vSBar, r.right - SBWIDTH + 1, -1);
- SizeControl(doc->hSBar, r.right - r.left - SBWIDTH + 3, SBWIDTH);
- MoveControl(doc->hSBar, -1, r.bottom - SBWIDTH + 1);
- (*doc->vSBar)->contrlVis = Visible;
- (*doc->hSBar)->contrlVis = Visible;
- }
-
- static void AdjustScrollBars(dataPeek doc)
- {
- short max, value, scale;
- long x;
-
- max = gp->destRect.bottom - gp->destRect.top - gp->viewRect.bottom + gp->viewRect.top;
- value = gp->viewRect.top - gp->destRect.top;
- SetScrollBar(doc->vSBar, max, value);
- max = gp->destRect.right - gp->destRect.left - gp->viewRect.right + gp->viewRect.left;
- value = gp->viewRect.left - gp->destRect.left;
- SetScrollBar(doc->hSBar, max, value);
- }
-
- static void ScrollGraph(dataPeek doc, short dh, short dv)
- {
- RgnHandle updateRgn;
- Rect r, offRect;
- short max, value;
-
- updateRgn = NewRgn();
- ScrollRect(&gp->viewRect, dh, dv, updateRgn);
- OffsetRect(&gp->destRect, dh, dv);
- SectRect(&gp->viewRect, &(*updateRgn)->rgnBBox, &r);
- offRect = r;
- OffsetRect(&offRect, gp->viewRect.left - gp->destRect.left, gp->viewRect.top - gp->destRect.top);
- SetPort (CAMLGraph);
- copy_bits (&CAMLOffScreen->portBits, &CAMLGraph->portBits, &offRect, &r, srcCopy, nil);
- DisposeRgn(updateRgn);
- max = gp->destRect.bottom - gp->destRect.top - gp->viewRect.bottom + gp->viewRect.top;
- value = gp->viewRect.top - gp->destRect.top;
- SetScrollBar(doc->vSBar, max, value);
- max = gp->destRect.right - gp->destRect.left - gp->viewRect.right + gp->viewRect.left;
- value = gp->viewRect.left - gp->destRect.left;
- SetScrollBar(doc->hSBar, max, value);
- }
-
- #define NSPIXEL 10 /* nombre de pixels a scroller */
-
- static pascal void DoClickGraphSBar(ControlHandle control, short part)
- {
- dataPeek doc;
- graphPeek g;
- short d, value;
-
- if (part) {
- doc = (dataPeek) (*control)->contrlOwner;
- g = (graphPeek) doc->h;
- value = GetControlValue(control);
- switch (part) {
- case kControlUpButtonPart: // inUpButton
- case kControlDownButtonPart: // inDownButton
- d = NSPIXEL;
- break;
- case kControlPageUpPart: // inPageUp
- case kControlPageDownPart: // inPageDown
- if (control == doc->vSBar)
- d = g->viewRect.bottom - g->viewRect.top;
- else
- d = g->viewRect.right - g->viewRect.left;
- d -= NSPIXEL;
- break;
- }
- if ((part == kControlDownButtonPart) || (part == kControlPageDownPart))
- d = -d;
- if (d > value)
- d = value;
- else
- if (value - d > GetControlMaximum(control))
- d = value - GetControlMaximum(control);
- if (control == doc->vSBar)
- ScrollGraph(doc, 0, d);
- else
- ScrollGraph(doc, d, 0);
- }
- }
-
- ControlActionUPP tcUPP = 0;
-
- #define BTstQ(arg, bitnbr) (arg & (1 << bitnbr))
-
- static WindowPtr DoNew(Rect *boundsRect, Str255 title)
- {
- WindowPtr window;
- dataPeek storage;
- Boolean goAwayFlag;
- Rect r;
- long gesResponse;
-
- if( tcUPP == 0 ) /* first time */
- { tcUPP = NewControlActionProc(DoClickGraphSBar);
- if ( !Gestalt( gestaltQuickdrawFeatures, &gesResponse )
- && BTstQ( gesResponse, gestaltHasColor ) )
- { color_qd = 1; max_depth = 8; }
- else
- { color_qd = 0; max_depth = 1; }
- }
-
- storage = (dataPeek )NewPtr(sizeof(dataRecord));
- if (storage) {
- /* GetIndString(title, rWTitle, index); */
- goAwayFlag = 1;
- if (color_qd){
- window = (WindowPtr) NewCWindow (storage, boundsRect, title, false, zoomDocProc, nil, goAwayFlag, 0);
- }else{
- window = NewWindow(storage, boundsRect, title, false, zoomDocProc, nil, goAwayFlag, 0);
- }
- SetRect(&r, 0, 0, 16, 50);
- storage->vSBar = NewControl(window, &r, "\p", false, 0, 0, 0, scrollBarProc, 0);
- storage->hSBar = NewControl(window, &r, "\p", false, 0, 0, 0, scrollBarProc, 0);
- SetPort(window);
- SetOrigin(0,0);
- TextFont(monaco); /* la largeur des caractères est constante dans cette font */
- TextSize(FONTSIZE);
- FixScrollBar(storage);
- (*storage->vSBar)->contrlVis = inVisible; /* ShowWindow genere un updateEvt, qui prendra en charge le */
- (*storage->hSBar)->contrlVis = inVisible; /* remplissage de la nouvelle fenetre; il faut forcer les */
- ShowWindow(window); /* scroll bars a etre redessinees par DoActivate. */
- }
- return window;
- }
-
- static Boolean OpenGraph(Str255 title)
- {
- Rect r;
-
- SetRect( &r, 40, 40, 240, 240 ); /* fix this !! */
- if ( CAMLGraph = DoNew(&r, title) )
- {
- graph_event_head = graph_event_tail = 0;
- CAMLOffScreen = (GrafPtr )NewPtr(sizeof(graphRecord));
- if (CAMLOffScreen) {
- ((dataPeek )CAMLGraph)->h = gp;
- FixViewRect(CAMLGraph);
- r = gp->viewRect;
- r.right = r.left + SIZEX;
- r.bottom = r.top + SIZEY;
- if (color_qd){
- GDHandle the_max_device, old_device;
- CTabHandle color_map;
- Rect wide_open = {-32000, -32000, 32000, 32000};
- CGrafPtr color_off_screen = (CGrafPtr) CAMLOffScreen;
- long off_row_bytes;
-
- the_max_device = GetMaxDevice (&wide_open);
- old_device = GetGDevice ();
- CAMLGDevice = NewGDevice (0, 0);
- max_depth = (*(*the_max_device)->gdPMap)->pixelSize;
- **(*CAMLGDevice)->gdPMap = **(*the_max_device)->gdPMap;
- off_row_bytes = (max_depth * (r.right - r.left) + 31) / 32 * 4;
- (*(*CAMLGDevice)->gdPMap)->rowBytes = off_row_bytes + 0x8000;
- (*(*CAMLGDevice)->gdPMap)->baseAddr = NewPtr (off_row_bytes * (long) (r.bottom - r.top));
- if ((*(*CAMLGDevice)->gdPMap)->baseAddr == nil){
- DoClose (CAMLGraph);
- return false;
- }
- (*(*CAMLGDevice)->gdPMap)->bounds = r;
- color_map = (*(*the_max_device)->gdPMap)->pmTable;
- if (HandToHand ((Handle *) &color_map) != noErr){
- DoClose (CAMLGraph);
- return false;
- }
- (*(*CAMLGDevice)->gdPMap)->pmTable = color_map;
- SetGDevice (CAMLGDevice);
- MakeITable (nil, nil, (*the_max_device)->gdResPref);
- if (QDError () != noErr){
- SetGDevice (old_device);
- DoClose (CAMLGraph);
- return false;
- }
- OpenCPort (color_off_screen);
- SetGDevice (old_device);
- SetPalette (CAMLGraph, nil, 1);
- }else{
- max_depth = 1;
- OpenPort(CAMLOffScreen);
- CAMLOffScreen->portBits.rowBytes = (r.right - r.left + 31) / 32 * 4;
- CAMLOffScreen->portBits.baseAddr = NewPtr(CAMLOffScreen->portBits.rowBytes * (long) (r.bottom - r.top));
- CAMLOffScreen->portBits.bounds = r;
- if (CAMLOffScreen->portBits.baseAddr == nil){
- DoClose (CAMLGraph);
- return false;
- }
- }
- CAMLOffScreen->portRect = r;
- EraseRect(&r);
- r.bottom = gp->viewRect.bottom;
- r.top = r.bottom - SIZEY;
- gp->destRect = r;
- gp->destRectZoom = r;
- r = qd.screenBits.bounds;
- r.top += GetMBarHeight() + SBWIDTH;
- InsetRect(&r, MARGINDRAG, MARGINDRAG);
- if (r.right - r.left > SIZEX + SBWIDTH - 1)
- r.left = r.right - SIZEX - SBWIDTH + 1;
- if (r.bottom - r.top > SIZEY + SBWIDTH - 1)
- r.top = r.bottom - SIZEY - SBWIDTH + 1;
- (*((WStateDataHandle) ((WindowPeek) CAMLGraph)->dataHandle))->stdState = r;
- TextFont(monaco);
- TextSize(FONTSIZE);
- SetPort(CAMLGraph);
- AdjustScrollBars(((dataPeek )CAMLGraph));
- /* EnableItem(GetMHandle(mCaml), iShowGraph); */
- SelectWindow(CAMLGraph);
- return true;
- }
- DoClose(CAMLGraph);
- }
- return false;
- }
-
- static void DoGrow(WindowPtr window, EventRecord *event)
- {
- Rect r, *destRect;
- long newSize;
- short bound;
-
- r.right = gp->destRect.right - gp->destRect.left + SBWIDTH;
- r.bottom = gp->destRect.bottom - gp->destRect.top + SBWIDTH;
- r.left = WMINSIZE;
- r.top = WMINSIZE;
- if (newSize = GrowWindow(window, event->where, &r)) {
- SetPort(window);
- InvalRect(&window->portRect); /* on redessine tout ! */
- SizeWindow(window, LoWord(newSize), HiWord(newSize), true); /* la fenetre sera dessinee via un updateEvt */
- destRect = &((graphPeek) CAMLOffScreen)->destRect;
- bound = window->portRect.right - SBWIDTH + 1;
- if (bound > destRect->right)
- OffsetRect(destRect, bound - destRect->right, 0);
- bound = window->portRect.bottom - SBWIDTH + 1;
- if (bound > destRect->bottom)
- OffsetRect(destRect, 0, bound - destRect->bottom);
- ClipRect(&CAMLGraph->portRect);
- FixViewRect(window);
- (*((dataPeek) window)->vSBar)->contrlVis = inVisible; /* pour que AdjustScrollBars ne redessine pas */
- (*((dataPeek) window)->hSBar)->contrlVis = inVisible; /* les controles, ce sera fait par UpdtControls */
- AdjustScrollBars((dataPeek) window);
- FixScrollBar((dataPeek) window); /* remet les controles a l'etat visible */
- }
- }
-
- static void draw_grow_icon (WindowPtr window)
- {
- PenState saved_pen;
-
- SetPort (window);
- GetPenState (&saved_pen);
- PenNormal ();
- DrawGrowIcon (window);
- SetPenState (&saved_pen);
- }
-
- static void DoActivate(WindowPtr window, Boolean isActive)
- {
- dataPeek doc;
- Rect r;
- RgnHandle clipRgn, tempRgn;
-
- doc = (dataPeek) window;
- if (isActive) {
- SetPort(window);
- (*doc->vSBar)->contrlVis = Visible;
- (*doc->hSBar)->contrlVis = Visible;
- r = (*doc->vSBar)->contrlRect;
- InvalRect(&r); /* un updateEvt redessinera les controles */
- r = window->portRect;
- r.top = r.bottom - SBWIDTH + 1;
- InvalRect(&r);
- } else {
- HideControl(doc->vSBar);
- HideControl(doc->hSBar);
- draw_grow_icon(window);
- SetPort(window);
- ValidRect(&(*doc->vSBar)->contrlRect); /* permet d'eviter l'updateEvt genere par HideControl */
- ValidRect(&(*doc->hSBar)->contrlRect);
- }
- }
-
- static void DoUpdate(WindowPtr window)
- {
- Rect r;
-
- BeginUpdate(window);
- SetPort(window);
- EraseRect(&window->portRect);
- UpdateControls(window, window->visRgn);
- draw_grow_icon(window);
- r = window->portRect;
- r.right -= SBWIDTH - 1;
- r.bottom -= SBWIDTH - 1;
- if (SectRect(&r, &(*window->visRgn)->rgnBBox, &r))
- { Rect offRect = r;
-
- OffsetRect (&offRect, gp->viewRect.left - gp->destRect.left,
- gp->viewRect.top - gp->destRect.top);
- copy_bits (&CAMLOffScreen->portBits, &window->portBits,
- &offRect, &r, srcCopy, nil);
- }
- EndUpdate(window);
- }
-
- /* in cursor adjust
- if (isGraphWindow (window) && wait_graph_move){
- wait_graph_move = 0;
- GetMouse (&mouse);
- mouseRgn = NewRgn ();
- SetRectRgn (mouseRgn, mouse.h, mouse.v, mouse.h + 1, mouse.v + 1);
- OffsetRgn (mouseRgn, -window->portBits.bounds.left, -window->portBits.bounds.top);
- return mouseRgn;
- }
- */
-
- int DoGraphEvent(EventRecord *event, WindowPtr window)
- { /* window = FrontWindow() */
- Point mouse;
- dataPeek doc;
- WindowPtr mouse_window;
- ControlHandle control;
- graphPeek g;
- short part;
-
- switch (event->what)
- { case mouseDown:
- part = FindWindow( event->where, &mouse_window );
- if ( mouse_window != CAMLGraph ) return 0; /* not handled */
- switch (part)
- { case inGoAway:
- DoClose(CAMLGraph);
- return 1; /* handled */
- case inGrow:
- DoGrow(CAMLGraph,event);
- return 1; /* handled */
- case inDrag:
- DragWindow(CAMLGraph,event->where,&qd.screenBits.bounds);
- return 1; /* handled */
- case inContent:
- if (mouse_window != window)
- { SelectWindow(mouse_window);
- return 1; /* handled */
- }
- mouse = event->where;
- SetPort(window);
- GlobalToLocal(&mouse);
- switch ( FindControl( mouse, window, &control ))
- { case 0:
- push_graph_event (event);
- break;
- case kControlIndicatorPart: // inThumb
- doc = (dataPeek) window;
- if (TrackControl(control, mouse, nil))
- { g = (graphPeek) doc->h;
- if (control == doc->vSBar)
- ScrollGraph(doc, 0, g->viewRect.top - g->destRect.top - GetControlValue(control));
- else
- ScrollGraph(doc, g->viewRect.left - g->destRect.left - GetControlValue(control), 0);
- }
- break;
- default:
- TrackControl(control, mouse, tcUPP);
- break;
- }
- return 1; /* handled */
- case inZoomIn:
- case inZoomOut:
- if ((WindowPtr)event->message != CAMLGraph) return 0; /* not handled */
- if (TrackBox(window, event->where, part))
- { SetPort(window);
- EraseRect(&window->portRect);
- ZoomWindow(window, part, window == FrontWindow());
- FixViewRect(window);
- switch (part)
- { case inZoomIn:
- gp->destRect = gp->destRectZoom;
- break;
- case inZoomOut:
- gp->destRectZoom = gp->destRect;
- gp->destRect = gp->viewRect;
- gp->destRect.right = gp->destRect.left + SIZEX;
- gp->destRect.top = gp->destRect.bottom - SIZEY;
- }
- ClipRect(&CAMLGraph->portRect);
- InvalRect(&window->portRect);
- (*((dataPeek) window)->vSBar)->contrlVis = inVisible; /* pour que AdjustScrollBars ne redessine pas */
- (*((dataPeek) window)->hSBar)->contrlVis = inVisible; /* les controles, ce sera fait via le updateEvt */
- AdjustScrollBars((dataPeek) window);
- FixScrollBar((dataPeek) window);
- }
- return 1; /* handled */
- }
- return 0;
- case mouseUp:
- if (window != CAMLGraph) return 0; /* not handled */
- push_graph_event (event);
- return 1; /* handled */
- case keyDown:
- case autoKey:
- if ( event->modifiers & cmdKey || window != CAMLGraph )
- return 0; /* don't handle */
- push_graph_event (event);
- return 1; /* handled */
- case activateEvt:
- if ((WindowPtr)event->message != CAMLGraph) return 0; /* not handled */
- DoActivate(CAMLGraph, (event->modifiers & activeFlag));
- return 1; /* handled */
- case updateEvt:
- if ((WindowPtr)event->message != CAMLGraph) return 0; /* not handled */
- DoUpdate(CAMLGraph);
- return 1; /* handled */
- default:
- return 0;
- }
- }
-
- #if 0
-
- static long GetGraphEvent(EventRecord *event)
- {
- return os_get_next_event(event); /* add queue! */
- }
-
- #define PTL(a) *((long *)&(a)) /* coerce Point type to long */
-
- static void LookGraphEvent (EventRecord *event, int move_ok, int poll)
- {
- Point mouse_before, mouse_after;
- int i, did_it, ret_it;
- long res;
-
- OSEventAvail(0L, event); /* This returns a NULL event with the global mouse location */
- mouse_after = event->where;
- do
- { res = GetGraphEvent(event);
- mouse_before = mouse_after;
- mouse_after = event->where;
- did_it = 0;
- ret_it = 0;
- i = FindWindow(mouse_after,&event_window);
- switch (event->what)
- { case nullEvent:
- if ( poll || ( move_ok && ( PTL(mouse_after) != PTL(mouse_before) ) ) )
- ret_it = 1;
- else
- did_it = 1;
- break;
- default: ;
- }
- if ( did_it + ret_it == 0 ) os_handle_event(event);
- } while ( !ret_it );
- }
-
- static void LookGraphEvent (EventRecord *result, int move_ok, int poll)
- {
- Point mouse_before, mouse_after;
- int i;
-
- if (poll){
- GetMouse (&result->where);
- LocalToGlobal (&result->where);
- result->modifiers = Button () ? 0 : btnState;
- result->what = nullEvent;
- for (i = graph_event_tail; i != graph_event_head; Incr (i)){
- if (graph_event_queue [i].what == keyDown){
- result->what = keyDown;
- result->message = graph_event_queue [i].message;
- break;
- }
- }
- return;
- }
- if (graph_event_head != graph_event_tail){
- *result = graph_event_queue [graph_event_tail];
- Incr (graph_event_tail);
- return;
- }
- GetMouse (&mouse_before);
- LocalToGlobal (&mouse_before);
- while (1){
- /* wait_graph_move = move_ok; */
- /* LookEvent (15); */
- os_event_check();
- GetMouse (&mouse_after);
- LocalToGlobal (&mouse_after);
- #define PTL(a) *((long *)&(a)) /* coerce Point type to long */
- if (move_ok && PTL(mouse_after) != PTL(mouse_before)
- || graph_event_head != graph_event_tail)
- break;
- }
- if (graph_event_head == graph_event_tail){
- *result = graph_event_queue [graph_event_head];
- result->what = nullEvent;
- }else{
- *result = graph_event_queue [graph_event_tail];
- Incr (graph_event_tail);
- }
- }
-
- #endif
-
- #define PTL(a) *((long *)&(a)) /* coerce Point type to long */
-
- static void LookGraphEvent (EventRecord *event, int move_ok, int poll)
- {
- Point mouse_before, mouse_after;
- int i;
-
- OSEventAvail(0L, event); /* returns a NULL event with the global mouse location & button */
- mouse_after = event->where;
- if (poll) /* just look */
- { for (i = graph_event_tail; i != graph_event_head; Incr (i))
- { if (graph_event_queue [i].what == keyDown)
- { event->what = keyDown;
- event->message = graph_event_queue [i].message;
- break;
- }
- }
- }
- else do
- { if (graph_event_head != graph_event_tail)
- { *event = graph_event_queue [graph_event_tail];
- Incr (graph_event_tail);
- return;
- }
- mouse_before = mouse_after;
- if ( os_get_next_event(event) ) os_handle_event(event);
- else
- { /* NULL event */
- mouse_after = event->where;
- if ( move_ok && ( PTL(mouse_after) != PTL(mouse_before) ) ) return;
- }
- } while ( 1 );
- }
-
- #undef Incr
-
- /* ***************************************************************** */
-
- void graphic_fail(char * msg)
- {
- raise_with_arg(GRAPHIC_FAILURE_EXN, copy_string(msg));
- }
-
- static void check_graph()
- {
- if (CAMLGraph == nil)
- graphic_fail("graphic window not opened");
- }
-
- value moveto(value x, value y) /* ML */
- {
- check_graph();
- SetPort(CAMLOffScreen);
- MoveTo(Short_val(x), convert_y(y));
- return Atom(0);
- }
-
- value open_graph(value str) /* ML */
- {
- Str255 tit;
- unsigned char *p;
- int i, len = string_length(str);
-
- if ( len > 64 ) len = 64;
- tit[0] = len;
- for (i = 1, p = (unsigned char *) String_val(str); i <= len; ) tit[i++] = *p++;
-
- if (CAMLGraph == nil) {
- if (!OpenGraph(tit))
- graphic_fail("open_graph: cannot open graphic window");
- moveto(Val_long(0), Val_long(0));
- }
- return Atom(0);
- }
-
- value close_graph() /* ML */
- {
- check_graph();
- DoClose(CAMLGraph);
- return Atom(0);
- }
-
- value clear_graph() /* ML */
- {
- check_graph();
- SetPort(CAMLGraph);
- EraseRect(&grafpk->viewRect);
- Begin_offscreen
- EraseRect(&CAMLOffScreen->portRect);
- End_offscreen
- return Atom(0);
- }
-
- value size_x() /* ML */
- {
- Rect * r;
-
- check_graph();
- r = &CAMLOffScreen->portRect;
- return Val_long(r->right - r->left);
- }
-
- value size_y() /* ML */
- {
- Rect * r;
-
- check_graph();
- r = &CAMLOffScreen->portRect;
- return Val_long(r->bottom - r->top);
- }
-
- value set_color(value color) /* ML */
- {
- long col = Long_val (color);
-
- check_graph();
- if (color_qd){
- RGBColor qd_col;
-
- qd_col.red = (col >> 16) * 257;
- qd_col.green = ((col >> 8) & 0xff) * 257;
- qd_col.blue = (col & 0xff) * 257;
- SetPort (CAMLGraph);
- RGBForeColor (&qd_col);
- Begin_offscreen
- RGBForeColor (&qd_col);
- End_offscreen
- }else{
- SetPort(CAMLGraph);
- if (col == 0xffffff){
- PenPat (&qd.white);
- TextMode (srcBic);
- }else{
- PenPat (&qd.black);
- TextMode (srcOr);
- }
- SetPort(CAMLOffScreen);
- if (col == 0xffffff){
- PenPat (&qd.white);
- TextMode (srcBic);
- }else{
- PenPat (&qd.black);
- TextMode (srcOr);
- }
- }
- return Atom(0);
- }
-
- value plot(value x, value y) /* ML */
- {
- short h, v;
- Point old_pen_size;
-
- check_graph();
- h = Short_val(x);
- v = convert_y(y);
- SetPort(CAMLOffScreen);
- old_pen_size = CAMLOffScreen->pnSize;
- PenSize (1, 1);
- MoveTo(h, v);
- LineTo(h, v);
- PenSize (old_pen_size.h, old_pen_size.v);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- h += offset_x;
- v += offset_y;
- PenSize (1, 1);
- MoveTo(h, v);
- LineTo(h, v);
- PenSize (old_pen_size.h, old_pen_size.v);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value point_color(value x, value y) /* ML */
- {
- Point p;
-
- check_graph();
- SetPt(&p, Short_val(x), convert_y(y));
- if (!PtInRect(p, &CAMLOffScreen->portRect))
- graphic_fail("point_color: point out of graphic window");
- if (color_qd){
- RGBColor qd_col;
- Begin_offscreen
- GetCPixel (p.h, p.v, &qd_col);
- End_offscreen
- return Val_long ((qd_col.red / 256 << 16)
- + (qd_col.green / 256 << 8)
- + (qd_col.blue / 256));
- }else{
- SetPort(CAMLOffScreen);
- return GetPixel(p.h, p.v) ? Val_long(0) : Val_long(0xFFFFFF);
- }
- }
-
- value current_point() /* ML */
- {
- value res;
- Point p;
-
- check_graph();
- SetPort(CAMLOffScreen);
- GetPen(&p);
- res = alloc_tuple(2);
- Field(res, 0) = Val_long(p.h);
- Field(res, 1) = Val_long(convert_y(Val_long(p.v)));
- return res;
- }
-
- value lineto(value x, value y) /* ML */
- {
- short h, v;
- Point p;
-
- check_graph();
- SetPort(CAMLOffScreen);
- GetPen(&p);
- h = Short_val(x);
- v = convert_y(y);
- LineTo(h, v);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- MoveTo(p.h + offset_x, p.v + offset_y);
- LineTo(h + offset_x, v + offset_y);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value draw_arc(value * argv, int argn) /* ML */
- {
- #pragma unused(argn)
- short h, v, r_x, r_y, start, arc;
- Rect r;
-
- check_graph();
- r_x = Short_val(argv[2]);
- r_y = Short_val(argv[3]);
- if ((r_x < 0) || (r_y < 0))
- graphic_fail("draw_arc: radius must be positives");
- h = Short_val(argv[0]);
- v = convert_y(argv[1]);
- SetRect(&r, h - r_x, v - r_y, h + r_x + 1, v + r_y + 1);
- SetPort(CAMLOffScreen);
- start = Short_val(argv[4]);
- arc = Short_val(argv[5]) - start;
- while (arc < 0)
- arc += 360;
- FrameArc(&r, 90 - start, -arc);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetRect(&r, offset_x, offset_y);
- FrameArc(&r, 90 - start, -arc);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value set_line_width(value width) /* ML */
- {
- short size;
-
- check_graph();
- size = Short_val(width);
- if (size < 0)
- graphic_fail("set_line_width: width must be positive");
- SetPort(CAMLOffScreen);
- PenSize(size, size);
- SetPort(CAMLGraph);
- PenSize(size, size);
- return Atom(0);
- }
-
- value draw_char(value ch) /* ML */
- {
- Point p;
-
- check_graph();
- Begin_offscreen
- GetPen(&p);
- DrawChar((char) Long_val(ch));
- End_offscreen
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- MoveTo(p.h + offset_x, p.v + offset_y);
- DrawChar((char) Long_val(ch));
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value draw_string(value str) /* ML */
- {
- mlsize_t len;
- Point p;
-
- check_graph();
- if ((len = string_length(str)) > 32767)
- len = 32767;
- Begin_offscreen
- GetPen(&p);
- DrawText(Bp_val(str), 0, (unsigned short) len);
- End_offscreen
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- MoveTo(p.h + offset_x, p.v + offset_y);
- DrawText(Bp_val(str), 0, (short) len);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value set_font(value str) /* ML */
- {
- Str255 name;
- short i, len, fontnum;
-
- check_graph();
- len = string_length(str);
- for(i = 0; (i < len) && (i < 255); i++)
- name[i + 1] = Byte(str, i);
- name[0] = i;
- GetFNum(name,&fontnum);
- SetPort(CAMLOffScreen);
- TextFont(fontnum);
- SetPort(CAMLGraph);
- TextFont(fontnum);
- return Atom(0);
- }
-
- value set_text_size(value size) /* ML */
- {
- short s;
-
- check_graph();
- SetPort(CAMLOffScreen);
- s = Short_val(size);
- if (s < 0)
- graphic_fail("set_text_size: size must be positive");
- TextSize(s);
- SetPort(CAMLGraph);
- TextSize(s);
- return Atom(0);
- }
-
- value text_size(value str) /* ML */
- {
- value res;
- FontInfo info;
-
- check_graph();
- SetPort(CAMLOffScreen);
- GetFontInfo(&info);
- res = alloc_tuple(2);
- Field(res, 0) = Val_long(TextWidth(Bp_val(str), 0, string_length(str)));
- Field(res, 1) = Val_long(info.ascent + info.descent);
- return res;
- }
-
- value fill_rect(value x, value y, value wdth, value hgth) /* ML */
- {
- short h, v, width, heigth;
- Rect r;
-
- check_graph();
- width = Short_val(wdth);
- heigth = Short_val(hgth);
- if ((width < 0) || (heigth < 0))
- graphic_fail("fill_rect: width and heigth must be positives");
- h = Short_val(x);
- v = convert_y(y) + 1;
- SetRect(&r, h, v - heigth, h + width, v);
- SetPort(CAMLOffScreen);
- PaintRect(&r);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetRect(&r, offset_x, offset_y);
- PaintRect(&r);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value fill_arc(value * argv, int argn) /* ML */
- {
- #pragma unused(argn)
- short h, v, r_x, r_y, start, arc;
- Rect r;
-
- check_graph();
- r_x = Short_val(argv[2]);
- r_y = Short_val(argv[3]);
- if ((r_x < 0) || (r_y < 0))
- graphic_fail("draw_arc: radius must be positives");
- h = Short_val(argv[0]);
- v = convert_y(argv[1]);
- SetRect(&r, h - r_x, v - r_y, h + r_x + 1, v + r_y + 1);
- start = Short_val(argv[4]);
- arc = Short_val(argv[5]) - start;
- while (arc < 0)
- arc += 360;
- SetPort(CAMLOffScreen);
- PaintArc(&r, 90 - start, -arc);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetRect(&r, offset_x, offset_y);
- PaintArc(&r, 90 - start, -arc);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value fill_poly(value vect) /* ML */
- {
- int n_points, i;
- PolyHandle poly;
-
- check_graph();
- n_points = Wosize_val(vect);
- if (n_points < 3)
- graphic_fail("fill_poly: not enough points");
- SetPort(CAMLOffScreen);
- poly = OpenPoly();
- MoveTo(Short_val(Field(Field(vect, 0), 0)), convert_y(Field(Field(vect, 0), 1)));
- for(i = 1; i < n_points; i++)
- LineTo(Short_val(Field(Field(vect, i), 0)), convert_y(Field(Field(vect, i), 1)));
- LineTo(Short_val(Field(Field(vect, 0), 0)), convert_y(Field(Field(vect, 0), 1)));
- ClosePoly();
- PaintPoly(poly);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetPoly(poly, offset_x, offset_y);
- PaintPoly(poly);
- ClipRect(&CAMLGraph->portRect);
- KillPoly(poly);
- return Atom(0);
- }
-
- struct image {
- value w;
- value h;
- value data;
- value mask;
- };
-
- #define Width(i) (((struct image *) i)->w)
- #define Height(i) (((struct image *) i)->h)
- #define Data(i) (((struct image *) i)->data)
- #define Mask(i) (((struct image *) i)->mask)
-
- static value new_bits(int width, int height, int depth)
- {
- int rowbytes, nbytes, nwords;
- value res;
-
- rowbytes = (depth * width + 31) / 32 * 4;
- nbytes = rowbytes * height;
- nwords = (nbytes + 3) / 4;
- if (nwords == 0) return Atom (Abstract_tag);
- if (nwords <= Max_young_wosize) {
- res = alloc(nwords, Abstract_tag);
- }else{
- res = alloc_shr(nwords, Abstract_tag);
- }
- return res;
- }
-
- static BitMap **image_to_bitmap (value image, int w, int h, int is_mask)
- {
- if (color_qd && !is_mask){
- GDHandle old_device;
- PixMapHandle result;
-
- old_device = GetGDevice ();
- SetGDevice (CAMLGDevice);
- result = NewPixMap ();
- DisposeHandle ((Handle) (*result)->pmTable);
- (*result)->pmTable = (*((CGrafPtr) CAMLOffScreen)->portPixMap)->pmTable;
- (*result)->baseAddr = (Ptr) image;
- (*result)->rowBytes = (max_depth * w + 31) / 32 * 4 + 0x8000;
- SetRect (&(*result)->bounds, 0, 0, w, h);
- SetGDevice (old_device);
- return (BitMap **) result;
- }else{
- BitMap **result = (BitMap **) NewHandle (sizeof (BitMap));
-
- (*result)->baseAddr = (Ptr) image;
- (*result)->rowBytes = (w + 31) / 32 * 4;
- SetRect(&(*result)->bounds, 0, 0, w, h);
- return result;
- }
- }
-
- value make_image (value mat) /* ML */
- {
- int height, width, i, j;
- int has_transp;
- GrafPtr old_port;
- value res;
- Push_roots(roots, 3)
- #define bdata (roots[0])
- #define bmask (roots[1])
- #define matrix (roots[2])
-
- check_graph ();
- matrix = mat;
- GetPort (&old_port);
- height = Wosize_val(matrix);
- if (height == 0) {
- width = 0;
- } else {
- width = Wosize_val(Field(matrix, 0));
- for (i = 1; i < height; i++) {
- if (width != Wosize_val(Field(matrix, i)))
- graphic_fail("make_image: non-rectangular matrix");
- }
- }
- bdata = new_bits (width, height, max_depth);
- has_transp = 0;
- if (color_qd){
- CGrafPort port;
- RGBColor qd_col;
- long col;
-
- OpenCPort (&port);
- DisposeHandle ((Handle) port.portPixMap);
- port.portPixMap = (PixMapHandle) image_to_bitmap (bdata, width, height, 0);
- port.portRect = (*port.portPixMap)->bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- col = Long_val (Field (Field (matrix, i), j));
- if (col == -1){
- has_transp = 1;
- }else{
- qd_col.red = (col >> 16) * 256;
- qd_col.green = ((col >> 8) & 0xff) * 256;
- qd_col.blue = (col & 0xff) * 256;
- SetCPixel (j, i, &qd_col);
- }
- }
- }
- SetPort (old_port);
- CloseCPort (&port);
- }else{
- GrafPort port;
- BitMap **h;
-
- OpenPort (&port);
- h = image_to_bitmap (bdata, width, height, 0);
- port.portBits = **h;
- DisposeHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- EraseRect (&port.portBits.bounds);
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- switch (Long_val (Field (Field (matrix, i), j))){
- case -1: has_transp = 1; break;
- case 0xFFFFFF: break;
- default: MoveTo (j, i); Line (0, 0); break;
- }
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }
- if (has_transp) {
- GrafPort port;
- BitMap **h;
-
- bmask = new_bits (width, height, 1);
- OpenPort (&port);
- h = image_to_bitmap (bmask, width, height, 1);
- port.portBits = **h;
- DisposeHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- EraseRect (&port.portBits.bounds);
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- if (Long_val (Field (Field (matrix, i), j)) != -1){
- MoveTo (j, i); Line (0, 0);
- }
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }else{
- bmask = Val_long (0);
- }
- res = alloc_tuple (4);
- Width (res) = Val_int (width);
- Height (res) = Val_int (height);
- Data (res) = bdata;
- Mask (res) = bmask;
- Pop_roots ();
- return res;
- #undef matrix
- #undef bdata
- #undef bmask
- }
-
- static value alloc_int_vect(mlsize_t size)
- {
- value res;
- mlsize_t i;
-
- if (size == 0) return Atom(0);
- if (size <= Max_young_wosize) {
- res = alloc(size, 0);
- } else {
- res = alloc_shr(size, 0);
- }
- for (i = 0; i < size; i++) {
- Field(res, i) = Val_long(0);
- }
- return res;
- }
-
- value dump_image(value image) /* ML */
- {
- int height, width, i, j;
- GrafPtr old_port;
- Push_roots(roots, 2);
- #define matrix (roots[0])
- #define im (roots [1])
-
- check_graph ();
- im = image;
- GetPort (&old_port);
- height = Int_val (Height (im));
- width = Int_val (Width (im));
- matrix = alloc_int_vect (height);
- for (i = 0; i < height; i++) {
- modify (&Field (matrix, i), alloc_int_vect (width));
- }
-
- if (color_qd){
- CGrafPort port;
- RGBColor qd_col;
-
- OpenCPort (&port);
- DisposeHandle ((Handle) port.portPixMap);
- port.portPixMap
- = (PixMapHandle) image_to_bitmap (Data (im), width, height, 0);
- port.portRect = (*port.portPixMap)->bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- GetCPixel (j, i, &qd_col);
- Field (Field (matrix, i), j) = Val_long ((qd_col.red / 256 << 16)
- + (qd_col.green / 256 << 8)
- + qd_col.blue / 256);
- }
- }
- SetPort (old_port);
- CloseCPort (&port);
- }else{
- GrafPort port;
- BitMap **h;
-
- OpenPort (&port);
- h = image_to_bitmap (Data (im), width, height, 0);
- port.portBits = **h;
- DisposeHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- Field (Field (matrix, i), j)
- = Val_long (GetPixel (j, i) ? 0 : 0xFFFFFF);
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }
-
- if (Mask(im) != Val_long(0)) {
- GrafPort port;
- BitMap **h;
-
- OpenPort (&port);
- h = image_to_bitmap (Mask (im), width, height, 1);
- port.portBits = **h;
- DisposeHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- if (! GetPixel (j, i)) Field (Field (matrix, i), j) = -1;
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }
- Pop_roots();
- return matrix;
- #undef matrix
- #undef im
- }
-
- value draw_image(value image, value x, value y) /* ML */
- {
- short rx, ry;
- int w, h;
- BitMap **src_bitmap, **mask_bitmap;
- Rect dst_rect, src_rect;
-
- check_graph();
- w = Int_val (Width (image));
- h = Int_val (Height (image));
- rx = Long_val(x);
- ry = convert_y(y) - h + 1;
- SetRect (&dst_rect, rx, ry, rx + w, ry + h);
- SetRect (&src_rect, 0, 0, w, h);
- Begin_offscreen
- if (Mask (image) != Val_long(0)) {
- src_bitmap = image_to_bitmap (Data(image), w, h, 0);
- mask_bitmap = image_to_bitmap (Mask(image), w, h, 1);
- copy_mask (*src_bitmap, *mask_bitmap, &CAMLOffScreen->portBits,
- &src_rect, &src_rect, &dst_rect);
- DisposeHandle ((Handle) src_bitmap);
- DisposeHandle ((Handle) mask_bitmap);
- }else{
- src_bitmap = image_to_bitmap (Data(image), w, h, 0);
- copy_bits (*src_bitmap, &CAMLOffScreen->portBits,
- &src_rect, &dst_rect, srcCopy, nil);
- DisposeHandle ((Handle) src_bitmap);
- }
- End_offscreen
- OffsetRect(&dst_rect, offset_x, offset_y);
- SectRect(&dst_rect, &grafpk->viewRect, &dst_rect);
- src_rect = dst_rect;
- OffsetRect(&src_rect, -offset_x, -offset_y);
- SetPort (CAMLGraph);
- copy_bits (&CAMLOffScreen->portBits, &CAMLGraph->portBits,
- &src_rect, &dst_rect, srcCopy, nil);
- return Atom(0);
- }
-
- value create_image (value w, value h) /* ML */
- {
- value res;
- Push_roots (roots, 1);
- #define bdata (roots[0])
-
- check_graph ();
- if (Int_val (w) < 0 || Int_val (h) < 0)
- graphic_fail("get_image: width and height must be positive");
- bdata = new_bits (Int_val (w), Int_val (h), max_depth);
- res = alloc_tuple (4);
- Width (res) = w;
- Height (res) = h;
- Data (res) = bdata;
- Mask (res) = Val_long (0);
- Pop_roots ();
- return res;
- #undef bdata
- }
-
- value blit_image (value i, value x, value y) /* ML */
- {
- short rx, ry, width, height;
- BitMap **dst_bitmap;
- Rect src_rect;
-
- check_graph();
- width = Short_val (Width (i));
- height = Short_val (Height (i));
- dst_bitmap = image_to_bitmap (Data (i), width, height, 0);
- rx = Short_val(x);
- ry = convert_y(y) + 1;
- SetRect (&src_rect, rx, ry - height, rx + width, ry);
- Begin_offscreen
- copy_bits (&CAMLOffScreen->portBits, *dst_bitmap,
- &src_rect, &(*dst_bitmap)->bounds, srcCopy, nil);
- End_offscreen
- return Atom (0);
- }
-
- value wait_event (value l) /* ML */
- {
- int b_down = 0;
- int b_up = 0;
- int key_press = 0;
- int motion = 0;
- int poll = 0;
- EventRecord event;
- value result;
-
- check_graph ();
- enter_blocking_section ();
- while (l != Atom (0)){
- switch (Tag_val (Field (l, 0))){
- case 0: b_down = 1; break;
- case 1: b_up = 1; break;
- case 2: key_press = 1; break;
- case 3: motion = 1; break;
- case 4: poll = 1; break;
- }
- l = Field (l, 1);
- }
- while (1){
- LookGraphEvent (&event, motion, poll);
- if (poll || motion
- || b_down && event.what == mouseDown
- || b_up && event.what == mouseUp
- || key_press && event.what == keyDown)
- break;
- }
- result = alloc_tuple (5);
- SetPort (CAMLGraph);
- GlobalToLocal (&event.where);
- Field (result, 0) = Val_int (event.where.h - offset_x);
- Field (result, 1) = Val_int (CAMLOffScreen->portRect.bottom - 1
- - (event.where.v - offset_y));
- Field (result, 2) = Atom (!(event.modifiers & btnState));
- if (event.what == keyDown){
- Field (result, 3) = Atom (1);
- Field (result, 4) = Val_int (event.message & charCodeMask);
- }else{
- Field (result, 3) = Atom (0);
- Field (result, 4) = Val_int (0);
- }
- leave_blocking_section ();
- return result;
- }
-
- value sound(value freq, value delay) /* ML */
- {
- long f = Long_val (freq);
- long d = Long_val (delay);
- int note;
- SndCommand cmd;
- SndChannelPtr chan = NULL;
-
- enter_blocking_section();
- note = 69 + (log((double) f / 440.0) / log(twelfthRootTwo) + 0.5);
- if (note < 1) note = 1;
- if (note > 127) note = 127;
- cmd.cmd = freqDurationCmd;
- cmd.param1 = d * 2;
- cmd.param2 = 0xFF000000 + note;
- if (SndNewChannel (&chan, squareWaveSynth, 0, NULL) != noErr){
- SysBeep (1);
- }else{
- if (SndDoCommand (chan, &cmd, 0) != noErr) SysBeep(1);
- SndDisposeChannel (chan, 0);
- }
- leave_blocking_section();
- return Atom(0);
- }
-