/* Copyright 1990-1992 Laboratoire de Recherche en Informatique (LRI)Permission to use, copy, and modify this software and its documentationfor your own purposes is hereby granted without fee, provided thatthe above copyright notice appear in all copies and that both thatcopyright notice and this permission notice appear in supportingdocumentation, and use acknowledge that the software was developedby Laboratoire de Recherche en Informatique, Universite de Paris-Sud,Orsay, France. LRI makes no representations about the suitability ofthis software for any purpose.  It is provided "as is" without expressor implied warranty.This software or modified versions of this software cannot bedistributed in source or binary form, nor included into productswithout prior written permission of the author.LRI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALLIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL LRIBE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGESWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTIONOF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.Author:   ___    0  Thomas Baudel                 e-mail: thomas@lri.fr  /   \  /   LRI - Bat 490 /  __/ /    Universite de Paris-Sud       voice : +33 (1) 69 41 69 10/__   \/     91 405 ORSAY Cedex - FRANCE   fax   : +33 (1) 69 41 65 86*/#include <Values.h>#include <Types.h>#include <Resources.h>#include <QuickDraw.h>#include <Fonts.h>#include <Events.h>#include <Windows.h>#include <Menus.h>#include <TextEdit.h>#include <Dialogs.h>#include <Desk.h>#include <ToolUtils.h>#include <Memory.h>#include <SegLoad.h>#include <Files.h>#include <OSUtils.h>#include <OSEvents.h>#include <DiskInit.h>#include <Packages.h>#include <Traps.h>#include <Sound.h>#include <GestParse.h>	typedef struct grafobject {	struct grafobject* Next;	int Selected;	int Type;	Rect Extent;} GrafObject;GrafObject* Objects = 0;GestStructure* MyGrammar;#define	rMenuBar	128				/* application's menu bar */#define	rAboutAlert	128				/* about alert */#define	rUserAlert	129				/* error user alert */#define	rWindow		128				/* application's window */#define rStopRect	128				/* rectangle for Stop light */#define rGoRect		129				/* rectangle for Go light *//* The following constants are used to identify menus and their items. The menu IDs   have an "m" prefix and the item numbers within each menu have an "i" prefix. */#define	mApple					128		/* Apple menu */#define	iAbout					1#define	mFile					129		/* File menu */#define	iNew					1#define iOpen					2#define	iClose					4#define	iQuit					12#define	mEdit					130		/* Edit menu */#define	iUndo					1#define	iCut					3#define	iCopy					4#define	iPaste					5#define	iClear					6extern void _DataInit();void DrawWindow(WindowPtr);void add_rect (GestDescription* gest){     GrafObject* current = (GrafObject*) NewPtr (sizeof(GrafObject));	 current->Next = Objects; current->Selected = 0;	 current->Type = 0; current->Extent = gest->Extent;	 Objects = current;	 PaintRect (&current->Extent);}void add_oval (GestDescription* gest){     GrafObject* current = (GrafObject*) NewPtr (sizeof(GrafObject));	 current->Next = Objects; current->Selected = 0;	 current->Type = 1;  current->Extent = gest->Extent;	 Objects = current;	 PaintOval (&current->Extent);}void add_triangle (GestDescription* gest){     GrafObject* current = (GrafObject*) NewPtr (sizeof(GrafObject));	 PolyHandle poly;	 	 current->Next = Objects; current->Selected = 0;	 current->Type = 2; current->Extent = gest->Extent;	 Objects = current;	 PenNormal ();	 poly = OpenPoly ();	 MoveTo (current->Extent.left, current->Extent.bottom);	 LineTo ((current->Extent.right + current->Extent.left) /2, current->Extent.top);	 LineTo (current->Extent.right, current->Extent.bottom);	 LineTo (current->Extent.left, current->Extent.bottom);	 ClosePoly ();	 PaintPoly (poly);	 KillPoly (poly);}void move_objects  (GestDescription* gest){	GrafObject* cur = Objects;	while (cur) {		if (PtInRect (gest->Begin, &(cur->Extent))) break;		cur = cur->Next;	}	if (cur) 		OffsetRect (&(cur->Extent), gest->End.h - gest->Begin.h,  gest->End.v - gest->Begin.v);	else {		/* move the selection */	}	DrawWindow (FrontWindow()); /* should optimize the region to redraw */}void copy_objects (GestDescription* gest){	GrafObject* cur = Objects;	while (cur) {		if (PtInRect (gest->Begin, &(cur->Extent))) break;		cur = cur->Next;	}	if (cur)  {		gest->Extent = cur->Extent;		OffsetRect (&(gest->Extent), gest->End.h - gest->Begin.h,  gest->End.v - gest->Begin.v);		switch (cur->Type) {		case 0: add_rect (gest); break;		case 1: add_oval (gest); break;		case 2 : add_triangle (gest); break;		}	} else {		/* copy the selection */	}	DrawWindow (FrontWindow()); /* should optimize the region to redraw */}void delete_object  (GestDescription* gest){	GrafObject* cur = Objects;	if (! cur) return;	if (PtInRect (gest->Begin, &(Objects->Extent)))  {		cur = Objects;		Objects = Objects->Next;		DisposPtr ((Ptr) cur);		cur = 0;	} else {		GrafObject* cur2 = Objects->Next;		while (cur2) {			if (PtInRect (gest->Begin, &(cur2->Extent))) 				break;			cur = cur->Next;			cur2 = cur2->Next;		}		if (cur2) {			cur->Next = cur->Next->Next;			DisposPtr ((Ptr) cur2);		} else {			/* delete the selection */		}	}	DrawWindow (FrontWindow()); /* should optimize the region to redraw */}void select_objects  (GestDescription* gest) {	GrafObject* cur = Objects;	Rect tamp;	while (cur) {		cur->Selected = 0; cur = cur->Next;	} 	cur = Objects;	while (cur) {		if (SectRect (&(gest->Extent), &(cur->Extent), &tamp))			cur->Selected = 1;		cur = cur->Next;	}	DrawWindow (FrontWindow()); /* should optimize the region to redraw */}void modify_object  (GestDescription* gest){	GrafObject* cur = Objects;	while (cur) {		if (PtInRect (gest->Begin, &(cur->Extent))) break;		cur = cur->Next;	}	if (cur) 		cur->Extent = gest->Extent;	DrawWindow (FrontWindow()); /* should optimize the region to redraw */}#pragma segment Mainvoid DrawWindow(window) WindowPtr	window;{	GrafObject* current = Objects;	PolyHandle poly;	SetPort(window);    EraseRect(&window->portRect);	PenNormal ();	while (current) {		if (current->Selected) PenPat (qd.gray);  		else PenPat (qd.black);		switch (current->Type) {			case 0: PaintRect (&current->Extent); break;			case 1: PaintOval (&current->Extent); break;			case 2:  poly = OpenPoly ();						MoveTo (current->Extent.left, current->Extent.bottom);	 					LineTo ((current->Extent.right + current->Extent.left) /2, current->Extent.top);	 					LineTo (current->Extent.right, current->Extent.bottom);	 					LineTo (current->Extent.left, current->Extent.bottom); 						 ClosePoly ();	 					PaintPoly (poly);	 					KillPoly (poly);						break;		}		current = current->Next;	}}#pragma segment Mainvoid DoContentClick (event, window) EventRecord* event; WindowPtr	window;{	GestTrack (MyGrammar, event);}#pragma segment Initializevoid Initialize(){	Handle		menuBar;	WindowPtr	window;	InitGraf((Ptr) &qd.thePort);	InitFonts(); InitWindows();	InitMenus(); TEInit();	InitDialogs(nil); InitCursor();		window = (WindowPtr) NewPtr(sizeof(WindowRecord));	window = GetNewWindow(rWindow, (Ptr) window, (WindowPtr) -1);    SetPort (window);		menuBar = GetNewMBar(rMenuBar);		SetMenuBar(menuBar);		/* DisposHandle(menuBar); */	AddResMenu(GetMHandle(mApple), 'DRVR');		DrawMenuBar();		MyGrammar = GestInitialize ("gedit.cl");	if (! MyGrammar) ExitToShell ();	GestAssociate  (MyGrammar, "rectangle", add_rect);	GestAssociate  (MyGrammar, "oval", add_oval);	GestAssociate  (MyGrammar, "triangle", add_triangle);	GestAssociate  (MyGrammar, "move", move_objects);	GestAssociate  (MyGrammar, "copy", copy_objects);	GestAssociate  (MyGrammar, "delete", delete_object);	GestAssociate  (MyGrammar, "select", select_objects);	GestAssociate  (MyGrammar, "modify", modify_object);} #pragma segment MainBoolean IsAppWindow(window)	WindowPtr	window;{	short		windowKind;	if ( window == nil ) return false;	else { windowKind = ((WindowPeek) window)->windowKind;		return (windowKind = userKind);	}}#pragma segment Mainvoid DoMenuCommand(menuResult) long		menuResult;{	short		menuID;				/* the resource ID of the selected menu */	short		menuItem;			/* the item number of the selected menu */	short		itemHit;	Str255		daName;	menuID = HiWord(menuResult);		menuItem = LoWord(menuResult);		switch ( menuID ) {		case mApple:			switch ( menuItem ) {				case iAbout:	 itemHit = Alert (rAboutAlert, nil); break;				default:						GetItem(GetMHandle(mApple), menuItem, daName);					OpenDeskAcc(daName);					break;			}			break;		case mFile:			switch ( menuItem ) {			    case iOpen: break;				case iClose: break;				case iQuit: ExitToShell(); break;			} break;		case mEdit: SystemEdit(menuItem-1);	break;	}	HiliteMenu(0);			}#pragma segment Mainvoid DoEvent(event) EventRecord	*event;{	short		part;	WindowPtr	window;	Boolean		hit;	char		key;	switch ( event->what ) {		case mouseDown:			part = FindWindow(event->where, &window);			switch ( part ) {				case inMenuBar: DoMenuCommand(MenuSelect(event->where)); break;				case inSysWindow: SystemClick(event, window); break;				case inContent:					if ( window != FrontWindow() ) SelectWindow(window);					else DoContentClick (event, window);					break;				case inDrag: DragWindow(window, event->where, &qd.screenBits.bounds); break;				case inGrow: GrowWindow(window, event->where, &qd.screenBits.bounds);  break;				case inZoomIn:				case inZoomOut:					hit = TrackBox(window, event->where, part);					if ( hit ) { SetPort(window);	 EraseRect(&window->portRect);							ZoomWindow(window, part, true); InvalRect(&window->portRect);					}					break;			}			break;		case keyDown:		case autoKey:				key = event->message & charCodeMask;			if ( event->modifiers & cmdKey && event->what == keyDown ) 					DoMenuCommand (MenuKey (key));			break;		case activateEvt: break;		case updateEvt:  if ( IsAppWindow((WindowPtr) event->message) ) {						BeginUpdate((WindowPtr) event->message);						if ( ! EmptyRgn(((WindowPtr) event->message)->visRgn) )								DrawWindow ((WindowPtr) event->message);						EndUpdate((WindowPtr) event->message);						} break;	}}#pragma segment Mainvoid EventLoop(){	EventRecord	event;	do {		SystemTask();		if (GetNextEvent (everyEvent, &event))			DoEvent(&event);	} while (1);	}#pragma segment Mainmain(){	UnloadSeg((Ptr) _DataInit);		MaxApplZone();		Initialize();		UnloadSeg((Ptr) Initialize);	EventLoop();	}
