📄 xaosapplication.cpp
字号:
// The Application class for XaoS on BeOS.// Copyright © 1997 Jens Kilian (jjk@acm.org)//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.#include <cstring>#include <stdio.h>#include <Application.h>#include <Archivable.h>#include <Bitmap.h>#include <File.h>#include <Message.h>#include <OS.h>#include <Point.h>#include <Rect.h>#include <NodeInfo.h>#include <Resources.h>#include <Roster.h>#include <Screen.h>#include <Entry.h>#include <setjmp.h>#include <Path.h>#include "XaoSApplication.h"#include "XaoSSplashView.h"#include "XaoSSplashWindow.h"#include "XaoSWindow.h"#include "setjmp.h"#include "version.h"#include "xerror.h"#include "xio.h"#include "xthread.h"// Application signature.static const char kSignature[] = "application/x-jjk-xaos";static char *loadarg=NULL;static char *filearg=NULL;extern jmp_buf translatorjmp;extern int translator;extern "C" {void be_exit_xaos(int i){ /* In translator mode we ought to cleanup everything and return error. but we can't. XaoS calls exit in translator mode only in x_fatalerror that is called in case of internal error and out of memory sitations only. Hope this is not major problem.*/ if (translator) longjmp(translatorjmp, 1); if(be_app) { be_app->PostMessage(B_QUIT_REQUESTED); ((XaoSApplication*)be_app)->mExitStatus=i; xth_uninit(); if(i==10) exit(10); exit_thread(i); } else exit(i);}}XaoSApplication::XaoSApplication(main_function_ptr pMainFunction): inherited(kSignature), mExitStatus(-1), mMainThreadID(B_ERROR), mpMainFunction(pMainFunction), mArgc(0), mppArgv(0){ // empty}static const char *xpfdesc="XaoS Position File";static const char *xafdesc="XaoS Animation File";/* Install information about xaf and xpf to mime database, set icons etc. this is done only in the case mime database don't contain their records*/void XaoSApplication::InstallMimeTypes(){ int installed1=0, installed2=0; BMimeType mime; size_t length; char name[B_MIME_TYPE_LENGTH]; // Get application info. app_info info; if (GetAppInfo(&info) != B_NO_ERROR) { x_error("Oh my god! I don't exist!\n"); return; } // Get the executable. BFile appFile(&(info.ref), O_RDONLY); if (appFile.InitCheck() != B_NO_ERROR) { x_error("Can't open myself! Help me!\n"); return; } // Get resources. BResources resources; if (resources.SetTo(&appFile) != B_NO_ERROR) { x_error("Someone throwed away my resources! Pleasase recompile me!\n"); return; } // Find the icon resource. void *pResource = resources.FindResource((type_code) 'MICN', (int32) 0, &length); if (!pResource) { x_error("Resources are wrong. I want MY resources back!\n"); return; } BBitmap xpfsmall(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_COLOR_8_BIT); xpfsmall.SetBits(pResource, xpfsmall.BitsLength(),0,B_COLOR_8_BIT); delete pResource; pResource = resources.FindResource('ICON', (int32) 0, &length); if (!pResource) { x_error("Resources are wrong. I want MY resources back!\n"); return; } BBitmap xpflarge(BRect(0, 0, B_LARGE_ICON - 1, B_LARGE_ICON - 1), B_COLOR_8_BIT); xpflarge.SetBits(pResource, xpflarge.BitsLength(),0,B_COLOR_8_BIT); delete pResource; pResource = resources.FindResource((type_code) 'MICN', (int32) 1, &length); if (!pResource) { x_error("Resources are wrong. I want MY resources back!\n"); return; } BBitmap xafsmall(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_COLOR_8_BIT); xafsmall.SetBits(pResource, xafsmall.BitsLength(),0,B_COLOR_8_BIT); delete pResource; pResource = resources.FindResource('ICON', (int32) 1, &length); if (!pResource) { x_error("Resources are wrong. I want MY resources back!\n"); return; } BBitmap xaflarge(BRect(0, 0, B_LARGE_ICON - 1, B_LARGE_ICON - 1), B_COLOR_8_BIT); xaflarge.SetBits(pResource, xpflarge.BitsLength(),0,B_COLOR_8_BIT); delete pResource; mime.SetType("image/x-xaos-position"); mime.GetShortDescription(name); if (!mime.IsInstalled() || strcmp(name,xpfdesc)) { BMessage ext; if (!mime.IsInstalled()) mime.Install(); printf("Installing XaoS Position File mime type\n"); installed1=1; ext.AddString("extensions","xpf"); mime.SetFileExtensions(&ext); mime.SetShortDescription(xpfdesc); mime.SetLongDescription("Position files used by XaoS realtime fractal zoomer"); mime.SetPreferredApp(kSignature); mime.SetIcon(&xpflarge, B_LARGE_ICON); mime.SetIcon(&xpfsmall, B_MINI_ICON); } mime.SetType("video/x-xaos-animation"); mime.GetShortDescription(name); if (!mime.IsInstalled() || strcmp(name,xafdesc)) { BMessage ext; if (!mime.IsInstalled()) mime.Install(); printf("Installing XaoS Animation File mime type\n"); installed2=1; ext.AddString("extensions","xaf"); mime.SetFileExtensions(&ext); mime.SetShortDescription("XaoS Animation File"); mime.SetLongDescription("Animation files used by XaoS realtime fractal zoomer"); mime.SetPreferredApp(kSignature); mime.SetIcon(&xaflarge, B_LARGE_ICON); mime.SetIcon(&xafsmall, B_MINI_ICON); } if (installed1 && installed2) x_message("To archieve a more confortable behaviour I've registered the new mime types:\n\nimage/x-xaos-position (XaoS Position File)\nvideo/x-xaos-animation (XaoS Animation File)\n\nLovely!\n"); else if (installed1) x_message("To archieve a more confortable behaviour I've registered the new mime type:\n\nimage/x-xaos-position (XaoS Position File)\n\n Thank you!"); else if (installed2) x_message("To archieve a more confortable behaviour I've registered the new mime type:\n\nvideo/x-xaos-animation (XaoS Animation File)\n\n Lovely!\n");}XaoSApplication::~XaoSApplication(void){ if (mppArgv) { // Delete command line arguments. for (int i = 0; i < mArgc; ++i) { delete [] mppArgv[i]; } delete [] mppArgv; mppArgv = 0; }}voidXaoSApplication::AboutRequested(void){ BBitmap *b = MakeSplashBitmap(); if (b!=NULL) { XaoSSplashView *pSplashView = new XaoSSplashView(MakeSplashBitmap()); (new XaoSSplashWindow(pSplashView))->Go(); }}voidXaoSApplication::ArgvReceived(int32 argc, char **ppArgv){ if (mppArgv) { // This shouldn't happen (as long as XaoS is not made // a single-launch application, which won't happen soon :-) } else { // Copy the command line arguments. mArgc = (int)argc; char **p = mppArgv = new char*[mArgc+3]; for (int i = 0; i < mArgc; ++i) { *p++ = strcpy(new char [strlen(*ppArgv)+1], *ppArgv); ++ppArgv; } *p = 0; }}boolXaoSApplication::QuitRequested(void){ // Cleanly shutting down a BeOS application is hard work. // This function may be called multiple times before it finally // returns 'true'. In an extreme case, the following // interactions may occur: // // User Application Window XaoS thread // | B_QUIT_REQ. | | | // | ##########> | QuitReq. | | // | | =========> | Quit cmd. | // | | false | ############> | // | | <--------- | | // | | | AllowQuit | // | | | <=========== | // | | | B_QUIT_REQ. | // | | B_QUIT_REQ | <############ | // | | <######### | | // | | QuitReq. | (thread ends) // | | =========> | . // | | true | . // | | <--------- | . // | | Quit | . // | | =========> | . // | | . . // | (wait_for_thread) . . // | | < - - - - - - - - - - - - - - . // | | . . // // #######> BMessage or other asynchronous event // =======> function call // -------> function return value const bool mayQuit = inherited::QuitRequested(); if (mayQuit && mMainThreadID >= B_NO_ERROR) { // Wait for the main thread to finish. int32 dummy; (void)wait_for_thread(mMainThreadID, &dummy); mMainThreadID = B_ERROR; } return mayQuit;}// This is a small hack to add -loadpos or -play option in case files are specifiedvoidXaoSApplication::RefsReceived(BMessage *message){ const char *filename; char type[B_MIME_TYPE_LENGTH]; int l; BPath path; entry_ref refs; int animation = 0; int one=0; int c; xio_file sfile=NULL; if (message->FindRef("refs", 0, &refs) != B_OK) return; if (message->FindRef("refs", 1, &refs) != B_OK) one=1; /* In case one file is received just load it. For multiple files construct an "slide show" animation */ for(c=0;message->FindRef("refs",c,&refs)==B_OK;c++) { BEntry e(&refs,true); e.GetPath(&path); filename=path.Path(); l=strlen(filename); BNode node(&e); BNodeInfo ni(&node); if (ni.GetType(type)!=B_OK) type[0]=0; if (!strcmp(type, "image/x-xaos-position")) animation = 0; else if (!strcmp(type, "video/x-xaos-animation")) animation = 1; else if (l>4 && !strcmp(type+l-4, ".xpf")) animation = 0; else if (l>4 && !strcmp(type+l-4, ".xaf")) animation = 1; else x_fatalerror("%s:Unknown file\n",filename), exit(1); if (one) { filearg=strdup(filename); if (!animation) loadarg=strdup("-loadpos"); else loadarg=strdup("-play"); } else { if (!sfile) sfile=xio_strwopen(); xio_puts("(load \"",sfile); xio_puts((const char *)filename,sfile); xio_puts("\")\n(usleep 500000)(wait)(usleep 500000)\n",sfile); } } if (sfile) { loadarg=strdup("-playstr"); xio_close(sfile); filearg=xio_getstring(sfile); }}voidXaoSApplication::ReadyToRun(void){ InstallMimeTypes(); if (!mppArgv) { // User didn't pass any command line options. // ### TO DO: LET THE USER SELECT MODE, SIZE ETC. mppArgv = new char*[mArgc+3]; mppArgv[1] = 0; mArgc = 1; } else delete mppArgv[0]; if (loadarg) { mppArgv[mArgc] = loadarg; mppArgv[mArgc+1] = filearg; mArgc+=2; } /* Get the path to file executable. XaoS use it to locate tutorials and other files */ app_info info; if (GetAppInfo(&info) != B_NO_ERROR) { x_error("Oh my god! I don't exist!\n"); } BEntry e(&info.ref,true); BPath path; e.GetPath(&path); const char *filename=path.Path(); mppArgv[0] = strdup (filename); // Spawn and start the thread running the real main program. if ((mMainThreadID = spawn_thread(MainThread, "XaoS main program", B_NORMAL_PRIORITY, this)) < B_NO_ERROR || resume_thread(mMainThreadID) < B_NO_ERROR) { PostMessage(B_QUIT_REQUESTED); }}longXaoSApplication::MainThread(void *data){ XaoSApplication *pApp = (XaoSApplication *)data; pApp->mExitStatus = (pApp->mpMainFunction)(pApp->mArgc, pApp->mppArgv); printf("%i\n",pApp->mExitStatus); return 0;}BBitmap *XaoSApplication::MakeSplashBitmap(void){ // Get application info. app_info info; if (GetAppInfo(&info) != B_NO_ERROR) { x_error("No application - no about boxes. Sorry!\n"); return 0; } // Get the executable. BFile appFile(&(info.ref), O_RDONLY); if (appFile.InitCheck() != B_NO_ERROR) { x_error("No application - no about boxes. Sorry!\n"); return 0; } // Get resources. BResources resources; if (resources.SetTo(&appFile) != B_NO_ERROR) { x_error("No resources - no about boxes. Sorry!\n"); return 0; } // Find the splash screen resource. size_t length; void *pResource = resources.FindResource('XaSp', 1, &length); if (!pResource) { x_error("Resources are wrong and the lovely about dialog is lost. Sorry!\n"); return 0; } // Unflatten the resource. BMessage archived; status_t status = archived.Unflatten((const char *)pResource); delete pResource; if (status != B_NO_ERROR) { return 0; } // Instantiate & return a bitmap. BArchivable *pResult = instantiate_object(&archived); if (!pResult) { return 0; } BBitmap *pSplashBitmap = dynamic_cast<BBitmap *>(pResult); if (!pSplashBitmap) { delete pResult; } return pSplashBitmap;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -