/* Copyright 1997 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /***************************************************/ /* File : Main.c */ /* */ /* Purpose: To run. */ /* */ /* Author : A.D.Hodgkinson */ /* */ /* History: 12-Nov-96: Created. */ /***************************************************/ #include "setjmp.h" #include "signal.h" #include #include #include #include #include #include "swis.h" #include "kernel.h" #include "flex.h" #include "HTMLLib.h" /* HTML library API, Which will include html2_ext.h, tags.h and struct.h */ #include "URI.h" /* URI handler API, in URILib:h */ #include "wimp.h" #include "wimplib.h" #include "event.h" #include "toolbox.h" #include "quit.h" #include "proginfo.h" #include "window.h" #include "menu.h" #include "saveas.h" #include "printdbox.h" #include "gadgets.h" #include "svcprint.h" #include "Global.h" #include "FromROSLib.h" #include "TBEvents.h" #include "Utils.h" #include "Browser.h" #include "Find.h" #include "FontManage.h" #include "Handlers.h" #include "Menus.h" #include "MiscDefs.h" #include "Mouse.h" #include "OpenURL.h" #include "Printing.h" #include "Save.h" #include "URLutils.h" #include "Windows.h" /* Conditional includes */ #ifdef TRACE #include "Trace.h" #endif /* The following three are defined or undefined locally */ #undef INCLUDE_HEAPGRAPH #undef INCLUDE_HIERPROF #undef INCLUDE_MEMCHECK #ifdef INCLUDE_HEAPGRAPH #include "HeapGraph.HeapGraph.h" #endif #ifdef INCLUDE_HIERPROF #define HierProf_PROFILE #include "HierProf:HierProf.h" #endif #ifdef INCLUDE_MEMCHECK #include "MemCheck:MemCheck.h" #endif /* Finally, Main.h itself */ #include "Main.h" /* Static function prototypes */ static void initialise_app (void); static _kernel_oserror * open_choices_file (void); static void load_choices (void); static void catch_errors (int signum); static void termination (void); /* Make sure the stack starts at a reasonable size to prevent frequent */ /* stack extensions - this is a directive to the C run time system and */ /* can be removed on other systems which have no equivalent. */ int __root_stack_size = 16384; // /*************************************************/ // /* attach_event_handlers() */ // /* */ // /* Called when an object is autocreated by the */ // /* toolbox (see initialise_app()). Used to get */ // /* the ObjectID of things without needing a */ // /* specifically generated event to deliver it */ // /*************************************************/ // // int attach_event_handlers(int eventcode,ToolboxEvent *event,IdBlock *idb,void *handle) // { // ObjectId temp; // // ToolboxObjectAutoCreatedEvent *c=(ToolboxObjectAutoCreatedEvent *) event; // // /* We extract the relevant object Id by comparing the template name */ // /* given in the event structure with something we know about and */ // /* proceeding as is relevant. */ // // if (!strcmp(c->template_name,"Browser")) // { // main_window_id = idb->self_id; // show_centred(main_window_id); // } // else if (!strcmp(c->template_name,"ButtonBar")) // { // temp = idb->self_id; // { // BBox b; // b.xmin=0; // b.ymin=-144; // b.xmax=16384; // b.ymax=0; // set_corrected_extent(0,temp,&b); // } // } // // return 1; // } /*************************************************/ /* initialise_app() */ /* */ /* Initialises application as a Toolbox task. */ /*************************************************/ static void initialise_app(void) { int module_version; show_error(event_initialise(&idb)); // show_error(event_register_toolbox_handler(-1, // Toolbox_ObjectAutoCreated, // attach_event_handlers, // NULL)); /* Register fundamental handlers and initialise as a Toolbox task */ show_error(event_register_message_handler(Wimp_MQuit, handle_messages, NULL)); /* Check the Wimp version; for window managers of 3.8 and above, */ /* declare a minimum version of 3.80 so borderless windows can */ /* still have tools. Otherwise, only ask for 3.1. */ _swix(Wimp_ReadSysInfo, _IN(0) | _OUT(0), 7, &module_version); if (module_version >= 387) nested_wimp = 1; else nested_wimp = 0; show_error(toolbox_initialise(0, nested_wimp ? WIMPMINH : WIMPMINL, messages_list, event_code_list, TASKDIR, &meb, &idb, &wimp_version, &task_handle, (void *) &sprite_block)); show_error(open_choices_file()); show_error(event_register_toolbox_handler(-1, Toolbox_Error, report_toolbox_error, NULL)); /* If the system variable 'Browse$IssueDesktopCommand' is set to 'yes', */ /* then the AcornURI and/or TaskModule modules were started in !Run and */ /* we must issue a *Desktop command to start their task components. */ { char combuf[96]; sprintf(combuf, "If \"\" = \"yes\" Then WimpTask Desktop\r\n"); _swix(OS_CLI, /* Don't want to hear about any errors */ _IN(0), combuf); } /* Quit menu items are set to give the Quit_Quit event type, as well as */ /* this event possibly being delivered by the Toolbox from elsewhere. */ show_error(event_register_toolbox_handler(-1, Quit_Quit, handle_quit, NULL)); /* Called before the application's Info box is shown */ show_error(event_register_toolbox_handler(-1, ProgInfo_AboutToBeShown, handle_show_info, NULL)); /* Called when the icon bar is clicked upon with Select */ show_error(event_register_toolbox_handler(-1, EOpenNewWindow, windows_new_browser, NULL)); /* Called when the Open URL dialogue is to be shown */ show_error(event_register_toolbox_handler(-1, EOpenURLWindow, openurl_to_be_shown, NULL)); /* Called when the Find dialogue is to be shown */ show_error(event_register_toolbox_handler(-1, EOpenFindWindow, find_to_be_shown, NULL)); /* Called when the Print dialogue is to be shown */ show_error(event_register_toolbox_handler(-1, PrintDbox_AboutToBeShown, print_to_be_shown, NULL)); /* Called when the user clicks on a Print dialogue's Print button */ show_error(event_register_toolbox_handler(-1, PrintDbox_Print, print_initiate, NULL)); /* Called when the print dialogue is cancelled */ show_error(event_register_toolbox_handler(-1, PrintDbox_DialogueCompleted, print_restore, NULL)); /* Called when radios are used in the Print dialogue which */ /* may alter the state of the Reformat option (i.e. enable */ /* or disable / ungrey it or grey it out). */ show_error(event_register_toolbox_handler(-1, EEnableReformat, print_check_contents, NULL)); /* Called when the Utils submenu is to be opened from the */ /* main menu in a browser window. */ show_error(event_register_toolbox_handler(-1, EShowUtilsMenu, menus_show_utils, NULL)); /* Called when the Choices submenu is to be opened */ /* from the icon bar menu */ show_error(event_register_toolbox_handler(-1, EShowChoicesMenu, menus_show_choices, NULL)); /* Called when the File submenu is to be opened from */ /* a browser window's main menu */ show_error(event_register_toolbox_handler(-1, EShowFileMenu, menus_show_file, NULL)); /* Called whenever a menu item is selected */ show_error(event_register_toolbox_handler(-1, Menu_Selection, menus_item_selected, NULL)); /* General key press handler */ show_error(event_register_wimp_handler(-1, Wimp_EKeyPressed, handle_keys, NULL)); /* Menu handler for forms etc. */ show_error(event_register_wimp_handler(-1, Wimp_EMenuSelection, handle_menus, NULL)); /* LoseCaret event handler for grabbing the caret back, etc. */ show_error(event_register_wimp_handler(-1, Wimp_ELoseCaret, handle_lose_caret, NULL)); /* Pointer checking */ show_error(event_register_wimp_handler(-1, Wimp_EPointerEnteringWindow, browser_pointer_entering, NULL)); show_error(event_register_wimp_handler(-1, Wimp_EPointerLeavingWindow, browser_pointer_leaving, NULL)); /* Related to that, end of drag handling */ show_error(event_register_wimp_handler(-1, Wimp_EUserDrag, (WimpEventHandler *) handle_drags, NULL)); /* General Wimp message handling */ show_error(event_register_message_handler(Wimp_MModeChange, handle_messages, NULL)); show_error(event_register_message_handler(Wimp_MDataLoad, handle_messages, NULL)); show_error(event_register_message_handler(Wimp_MDataOpen, handle_messages, NULL)); show_error(event_register_message_handler(Wimp_MMenusDeleted, handle_messages, NULL)); /* URI handler message handling */ show_error(event_register_message_handler(URI_MProcess, handle_messages, NULL)); show_error(event_register_message_handler(URI_MReturnResult, handle_messages, NULL)); /* AppControl message handling */ show_error(event_register_message_handler(Wimp_MAppControl, handle_messages, NULL)); /* Printing related message handlers */ show_error(event_register_message_handler(Browser_Message_PrintError, handle_messages, NULL)); show_error(event_register_message_handler(Browser_Message_PrintSave, handle_messages, NULL)); show_error(event_register_message_handler(Browser_Message_PrintTypeOdd, handle_messages, NULL)); show_error(event_register_message_handler(Wimp_MDataSaveAck, handle_messages, NULL)); show_error(event_register_wimp_handler(-1, Wimp_EUserMessageAcknowledge, handle_ack, NULL)); /* Debug build event handlers */ #ifdef TRACE show_error(event_register_toolbox_handler(-1, Trace_TokenDumpByLine, trace_dump_tokens_by_line, NULL)); show_error(event_register_toolbox_handler(-1, Trace_TokenDumpByStream, trace_dump_tokens_by_stream, NULL)); #endif /* Event handlers for menu items that relate to toolbar buttons. */ /* This list needs to be kept in sync with the specific list in */ /* Windows.c, which allows buttons in specific windows to use */ /* the same event codes. */ show_error(event_register_toolbox_handler(-1, EButtonHome, handle_home, NULL)); show_error(event_register_toolbox_handler(-1, EButtonBack, handle_back, NULL)); show_error(event_register_toolbox_handler(-1, EButtonForward, handle_forwards, NULL)); show_error(event_register_toolbox_handler(-1, EButtonReload, handle_reload, NULL)); show_error(event_register_toolbox_handler(-1, EButtonStop, handle_stop, NULL)); show_error(event_register_toolbox_handler(-1, EButtonViewHot, handle_view_hotlist, NULL)); show_error(event_register_toolbox_handler(-1, EButtonAddHot, handle_add_hotlist, NULL)); show_error(event_register_toolbox_handler(-1, EButtonViewRes, handle_view_resources, NULL)); show_error(event_register_toolbox_handler(-1, EButtonLoadImg, handle_load_images, NULL)); show_error(event_register_toolbox_handler(-1, EButtonViewSrc, handle_view_source, NULL)); show_error(event_register_toolbox_handler(-1, EButtonGoTo, handle_go_to, NULL)); show_error(event_register_toolbox_handler(-1, EButtonGo, handle_go, NULL)); show_error(event_register_toolbox_handler(-1, EButtonCancel, handle_cancel, NULL)); show_error(event_register_toolbox_handler(-1, EBiStateKeyed, handle_bistate, NULL)); show_error(event_register_toolbox_handler(-1, ETriStateKeyed, handle_tristate, NULL)); /* Miscellaneous event handlers for keyboard control of some functions */ show_error(event_register_toolbox_handler(-1, EClearURL, handle_clear_url, NULL)); show_error(event_register_toolbox_handler(-1, EShowHistoryMenu, handle_show_history_menu, NULL)); /* Event handlers for saving */ show_error(event_register_toolbox_handler(-1, SaveAs_AboutToBeShown, save_fill_in, NULL)); show_error(event_register_toolbox_handler(-1, SaveAs_SaveToFile, save_save_to_file, NULL)); show_error(event_register_toolbox_handler(-1, SaveAs_FillBuffer, save_fill_buffer, NULL)); show_error(event_register_toolbox_handler(-1, SaveAs_SaveCompleted, save_save_completed, NULL)); show_error(event_register_toolbox_handler(-1, SaveAs_DialogueCompleted, save_dialogue_completed, NULL)); /* Wake up flex */ strncpy(program_name, lookup_token("_TaskName", 1, 0), sizeof(program_name)); program_name[sizeof(program_name) - 1] = 0; flex_init(program_name, NULL); flex_set_budge(1); /* Initialise the HTML library. This is to set up some initial */ /* data which can't be initialised in headers due to ROM build */ /* considerations. */ HtmlInit(); /* Similarly, initialise ImageLib */ ImageLib_Init(); /* Initialise FromROSLib routines */ wimpt_read(); /* Initialise Utils routines */ read_os_to_points(); /* Find the total number of animation frames for the status bar */ animation_frames = 0; { char v[10]; /* SpriteOp 40 is Read Info; it's just something that will give */ /* an error if the sprite doesn't exist. */ do { sprintf(v, "a%d\0", animation_frames ++); } while ( animation_frames < Limits_Misc_AnimFrames && !(_swix(OS_SpriteOp, _INR(0,2), 296, sprite_block, v)) ); /* animation_frames is incremented for every sprite looked at, */ /* including the last one, which must not be found. So need to */ /* subtract 1 now, to make it equal the number of frames. */ animation_frames --; } /* Similarly, find the number of bullets available */ bullets = 0; { char v[10]; do { sprintf(v,"b%d\0",bullets++); } while ( bullets < Limits_Misc_Bullets && !(_swix(OS_SpriteOp, _INR(0,2), 296, sprite_block, v)) ); bullets --; } /* Is the URI handler available? */ { int version; if (uri_version(0, &version)) uri_module_present = 0; else if (version >= 5) uri_module_present = 1; } /* Try and set the user agent string for HTTP fetches. */ show_error(utils_set_http_agent()); /* Find out window tool sizes */ ChkError(windows_initialise_tool_sizes()); } /*************************************************/ /* open_choices_file() */ /* */ /* Asks MessageTrans to open the Choices file. */ /* Looks through a system variable for the path */ /* to find the file in before going to the */ /* default of 'Choices' inside the application */ /* directory. */ /*************************************************/ static _kernel_oserror * open_choices_file(void) { char path[Limits_OS_Pathname]; _kernel_oserror * e; memset(path, 0, sizeof(path)); /* Equivalent to getenv(), but the RISC OS implementation evaluates */ /* the system variable as an expression which we don't want; hence */ /* the direct use of the SWI. */ if ( _swix(OS_ReadVarVal, _INR(0,4), "Browse$ChoicesFile", /* Variable name */ path, /* Buffer */ sizeof(path), /* Size of buffer */ 0, /* Name pointer (0 for 1st call) */ 4) /* Variable type (4 = literal string) */ ) { /* If there's an error, assume it was because the variable doesn't exist */ strcat(path, TASKDIR); strcat(path, ".Choices"); } /* Claim RMA for the control block and pathname */ e = _swix(OS_Module, _IN(0) | _IN(3) | _OUT(2), 6, sizeof(MessagesFD) + strlen(path) + 1, &chb); if (e) return e; #ifdef INCLUDE_MEMCHECK MemCheck_RegisterMiscBlock((void *) chb, sizeof(MessagesFD) + strlen(path) + 1); #endif strcpy((char *) ((int) chb + sizeof(MessagesFD)), path); /* Open the file */ return _swix(MessageTrans_OpenFile, _INR(0,2), chb, /* Pointer to control block */ (int) chb + sizeof(MessagesFD), /* Filename */ 0); /* 0 to buffer data in RMA */ } /*************************************************/ /* close_choices_file() */ /* */ /* Closes the Choices messages file and releases */ /* RMA claimed for it. */ /*************************************************/ static void close_choices_file(void) { /* If the file won't close for some reason, */ /* MessageTrans may still want to access it */ /* - so safest *not* to release the RMA */ /* holding the control block and filename. */ if ( _swix(MessageTrans_CloseFile, _IN(0), chb) ) return; /* Release the claimed RMA space holding the */ /* control block and messages file name. */ _swix(OS_Module, _IN(0) | _IN(2), 7, chb); } /*************************************************/ /* load_choices() */ /* */ /* Reads in the choices from the Messages file, */ /* filling in the global_choices structure, */ /* 'choices' (see Global.c and Global.h). */ /*************************************************/ static void load_choices(void) { /* Set the default window size and position */ choices.width = atoi(lookup_choice("DefWidth:1024",0,0)); choices.height = atoi(lookup_choice("DefHeight:1280",0,0)); choices.overridex = atoi(lookup_choice("OverrideX:0",0,0)); choices.overridey = atoi(lookup_choice("OverrideY:0",0,0)); /* If compiling for a multiuser environment, these will */ /* exist and need setting to null values. */ #ifndef SINGLE_USER choices.username[0] = 0; choices.password[0] = 0; #endif /* Set the various default colours */ choices.col_back = (unsigned int) strtoul(lookup_choice("BackColour:0xdddddd00",0,0),NULL,16); choices.col_text = (unsigned int) strtoul(lookup_choice("TextColour:0x00000000",0,0),NULL,16); choices.col_link = (unsigned int) strtoul(lookup_choice("LinkColour:0xff000000",0,0),NULL,16); choices.col_used = (unsigned int) strtoul(lookup_choice("UsedColour:0xbb008800",0,0),NULL,16); choices.col_foll = (unsigned int) strtoul(lookup_choice("FollColour:0x0000ff00",0,0),NULL,16); choices.col_sele = (unsigned int) strtoul(lookup_choice("SeleColour:0x00bb0000",0,0),NULL,16); /* Default fonts */ choices.fontsize = atoi(lookup_choice("FontSize:12",0,0)); if (choices.fontsize < 6) choices.fontsize = 6; if (choices.fontsize > 24) choices.fontsize = 24; choices.fontsize *= 16; /* None user-configurable options from the Messages file */ fixed.poll_delay = atoi(lookup_token("AnimSpeed:4", 0,0)); fixed.minimum_convergence = atoi(lookup_token("MinConvergence:480",0,0)); fixed.show_dstat_for = atoi(lookup_token("ShowDStatFor:300", 0,0)); fixed.quantise = atoi(lookup_token("Quantise:5", 0,0)); fixed.dontgrey = atoi(lookup_token("DontGrey:0", 0,0)); fixed.ptrlnkactvx = atoi(lookup_token("PtrLnkActvX:5",0,0)); fixed.ptrlnkactvy = atoi(lookup_token("PtrLnkActvY:2",0,0)); fixed.ptrmapactvx = atoi(lookup_token("PtrMapActvX:8",0,0)); fixed.ptrmapactvy = atoi(lookup_token("PtrMapActvY:8",0,0)); fixed.backoffat = atoi(lookup_token("BackOffAt:128",0,0)); if (!strcmp(lookup_token("SwapBars:no" ,0,0),"yes")) fixed.swapbars = 1; if (!strcmp(lookup_token("DBoxAnims:no" ,0,0),"yes")) fixed.dboxanims = 1; if (!strcmp(lookup_token("AppendStatus:no" ,0,0),"yes")) fixed.appendstatus = 1; if (!strcmp(lookup_token("UseBrackets:yes" ,0,0),"yes")) fixed.usebrackets = 1; if (!strcmp(lookup_token("AppendURLs:no" ,0,0),"yes")) fixed.appendurls = 1; if (!strcmp(lookup_token("KeepCaret:no" ,0,0),"yes")) fixed.keepcaret = 1; if (!strcmp(lookup_token("ClaimHelp:no" ,0,0),"yes")) fixed.claimhelp = 1; if (!strcmp(lookup_token("StopWebServ:no" ,0,0),"yes")) fixed.stopwebserv = 1; if (!strcmp(lookup_token("BackWindow:no" ,0,0),"yes")) fixed.backwindow = 1; if (!strcmp(lookup_token("IgnoreAdjust:no" ,0,0),"yes")) fixed.ignoreadjust = 1; if (!strcmp(lookup_token("LockToLine:no" ,0,0),"yes")) fixed.locktoline = 1; /* Maximum global history size in K, maximum */ /* view history size in entires, and maximum */ /* number of images to simultaneously fetch. */ choices.maxghistory = atoi(lookup_choice("GHistSize:8" ,0,0)); choices.maxvhistory = atoi(lookup_choice("VhistSize:50",0,0)); choices.maximages = atoi(lookup_choice("MaxImages:5" ,0,0)); if (choices.maxghistory < 1) choices.maxghistory = 1; if (choices.maxvhistory < 4) choices.maxvhistory = 4; if (choices.maximages <= 0) choices.maximages = 1; /* Page layout */ choices.leftmargin = atoi(lookup_choice("LeftMargin:1600" ,0,0)); choices.rightmargin = atoi(lookup_choice("RightMargin:6400" ,0,0)); choices.quotemargin = atoi(lookup_choice("QuoteMargin:19200",0,0)); choices.leading = atoi(lookup_choice("Leading:4" ,0,0)); choices.leftindent = atoi(lookup_choice("LeftIndent:12800" ,0,0)); choices.minfrmheight = atoi(lookup_choice("MinFrmHeight:48" ,0,0)); choices.minfrmwidth = atoi(lookup_choice("MinFrmWidth:48" ,0,0)); /* Reformatter options */ if (!strcmp(lookup_choice("RefoWait:no",0,0),"yes")) choices.refowait = 1; if (!strcmp(lookup_choice("RefoHang:no",0,0),"yes")) choices.refohang = 1; choices.refotime = atoi(lookup_choice("RefoTime:500",0,0)); if (choices.refotime < 25) choices.refotime = 25; if (choices.refotime > 2000) choices.refotime = 2000; /* Miscellaneous options */ if (!strcmp(lookup_choice("BrickWall:no" ,0,0),"yes")) choices.brickwall = 1; if (!strcmp(lookup_choice("SystemFont:no" ,0,0),"yes")) choices.systemfont = 1; if (!strcmp(lookup_choice("DelayImage:yes" ,0,0),"yes")) choices.delayimages = 1; if (!strcmp(lookup_choice("DisplayBgs:yes" ,0,0),"yes")) choices.displaybgs = 1; if (!strcmp(lookup_choice("UnderlineLks:yes",0,0),"yes")) choices.underlinelks = 1; if (!strcmp(lookup_choice("OverrideCols:no" ,0,0),"yes")) choices.overridecols = 1; if (!strcmp(lookup_choice("ShowURLs:no" ,0,0),"yes")) choices.show_urls = 1; if (!strcmp(lookup_choice("FixedPtr:yes" ,0,0),"yes")) choices.fixedptr = 1; if (!strcmp(lookup_choice("HighlightLks:no" ,0,0),"yes")) choices.highlightlks = 1; if (!strcmp(lookup_choice("KeyboardCtl:no" ,0,0),"yes")) choices.keyboardctl = 1; if (!strcmp(lookup_choice("ClearFirst:yes" ,0,0),"yes")) choices.clearfirst = 1; if (!strcmp(lookup_choice("KeepHighlight:no",0,0),"yes")) choices.keephighlight = 1; if (!strcmp(lookup_choice("UseProxy:no" ,0,0),"yes")) choices.use_proxy = 1; if (!strcmp(lookup_choice("FullScreen:no" ,0,0),"yes")) choices.full_screen = 1; if (!strcmp(lookup_choice("HScroll:no" ,0,0),"no")) choices.h_scroll = 0; else if (!strcmp(lookup_choice("HScroll:no" ,0,0),"yes")) choices.h_scroll = 2; else choices.h_scroll = 1; /* Auto */ if (!strcmp(lookup_choice("VScroll:yes",0,0),"no")) choices.v_scroll = 0; else if (!strcmp(lookup_choice("VScroll:yes",0,0),"yes")) choices.v_scroll = 2; else choices.v_scroll = 1; /* Auto */ /* Set toolbar options */ if (!strcmp(lookup_choice("DefURLbar:yes" ,0,0),"yes")) choices.url_bar = 1; if (!strcmp(lookup_choice("DefButtonBar:yes",0,0),"yes")) choices.button_bar = 1; if (!strcmp(lookup_choice("DefStatusBar:yes",0,0),"yes")) choices.status_bar = 1; if (!strcmp(lookup_choice("MoveGadgets" ,0,0),"0")) choices.move_gadgets = 0; if (!strcmp(lookup_choice("MoveGadgets" ,0,0),"1")) choices.move_gadgets = 1; if (!strcmp(lookup_choice("MoveGadgets:2",0,0),"2")) choices.move_gadgets = 2; if (!strcmp(lookup_choice("AnimDrift:no", 0,0),"yes")) choices.anim_drift = 1; if (!strcmp(lookup_choice("AnimDrift:no", 0,0),"always")) choices.anim_drift = 2; if (!strcmp(lookup_choice("SolidResize:yes",0,0),"yes")) choices.solid_resize = 1; if (!strcmp(lookup_choice("SolidResize:yes",0,0),"always")) choices.solid_resize = 2; #ifdef TRACE /* This list is somewhat out of date...! Still, it served */ /* its purpose in the early days of the above routines, */ /* and gives a useful overview for the Rout debug option */ /* during startup. */ if (tl & (1u<<5)) { Printf("\nWidth: %d\n" "Height: %d\n", choices.width, choices.height); Printf("\nBack colour: %p\n" "Text colour: %p\n" "Link colour: %p\n" "Used colour: %p\n", (void *) choices.col_back, (void *) choices.col_text, (void *) choices.col_link, (void *) choices.col_used); Printf("\nSystem font: %d\n" "Delay images: %d\n" "Display backgrounds: %d\n" "Fixed pointer: %d\n" "Underline links: %d\n" "Override colours: %d\n" "URL bar: %d\n" "Button bar: %d\n" "Status bar: %d\n" "Move gadgets: %d\n" "Use a proxy: %d\n\n", choices.systemfont, choices.delayimages, choices.displaybgs, choices.fixedptr, choices.underlinelks, choices.overridecols, choices.url_bar, choices.button_bar, choices.status_bar, choices.move_gadgets, choices.use_proxy); } #endif /* Wake up the font library */ fm_init(choices.systemfont, choices.fontsize); show_error(fm_define_default_typefaces()); fm_claim_basic_typefaces(choices.fontsize); /* Install any general handlers that might be needed as a */ /* result of the choices just loaded. */ show_error(event_register_wimp_handler(-1, Wimp_ELoseCaret, handle_lose_caret, NULL)); if (fixed.claimhelp) { register_null_claimant(Wimp_ENull, handle_send_helpreq, NULL); show_error(event_register_message_handler(Wimp_MHelpReply, handle_messages, NULL)); } } /*************************************************/ /* catch_errors() */ /* */ /* Catch OS errors and report them with the */ /* opportunity to continue or quit. */ /* */ /* Parameters: The signal number (ignored). */ /*************************************************/ static void catch_errors(int signum) { _kernel_oserror * e = _kernel_last_oserror(); print_abort_print(); if (e) show_error_cont(e); exit(EXIT_FAILURE); } /*************************************************/ /* termination() */ /* */ /* Called by registration through the atexit */ /* function. Shuts down core functions prior to */ /* the browser exitting (e.g. the Font Manager */ /* can get very tetchy about having font handles */ /* left claimed, so must release them). */ /*************************************************/ void termination(void) { #ifdef TRACE if (tl & (1u<<5)) Printf("termination() called\n"); #endif if (taskmodule_ds_registered) { /* Not interested in any errors, if it fails we can't really */ /* do anything about it at this stage. */ _swix(TaskModule_DeRegisterService, _INR(0,2), 0, 0, task_handle); } close_choices_file(); fm_shutdown(); } /*************************************************/ /* main() */ /* */ /* That which runs before all others. */ /*************************************************/ int main(int argc, char * argv[]) { WimpPollBlock b; int eventcode, time; int argp = 1, done_one = 0; #ifdef INCLUDE_HEAPGRAPH HeapGraph_RedirectAllocFns(NULL); #endif #ifdef INCLUDE_HIERPROF HierProf_ProfileAllFunctions(); #endif #ifdef INCLUDE_MEMCHECK MemCheck_Init(); MemCheck_InterceptSCLStringFunctions(); MemCheck_RegisterArgs(argc, argv); MemCheck_SetStoreMallocFunctions(1); MemCheck_SetReportFrees(1); MemCheck_SetAutoOutputBlocksInfo(0); #endif #ifndef TRACE /* Prevent postmortems; instead, report errors in a standard window. */ /* If backtraces are needed, use the debugger... */ /* */ /* If compiling a version for the debugger, ensure TRACE is defined */ /* or the code is commented out. The code below can mess up the */ /* debugger as default handlers are not beng used, and trying to */ /* install them tramples on the debugger's environment setup. */ { int loop, ret1, ret2, ret3; /* Loop over the undefined instruction, prefetch abort, data abort */ /* and address exception handlers, resetting them to the RISC OS */ /* defaults. The RISC OS default handlers raise a standard RISC OS */ /* error, having filled in the *ShowRegs register dump. (See PRM */ /* volume 1 page 315 onwards). */ for (loop = 1; loop <= 4; loop ++) { _swix(OS_ReadDefaultHandler, _IN(0) | _OUTR(1,3), loop, &ret1, &ret2, &ret3); _swix(OS_ChangeEnvironment, _INR(0,3), loop, ret1, ret2, ret3); } } #endif signal(SIGOSERROR, catch_errors); /* OS error */ signal(SIGILL, catch_errors); /* Illegal instruction */ signal(SIGSEGV, catch_errors); /* Segment violation */ signal(SIGSTAK, catch_errors); /* Stack overflow */ signal(SIGFPE, catch_errors); /* FPE error */ #ifdef TRACE malloccount = flexcount = 0; /* Handle -d[ebug] CLI switch; see Global.c for more information. */ /* This must be the first command line argument. */ if (argc >= argp + 1) { if (!strcmp(argv[argp],"-debug") | !strcmp(argv[argp],"-d")) { if (strstr(argv[argp + 1], "MsgT")) tl |= (1u<<0); if (strstr(argv[argp + 1], "TBar")) tl |= (1u<<1); if (strstr(argv[argp + 1], "Null")) tl |= (1u<<2); if (strstr(argv[argp + 1], "Wind")) tl |= (1u<<3); if (strstr(argv[argp + 1], "Menu")) tl |= (1u<<4); if (strstr(argv[argp + 1], "Rout")) tl |= (1u<<5); if (strstr(argv[argp + 1], "Fetc")) tl |= (1u<<6); if (strstr(argv[argp + 1], "Memo")) tl |= (1u<<7); if (strstr(argv[argp + 1], "Refo")) tl |= (1u<<8); if (strstr(argv[argp + 1], "Redr")) tl |= (1u<<9); if (strstr(argv[argp + 1], "Font")) tl |= (1u<<10); if (strstr(argv[argp + 1], "BBox")) tl |= (1u<<11); if (strstr(argv[argp + 1], "LMem")) tl |= (1u<<12); if (strstr(argv[argp + 1], "CMal")) tl |= (1u<<13); if (strstr(argv[argp + 1], "CFle")) tl |= (1u<<14); if (strstr(argv[argp + 1], "Imag")) tl |= (1u<<15); if (strstr(argv[argp + 1], "Hist")) tl |= (1u<<16); if (strstr(argv[argp + 1], "Fram")) tl |= (1u<<17); if (strstr(argv[argp + 1], "Stre")) tl |= (1u<<18); if (strstr(argv[argp + 1], "Circ")) tl |= (1u<<19); if (strstr(argv[argp + 1], "Tabl")) tl |= (1u<<20); if (strstr(argv[argp + 1], "URIH")) tl |= (1u<<21); if (strstr(argv[argp + 1], "KeyC")) tl |= (1u<<22); if (strstr(argv[argp + 1], "RBox")) tl |= (1u<<23); if (strstr(argv[argp + 1], "JScr")) tl |= (1u<<24); if (strstr(argv[argp + 1], "Hotl")) tl |= (1u<<25); if (strstr(argv[argp + 1], "Save")) tl |= (1u<<26); if (strstr(argv[argp + 1], "All")) tl = 0xffffffff; argp += 2; } } if (tl & (1u<<5)) Printf("\nmain: Initialising\n"); #endif initialise_app(); #ifdef TRACE if (tl & (1u<<5)) Printf("main: Loading choices\n"); #endif load_choices(); #ifdef TRACE if (tl & (1u<<5)) Printf("main: Handling CLI arguments\n"); #endif /* If using keyboard control, watch the pointer for movement, */ /* turning it off if not moved for 5 seconds. */ if (choices.keyboardctl) mouse_watch_pointer_control(1); /* Keep advancing argp if the arguments are dealt with; */ /* only continue to check the arguments if we haven't */ /* pushed argp past argc, the total number of arguments. */ done_one = 1; while (argc >= argp && done_one) { done_one = 0; /* Handle -html (HTML files) */ if (argc >= argp + 1) { if (!strcmp(argv[argp], "-html")) { char url[Limits_URL]; #ifdef TRACE if (tl & (1u<<5)) Printf("main: Handling -html CLI argument\n"); #endif StrNCpy0(url, argv[argp + 1]); urlutils_pathname_to_url(url, sizeof(url)); windows_create_browser(url, NULL, NULL, NULL, 0); argp += 2, done_one = 1; } } /* Handle -uri (URI files) */ if (argc >= argp + 1) { if (!strcmp(argv[argp], "-uri")) { char url[Limits_URL]; #ifdef TRACE if (tl & (1u<<5)) Printf("main: Handling -uri CLI argument\n"); #endif urlutils_load_uri_file(url, sizeof(url), argv[argp + 1]); windows_create_browser(url, NULL, NULL, NULL, 0); argp += 2, done_one = 1; } } /* Handle -url (URL strings) */ if (argc >= argp + 1) { if (!strcmp(argv[argp],"-url") || !strcmp(argv[argp],"-u")) { #ifdef TRACE if (tl & (1u<<5)) Printf("main: Handling -url CLI argument\n"); #endif windows_create_browser(argv[argp+1], NULL, NULL, NULL, 0); argp += 2, done_one = 1; } } } #ifdef TRACE if (tl & (1u<<5)) Printf("main: Polling\n"); #endif atexit(termination); setjmp(env); while(!quit) { _swix(OS_ReadMonotonicTime, _OUT(0), &time); /* Use PollIdle, but want drag events to be as responsive as possible */ ChkError(event_poll_idle(&eventcode, &b, time + (drag_in_progress ? 0 : fixed.poll_delay), NULL)); } #ifdef TRACE if (tl & (1u<<5)) Printf("\nmain: Calling exit()\n"); if (tl & (1u<<13)) Printf(" malloccount: \0216%d\0217\n",malloccount); if (tl & (1u<<14)) Printf(" flexcount : %d\n",flexcount); #endif /* This will call the termination() function in passing */ exit(EXIT_SUCCESS); }