/*----------------------------------------------------------------------------------------------- 名前 App.c 機能 test of shell 作成 2002. Mogami 変更 -----------------------------------------------------------------------------------------------*/ #include #include #include "app.h" #include /*----------------------------------------------------------------------------------------------- 定数の定義 -----------------------------------------------------------------------------------------------*/ #define SLEEP 3L #define NIL_MOUSE_REGION 0L #define DRAG_THRESHOLD 5 /* drag可能領域の余裕 */ /* MBARリソースのID番号 */ #define MBAR_ID 128 /* MENUリソースのID番号 */ #define APPLE_MENU 128 #define FILE_MENU 129 #define EDIT_MENU 130 /* アップルメニューのアイテム番号 */ #define ITEM_ABOUT 1 /* ファイルメニューのアイテム番号 */ #define ITEM_OPEN 1 #define ITEM_SAVE 2 #define ITEM_LATEX 3 #define ITEM_PRINT 4 #define ITEM_QUIT 6 /* Editメニューのアイテム番号 */ #define ITEM_UNDO 1 #define ITEM_CUT 3 #define ITEM_COPY 4 #define ITEM_PASTE 5 #define ITEM_CLEAR 6 #define ITEM_SELECTALL 7 /*------------------------------グローバル変数-----------------------------------------*/ WindowPtr currWindow; int windowHeight = 800; int windowWidth = 550; /*----------------------------------------------------------------------------------------------- プロトタイプ宣言 -----------------------------------------------------------------------------------------------*/ static void InitToolBox(void); static Boolean HandleEvent(void); static Boolean HandleMouseDown(EventRecord *pEv); static void HandleUpdateEvent(EventRecord *pEv); static StringPtr Str255cpy(StringPtr pDest, StringPtr pSrc); static void SetupMenuBar(void); static void FailNull(void *p); static Boolean HandleMenuChoice(long pM); static Boolean HandleFileMenuChoice(short pItem); static void InstallAEHandlers(); OSErr load_expression_from_file(); /*----------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------*/ //volatile jmp_buf jmpEnv; void assert_func(char* file, int line){ extern char*ptr; scroll(); // print_str(ptr); scroll(); myPrintf("assertion failure line %d in %s.",line,file); longjmp(jmpEnv, 1); } void error_func(char *str, char* file, int line){ extern char*ptr; scroll(); // print_str(ptr); scroll(); myPrintf("error: %s occured in line %d of file %s\n",str, line, file); longjmp(jmpEnv, 1); } void exit2shell(){ longjmp(jmpEnv, 1); } //----------------------------------------------------------------------------- #include "ciph.h" Interpreter interpreter; int main(int argc, char* argv[]){ InitToolBox(); SetupMenuBar(); /* メニューバーを用意する */ InstallAEHandlers(); Rect aRect; SetRect(&aRect, LEFTMARGIN, 50, 50+windowWidth, 50+windowHeight); WindowPtr win = NewCWindow(0, &aRect, "\pcipher", TRUE, documentProc,(WindowPtr)-1, FALSE, 0); if(win==nil) ExitToShell(); SetPortWindowPort(win); currWindow=win; // SetFractEnable(true); TextFont(1); //20:Times, 3:Geneva TextSize(FONTSIZE); MoveTo(LEFTMARGIN, 20); initLines(); newLine(); interpreter = create_interpreter(); while(1) { /* try {} catch(eval_error){} */ if(setjmp(jmpEnv)==0){ //try HandleEvent(); } else { //catch scrollBy(FONTSIZE*2); newLine(); } } dispose_interpreter(interpreter); DisposeWindow(win); } /*-------------------イベントハンドラ----------------------------*/ void DoIdle(){ updateCaret(); } Boolean HandleMouseDown(EventRecord *pEv) { WindowPtr win; switch(FindWindow(pEv->where, &win)) { case inMenuBar: return HandleMenuChoice(MenuSelect(pEv->where)); case inDrag: /* ウィンドウのタイトルをさしていた場合 */ #ifdef PtoCstr // a little hack to find CodeWarrior Rect aDragRect = qd.screenBits.bounds; InsetRect(&aDragRect, DRAG_THRESHOLD, DRAG_THRESHOLD); DragWindow(win, pEv->where, &aDragRect); #else BitMap screenBits; GetQDGlobalsScreenBits(&screenBits); Rect limitRect = screenBits.bounds; DragWindow(win, pEv->where, &limitRect); #endif break; case inContent: Point pt = pEv->where; GlobalToLocal(&pt); HandleContentClick(pt); break; } return false; } Boolean HandleEditMenuChoice(short pItem) { switch(pItem) { case ITEM_UNDO: DoUndo(); return true; case ITEM_CUT: DoCut(); return true; case ITEM_COPY: DoCopy(); return true; case ITEM_PASTE: DoPaste(); return true; } return false; } Boolean HandleFileMenuChoice(short pItem) { switch(pItem) { case ITEM_OPEN: DoOpen(); return true; case ITEM_SAVE: DoSave(); return true; case ITEM_LATEX: DoLatex(); return true; case ITEM_PRINT: DoPrint(); return true; case ITEM_QUIT: ExitToShell(); default: return false; } } Boolean HandleMenuChoice(long pM) { Boolean aResult = false; short aItem = LoWord(pM); switch(HiWord(pM)){ case FILE_MENU: aResult = HandleFileMenuChoice(aItem); break; case EDIT_MENU: aResult = HandleEditMenuChoice(aItem); break; } HiliteMenu(0); return aResult; } void DoHighLevelEvent(EventRecord * eventPtr){// AppleEventの処理 OSErr er = AEProcessAppleEvent(eventPtr); if(er!=noErr) //うまく行かない場合は {} //ほんとうはメッセージなどをだしましょう! } //#include Boolean HandleKey(EventRecord *pEv) { if(pEv->modifiers & cmdKey) { return HandleMenuChoice(MenuKey(charCodeMask & pEv->message)); } int c = pEv->message & charCodeMask; if((pEv->modifiers & shiftKey) && (c==arrowLeft|c==arrowRight|c==arrowUp|c==arrowDown)) { HandleShifted(c); return true; } if((pEv->modifiers & (cmdKey|optionKey|controlKey)) == 0){ HandleTyping(c); return true; } return false; } Boolean HandleEvent(void) { EventRecord aEv; if(WaitNextEvent(everyEvent, &aEv, SLEEP, NIL_MOUSE_REGION)) { /* Boolean isTSMEvent = TSMEvent(&aEv); //まずTSMイベントの処理をし if (isTSMEvent ) { // SetTSMCursor(event.where); //カーソル設定も行う } else */{ switch(aEv.what) { case mouseDown: return HandleMouseDown(&aEv); case keyDown: case autoKey: return HandleKey(&aEv); case updateEvt: DoUpdate((WindowPtr) aEv.message); return false; case kHighLevelEvent: DoHighLevelEvent(&aEv); break; } } } DoIdle(); return FALSE; } //------------ int getKey0(EventRecord *pEv, int mode) { // returns exit flag if(pEv->modifiers & cmdKey){ HandleMenuChoice(MenuKey(charCodeMask & pEv->message)); return false; } int c = pEv->message & charCodeMask; if((pEv->modifiers & shiftKey) && (c==CR|c==arrowLeft|c==arrowRight|c==arrowUp|c==arrowDown)) { if(c==CR) return true; HandleShifted(c); return false; } if((pEv->modifiers & (cmdKey|optionKey|controlKey)) == 0){ if(c==CR && onlyCR) return true; HandleTyping(c); return false; } return false; } int getKey(int mode) { // returns exit flag EventRecord aEv; if(WaitNextEvent(everyEvent,&aEv,SLEEP,NIL_MOUSE_REGION)) { switch(aEv.what) { case mouseDown: HandleMouseDown(&aEv); return false; case keyDown: case autoKey: return getKey0(&aEv, mode); case updateEvt: DoUpdate((WindowPtr) aEv.message); return false; case kHighLevelEvent: DoHighLevelEvent(&aEv); break; } } DoIdle(); return false; } //---------------------- void SetupMenuBar(void){ Handle aMenuBar; /* MBARリソースをロードする */ aMenuBar = GetNewMBar(MBAR_ID); FailNull(aMenuBar); SetMenuBar(aMenuBar); DrawMenuBar(); } // ------------- apple events---------------- OSErr DoAERun(){ // DoNewCommand(); //新しいウインドウを用意する return noErr; } // aete Editorが作成したもとの、基本的に同じ pascal OSErr HandleAERun(const AppleEvent *theAppleEvent, AppleEvent *theReply, long theRefCon){ OSErr err; DescType typeCode; long actualSize; /* We check to see if we missed any parameter from the client */ if (AESizeOfAttribute(theAppleEvent, keyMissedKeywordAttr, &typeCode, &actualSize) != errAEDescNotFound) { err = errAEParamMissed; goto CleanUp; } err = DoAERun(); if (err) goto CleanUp; CleanUp: return err; } OSErr DoAEQuit( const AEDesc *ptrToSaving) { // Finish = true; //単に終了のフラグを立てるだけ return noErr; } // aete Editorが作成したもとの、基本的に同じ pascal OSErr HandleAEQuit(const AppleEvent *theAppleEvent, AppleEvent *theReply, long theRefCon){ OSErr err; DescType typeCode; long actualSize; AEDesc saving, *ptrToSaving; saving.dataHandle = nil; err = AEGetParamDesc(theAppleEvent,enumSaveOptions,typeWildCard,&saving); if (err == errAEDescNotFound) { ptrToSaving = nil; /* or you may put in your default here */ } else { if (err) goto CleanUp; ptrToSaving = &saving; }; /* We check to see if we missed any parameter from the client */ if (AESizeOfAttribute(theAppleEvent, keyMissedKeywordAttr, &typeCode, &actualSize) != errAEDescNotFound) { err = errAEParamMissed; goto CleanUp; }; err = DoAEQuit(ptrToSaving); if (err) goto CleanUp; CleanUp: AEDisposeDesc(&saving); return err; } OSErr DoAEOpen( const AEDesc *ptrToDirectParam){ OSErr er; FSSpec myFSS; AEDescList*docListPtr=0; long i, itemsInList; Size actualSize; AEKeyword keywd; DescType returnedType; er = AECoerceDesc(ptrToDirectParam, typeAEList, docListPtr); //AppleScriptの場合はオブジェクトスペックがやってくるので、そこからリストを得る //Finderでのドラッグ&ドロップならディスクリプタのリストが得られる er = AECountItems(docListPtr, &itemsInList); //項目数を求める for(i=1;i<=itemsInList;i++) { //各項目について er = AEGetNthPtr(docListPtr, i, typeFSS, &keywd, &returnedType, (Ptr)&myFSS, sizeof(FSSpec), &actualSize); //リストからFSSpec型のデータを取り出し // LoadFromFile(&myFSS); //そのファイルを開く } er = AEDisposeDesc(docListPtr); return er; } // Openイベントのハンドラルーチン // aete Editorが作成したもとの、基本的に同じ pascal OSErr HandleAEOpen(const AppleEvent *theAppleEvent, AppleEvent *theReply, long theRefCon){ OSErr err; DescType typeCode; long actualSize; AEDesc directParam; directParam.dataHandle = nil; err = AEGetParamDesc(theAppleEvent,keyDirectObject,typeWildCard,&directParam); if (err) goto CleanUp; /* We check to see if we missed any parameter from the client */ if (AESizeOfAttribute(theAppleEvent, keyMissedKeywordAttr, &typeCode, &actualSize) != errAEDescNotFound) { err = errAEParamMissed; goto CleanUp; }; err = DoAEOpen(&directParam); if (err) goto CleanUp; CleanUp: AEDisposeDesc(&directParam); return err; } OSErr DoAEPrint( const AEDesc *ptrToDirectParam){ OSErr er; FSSpec myFSS; AEDescList* docListPtr=0; long i, itemsInList; Size actualSize; AEKeyword keywd; DescType returnedType; WindowPtr targetWin; #ifdef PtoCstr // a little hack to find CodeWarrior THPrint tempPaper; // DocRecHandle docH; TPPrPort myPP; TPrStatus myStat; PrOpen(); //プリンタドライバを開く tempPaper = (THPrint)NewHandle(sizeof(TPrint)); //プリントレコードを確保 PrintDefault(tempPaper); //プリントレコードを初期化 PrStlDialog(tempPaper); //用紙設定のダイアログボックスを表示する if(PrJobDialog(tempPaper)) { //印刷ダイアログを表示し、印刷ボタンが押されれば er = AECoerceDesc(ptrToDirectParam, typeAEList, docListPtr); //印刷するドキュメントを得て er = AECountItems(docListPtr, &itemsInList); //数える for(i=1;i<=itemsInList;i++) { //各項目について er = AEGetNthPtr(docListPtr, i, typeFSS, &keywd, &returnedType, (Ptr)&myFSS, sizeof(FSSpec), &actualSize); //ファイル情報を得る // LoadFromFile(&myFSS); //ファイルを開く(開いているファイルがある場合は考慮していない) targetWin = FrontWindow(); //開いたファイルに対し // docH = getCurDocHandle(); //DocRecordを取得 // DocPrinting(docH); //実際の印刷処理を行う // DisposeAllObject(targetWin); //ウインドウの破棄 // DisposeDocWin(targetWin); } er = AEDisposeDesc(docListPtr); } PrClose(); //プリンタドライバをクローズ #endif return noErr; } void DoPrint(){ PrOpen(); THPrint paperInfoH = (THPrint)NewHandle(sizeof(TPrint)); PrintDefault(paperInfoH); if( PrJobDialog(paperInfoH)){ TPPrPort myPP = PrOpenDoc(paperInfoH, 0, 0); // print graph port PrOpenPage(myPP, 0); // start printing page SetPortWindowPort((GrafPort*)myPP); TextFont(0x4101); //1:appFont, 20:Times, 3:Geneva, 0x4101:細明朝, 16700:平成明朝 Redraw(); SetPortWindowPort(currWindow); PrClosePage(myPP); PrCloseDoc(myPP); if(((**paperInfoH).prJob.bJDocLoop == bSpoolLoop) && (PrError()==noErr)) { TPrStatus myStat; PrPicFile(paperInfoH, 0,0,0, &myStat); } } PrClose(); } pascal OSErr HandleAEPrint(const AppleEvent *theAppleEvent, AppleEvent *theReply, long theRefCon){ OSErr err; // aete Editorが作成したもとの、基本的に同じ DescType typeCode; long actualSize; AEDesc directParam; directParam.dataHandle = nil; err = AEGetParamDesc(theAppleEvent,keyDirectObject,typeWildCard,&directParam); if (err) goto CleanUp; /* We check to see if we missed any parameter from the client */ if (AESizeOfAttribute(theAppleEvent, keyMissedKeywordAttr, &typeCode, &actualSize) != errAEDescNotFound) { err = errAEParamMissed; goto CleanUp; }; err = DoAEPrint(&directParam); if (err) goto CleanUp; CleanUp: AEDisposeDesc(&directParam); return err; } void InstallAEHandlers(){ OSErr er; AEEventHandlerUPP procOAPP,procQUIT; AEEventHandlerUPP procODOC,procPDOC; //requiredイベントをハンドリングするハンドラの登録 //#ifdef PtoCstr // a little hack to find CodeWarrior procOAPP = NewAEEventHandlerProc(HandleAERun); procQUIT = NewAEEventHandlerProc(HandleAEQuit); procODOC = NewAEEventHandlerProc(HandleAEOpen); procPDOC = NewAEEventHandlerProc(HandleAEPrint); /*#else procOAPP = NewAEEventHandlerUPP(HandleAERun); procQUIT = NewAEEventHandlerUPP(HandleAEQuit); procODOC = NewAEEventHandlerUPP(HandleAEOpen); procPDOC = NewAEEventHandlerUPP(HandleAEPrint); #endif */ AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, procOAPP, 0, false); AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, procQUIT, 0, false); AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, procODOC, 0, false); AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, procPDOC, 0, false); } /* このファイルapp.cの一部は「Macintoshアプリケーションプログラミング」 (新居雅行 著、ディーアート刊、1995)に含まれる サンプルプログラム"TextDraw II"をもとにしています。 同書の上巻114ページに記載されている利用の条件に基づいて利用しています。*/ //----------------------------------------------------------------------- /* pがヌルポインター(あるいはヌルハンドル)なら強制終了する */ void FailNull(void *p) { if(NULL == p){ SysBeep(1); ExitToShell(); } } /* ToolBoxの初期化 */ void InitToolBox(void) { #ifdef PtoCstr // a little hack to find CodeWarrior MaxApplZone(); InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(0); FlushEvents(everyEvent,0); InitCursor(); #endif } /*----------------------------------------------------------------------------------------------- End Of This File -----------------------------------------------------------------------------------------------*/