langipcmenus.c

Go to the documentation of this file.
00001 
00002 /*  $Id: langipcmenus.c 1208 2006-04-05 23:51:45Z karstenw $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include <land.h>
00032 #include "error.h"
00033 #include "kb.h"
00034 #include "memory.h"
00035 #include "strings.h"
00036 #include "lang.h"
00037 #include "langexternal.h"
00038 #include "tablestructure.h"
00039 #include "menubar.h"
00040 #include "menuverbs.h"
00041 #include "meprograms.h"
00042 #include "process.h"
00043 #include "launch.h"
00044 #include "langipc.h"
00045 
00046 
00047 
00048 typedef struct tymenulistrecord {
00049     
00050     long id; /*this list's key is the program id*/
00051     
00052     hdloutlinerecord houtline; /*another way to look up a stack*/
00053     
00054     hdlmenubarstack hstack;
00055     
00056     struct tymenulistrecord **nextlist;
00057     } tymenulistrecord, **hdlmenulistrecord;
00058 
00059 
00060 static hdlmenulistrecord hmenulist = nil;
00061 
00062 static boolean flshuttingmenusdown = false;
00063 
00064 
00065 
00066 static boolean langipcfindmenus (long id, hdloutlinerecord houtline, hdlmenulistrecord *hmenus) {
00067     
00068     register hdlmenulistrecord x = hmenulist;
00069     register boolean fl;
00070     
00071     while (x != nil) {
00072         
00073         if (houtline == nil)
00074             fl = (**x).id == id;
00075         else
00076             fl = (**x).houtline == houtline;
00077         
00078         if (fl) {
00079             
00080             *hmenus = x;
00081             
00082             return (true);
00083             }
00084         
00085         x = (**x).nextlist;
00086         } /*while*/
00087     
00088     *hmenus = nil;
00089     
00090     return (false);
00091     } /*langipcfindmenus*/
00092     
00093 
00094 static boolean langipcfindmenubarstack (long id, hdlmenubarstack *hstack) {
00095     
00096     hdlmenulistrecord hmenus;
00097     
00098     *hstack = nil; /*default return*/
00099     
00100     if (!langipcfindmenus (id, nil, &hmenus))
00101         return (false);
00102     
00103     *hstack = (**hmenus).hstack;
00104     
00105     return (true);
00106     } /*langipcfindmenubarstack*/
00107 
00108 
00109 boolean langipcgetmenuhandle (OSType id, short ixarray, Handle *hmenu) {
00110     
00111     hdlmenubarstack hstack;
00112     
00113     if (!langipcfindmenubarstack (id, &hstack))
00114         return (false);
00115     
00116     return (copyhandle ((Handle) (**hstack).stack [ixarray].hmenu, hmenu));
00117     } /*langipcgetmenuhandle*/
00118 
00119 
00120 static boolean pushmenulist (long id, hdloutlinerecord houtline, hdlmenubarstack hstack) {
00121     
00122     hdlmenulistrecord hlistrecord;
00123     register hdlmenulistrecord h;
00124     
00125     if (!newclearhandle (sizeof (tymenulistrecord), (Handle *) &hlistrecord))
00126         return (false);
00127     
00128     h = hlistrecord; /*move into register*/
00129     
00130     (**h).id = id;
00131     
00132     (**h).houtline = houtline;
00133     
00134     (**h).hstack = hstack;
00135     
00136     (**h).nextlist = hmenulist;
00137     
00138     hmenulist = h;
00139     
00140     return (true);
00141     } /*pushmenulist*/
00142 
00143 
00144 static void disposemenubarstack (hdlmenubarstack hstack) {
00145     
00146     hdlmenubarlist hsave = menubarlist;
00147     
00148     menubarlist = nil; /*so menu deallocation doesn't touch current bitmap*/
00149     
00150     medisposemenubar (hstack);
00151     
00152     menubarlist = hsave;
00153     } /*disposemenubarstack*/
00154 
00155 
00156 static boolean disposemenulist (long id) {
00157     
00158     /*
00159     dispose the menulist structure with the indicated id and remove 
00160     it from the linked list.
00161     */
00162     
00163     register hdlmenulistrecord x = hmenulist;
00164     register hdlmenulistrecord hnext = nil;
00165     register hdlmenulistrecord hprev = nil;
00166     
00167     while (x != nil) {
00168         
00169         hnext = (**x).nextlist;
00170         
00171         if ((**x).id == id) {
00172             
00173             disposemenubarstack ((**x).hstack);
00174             
00175             disposehandle ((Handle) x);
00176             
00177             if (hprev == nil)
00178                 hmenulist = hnext;
00179             else
00180                 (**hprev).nextlist = hnext;
00181             
00182             return (true);
00183             }
00184         
00185         hprev = x;
00186         
00187         x = hnext;
00188         } /*while*/
00189     
00190     return (false);
00191     } /*disposemenulist*/
00192 
00193 
00194 static void disposeallmenulists (void) {
00195     
00196     while (hmenulist != nil) /*list isn't empty*/
00197         disposemenulist ((**hmenulist).id);
00198     } /*disposeallmenulists*/
00199 
00200 
00201 static boolean getmenubartable (hdlhashtable *htable) {
00202     
00203     *htable = menubartable;
00204     
00205     return (menubartable != nil);
00206     } /*getmenubartable*/
00207 
00208 
00209 static boolean getappmenurecord (long id, hdlmenurecord *hrecord) {
00210     
00211     /*
00212     get the menurecord for the application with the indicated id.
00213     */
00214     
00215     hdlhashtable lmenubartable;
00216     bigstring bs;
00217     
00218     if (!getmenubartable (&lmenubartable))
00219         return (false);
00220     
00221     ostypetostring (id, bs);
00222     
00223     return (menugetmenubar (lmenubartable, bs, false, hrecord));
00224     } /*getappmenurecord*/
00225 
00226 
00227 static boolean buildmenubarstack (hdlmenurecord hmenurecord, short firstmenuid, hdlmenubarstack *hstack) {
00228     
00229     /*
00230     build a menubar stack for the given menu record's outline.
00231     
00232     set up an empty menubarlist with the indicated baseid so that the 
00233     full range of menu ids is available, independent of the menus in 
00234     Frontier's menu bar.
00235     */
00236     
00237     hdlmenubarlist hlist, savemenubarlist;
00238     register boolean fl;
00239     
00240     if (!newmenubarlist (&hlist))
00241         return (false);
00242     
00243     if (!menewmenubar ((**hmenurecord).menuoutline, hstack)) {
00244         
00245         disposemenubarlist (hlist);
00246         
00247         return (false);
00248         }
00249     
00250     (**hlist).basemenuid = firstmenuid;
00251     
00252     savemenubarlist = menubarlist;
00253     
00254     menubarlist = hlist;
00255     
00256     fl = mebuildmenubar (*hstack);
00257     
00258     if (!fl)
00259         medisposemenubar (*hstack);
00260     
00261     disposemenubarlist (hlist);
00262     
00263     menubarlist = savemenubarlist;
00264     
00265     return (fl);
00266     } /*buildmenubarstack*/
00267 
00268 
00269 static boolean buildmenuarray (hdlmenubarstack hstack, hdlmenuarray *hmenuarray) {
00270     
00271     /*
00272     fill the menuarray with menus from the menubar stack.
00273     
00274     4.1b2 dmb: menu array in the (client) application zone. actually, let the client
00275     do it. if *hmenuarray is non-nil, just resize it.
00276     */
00277     
00278     register tymenubarstackelement *pstack;
00279     register tyruntimemenurecord *pruntime;
00280     short ctmenus = (**hstack).topstack;
00281     
00282     #if 0 //def flnewfeatures
00283     
00284         /*
00285         THz savezone = GetZone ();
00286         
00287         SetZone (ApplicationZone ());
00288         
00289         *hmenuarray = (hdlmenuarray) NewHandleClear (ctmenus * sizeof (tyruntimemenurecord));
00290         
00291         SetZone (savezone);
00292         
00293         if (*hmenuarray == nil) {
00294         
00295             memoryerror ();
00296             
00297             return (false);
00298             }
00299         */
00300         
00301     #else
00302         
00303         if (!newclearhandle (ctmenus * sizeof (tyruntimemenurecord), (Handle *) hmenuarray))
00304             return (false);
00305         
00306     #endif
00307     
00308     pstack = (**hstack).stack;
00309     
00310     pruntime = ***hmenuarray;
00311     
00312     while (--ctmenus >= 0) { /*copy the fields we care about into the runtime array*/
00313         
00314         (*pruntime).idmenu = (*pstack).idmenu;
00315         
00316         (*pruntime).flhierarchic = (*pstack).flhierarchic;
00317         
00318         (*pruntime++).hmenu = (*pstack++).hmenu;
00319         }
00320     
00321     return (true);
00322     } /*buildmenuarray*/
00323 
00324 
00325 static boolean langipcsendmenumessage (tyapplicationid id, tyverbtoken message) {
00326     
00327     /*
00328     11/26/91 dmb: since this is just a notification, don't wait for a 
00329     reply.  these calls can be happening at odd times (while a script is 
00330     running; when quitting; etc.), so it may also prevent bugs like the one 
00331     just fixed in langipcmenubarchanged by avoiding the thread swapping that 
00332     occurs during a wait.
00333     */
00334     
00335     hdlverbrecord hverb;
00336     typaramrecord param;
00337     bigstring bserror;
00338     short iderror;
00339     
00340     if (!landnewverb (id, nil, id, message, 0, &hverb))
00341         return (false);
00342     
00343     landverbgetsnoreply (hverb); /*no point in waiting around*/
00344     
00345     if (!landsendverb (hverb, &param, bserror, &iderror))
00346         return (false);
00347     
00348     landdisposeparamrecord (&param);
00349     
00350     return (true);
00351     } /*langipcsendmenumessage*/
00352 
00353 
00354 #if !flruntime
00355 
00356 static boolean langipcmenuprocessstarted (void) {
00357     
00358     /*
00359     we don't want Frontier's menus to dim when serving another application's 
00360     menu selection.
00361     */
00362     
00363     processnotbusy ();
00364     
00365     return (true);
00366     } /*langipcmenuprocessstarted*/
00367 
00368 #endif
00369 
00370 
00371 static boolean langipcmenuprocesskilled (void) {
00372     
00373     /*
00374     send a message to the client application that asked for this script 
00375     to be run to let it know that the script has completed execution
00376     
00377     10/29/91 dmb: we now create the done verb when process is created, 
00378     so that errors can be hooked and reported back to caller.
00379     */
00380     
00381     hdlverbrecord hverb;
00382     typaramrecord param;
00383     bigstring bserror;
00384     short iderror;
00385     
00386     hverb = (hdlverbrecord) (**currentprocess).processrefcon; /*the pre-created 'done' message*/
00387     
00388     (**hverb).verbtoken = idscriptcompleted; /*landreturnerror changes token; restore*/
00389     
00390     landverbgetsnoreply (hverb); /*no point in waiting around*/
00391     
00392     if (landsendverb (hverb, &param, bserror, &iderror))
00393         landdisposeparamrecord (&param);
00394     
00395     return (true);
00396     } /*langipcmenuprocesskilled*/
00397 
00398 
00399 boolean langipcgetitemlangtext (long id, short idmenu, short iditem, Handle *htext, long *signature) {
00400     
00401     /*
00402     2/15/93 dmb: broke out this code to share w/osamenus.c
00403     */
00404     
00405     hdlmenubarstack hstack;
00406     hdlheadrecord hnode;
00407     boolean fl;
00408     
00409     *htext = nil;
00410     
00411     if (!langipcfindmenubarstack (id, &hstack))
00412         return (false);
00413     
00414     pushmenubarglobals (hstack);
00415     
00416     #if flruntime
00417         
00418         if (memenuhit (idmenu, iditem, &hnode))
00419             fl = megetnodelangtext (hnode, htext, signature);
00420         else
00421             fl = false;
00422     
00423     #else
00424         
00425         menudata = (hdlmenurecord) (**outlinedata).outlinerefcon;
00426         
00427         if (memenuhit (idmenu, iditem, &hnode)) {
00428             
00429             if (optionkeydown ())
00430                 fl = langipcshowmenunode ((long) hnode);
00431             else
00432                 fl = megetnodelangtext (hnode, htext, signature);
00433             }
00434         else
00435             fl = false;
00436         
00437     #endif
00438     
00439     popmenubarglobals ();
00440 
00441     return (fl);
00442     } /*langipcgetitemlangtext*/
00443 
00444 
00445 boolean langipccheckformulas (long id) {
00446     
00447     hdlmenubarstack hstack;
00448     register short i;
00449     register short topstack;
00450     
00451     if (!langipcfindmenubarstack (id, &hstack))
00452         return (false);
00453     
00454     pushmenubarglobals (hstack);
00455     
00456     topstack = (**hstack).topstack;
00457     
00458     for (i = 0; i < topstack; i++) /*search for the menu*/
00459         mecheckformulas (i);
00460     
00461     popmenubarglobals ();
00462     
00463     return (true);
00464     } /*langipccheckformulas*/
00465 
00466 
00467 boolean langipcrunitem (long id, short idmenu, short iditem, long *refcon) {
00468     
00469     /*
00470     9/27/91 dmb: when the option key is down, bring ourself to the front 
00471     so that the user will see the selected menu item (a feature of memenuhit)
00472     
00473     10/29/91 dmb: always set keyboardstatus.floptionkey, not just when option 
00474     key is now down
00475     
00476     2/10/92 dmb: use new shellactivate instead of activateprogram
00477     
00478     2/16/93 dmb: decision of what to do w/selected node now rests with us, not memenuhit
00479     
00480     3.0a dmb: no more special case for runtime's execution of the process
00481     */
00482     
00483     hdlmenubarstack hstack;
00484     boolean fl = false;
00485     register hdlprocessrecord hp;
00486     hdlverbrecord hverb;
00487     boolean fljustshownode;
00488     hdlheadrecord hnode;
00489     
00490     *refcon = 0; /*default return*/
00491     
00492     if (!langipcfindmenubarstack (id, &hstack))
00493         return (false);
00494     
00495     #if !flruntime
00496     
00497     fljustshownode = optionkeydown ();
00498     
00499     if (fljustshownode) /*option key is down -- we'll show item instead of running it*/
00500         shellactivate ();
00501     
00502     #endif
00503     
00504     pushmenubarglobals (hstack);
00505     
00506     newlyaddedprocess = nil; /*process manager global*/
00507     
00508     #if flruntime
00509     
00510         if (memenuhit (idmenu, iditem, &hnode))
00511             fl = meuserselected (hnode);
00512         
00513     #else
00514         
00515         if (memenuhit (idmenu, iditem, &hnode)) {
00516             
00517             if (fljustshownode)
00518                 fl = meshownode (hnode);
00519             else
00520                 fl = meuserselected (hnode);
00521             }
00522         
00523     #endif
00524     
00525     popmenubarglobals ();
00526     
00527     hp = newlyaddedprocess; /*process.c global; will be nil if a process wasn't just added*/
00528     
00529     if (hp != nil) {
00530         
00531         if (landnewverb (id, nil, id, idscriptcompleted, 0, &hverb)) { /*will send upon completion*/
00532             
00533             (**hp).processrefcon = (long) hverb;
00534             
00535             (**hp).errormessagecallback = &langipcerrorroutine;
00536             
00537             #if !flruntime
00538             
00539                 (**hp).processstartedroutine = &langipcmenuprocessstarted;
00540             
00541             #endif
00542             
00543             (**hp).processkilledroutine = &langipcmenuprocesskilled;
00544             
00545             *refcon = (long) (**hp).hcode;
00546             }
00547         else { /*ran out of memory*/
00548             
00549             processkill (hp); /*don't want it to run*/
00550             
00551             fl = false; /*must return false to caller so it won't expect 'done' message*/
00552             }
00553         }
00554     
00555     #if 0 /*flruntime*/
00556         
00557         if (!fl)
00558             return (false);
00559         
00560         addprocess (hp); /*run it*/
00561         
00562     #else
00563         
00564         newlyaddedprocess = nil; /*clean up*/
00565         
00566         return (fl);
00567     
00568     #endif
00569     
00570     } /*langipcrunitem*/
00571 
00572 
00573 boolean langipcgetmenuarray (long id, short firstmenuid, boolean flclientowned, Handle *hmenuarray) {
00574     
00575     /*
00576     6/1/93 dmb: make sure yielding is disabled when we build menus in case we 
00577     end up reducing a formula while servicing a fast event
00578     
00579     2.1b8 dmb: return false if we're in the process of shutting down
00580     
00581     2.1b13 dmb: about the flclientedowned mechanism... the issue: 
00582     with component menu sharing, there's only one copy of the menus. The 
00583     main benefit, aside from being more efficient, is that it makes it easier 
00584     to support recalculating formulas. but it also means that either Frontier 
00585     or the client has to refer to data structures in the other's heap. When 
00586     Frontier or the client quits, it's essential that this be managed carefully. 
00587     In particular, disposing a menu that is in the client's menu list will lead 
00588     to a crash, so we need to get the client to dispose its menus before we 
00589     finish quitting. (this is done by osacomponentshutdown).
00590     
00591     so crashing bugs led me to believe that the entire mechanism was inadequte, 
00592     but since the langipcmenu menulist structure is private, and only used to 
00593     serve shared menus, it's really pretty safe. the problem, I think, are some 
00594     timing issues that hadn't been considered. the new langipcdisposemenus 
00595     routine below should (I hope) clear this up.
00596     */
00597     
00598     hdlmenubarstack hstack;
00599     hdlmenurecord hmenurecord;
00600     boolean fl;
00601     
00602     if (flshuttingmenusdown)
00603         return (false);
00604     
00605     if (!langipcfindmenubarstack (id, &hstack)) {
00606         
00607         if (!getappmenurecord (id, &hmenurecord))
00608             return (false);
00609         
00610         ++fldisableyield;
00611         
00612         fl = buildmenubarstack (hmenurecord, firstmenuid, &hstack);
00613         
00614         --fldisableyield;
00615         
00616         if (!fl)
00617             return (false);
00618         
00619         if (!pushmenulist (id, (**hstack).menubaroutline, hstack)) {
00620             
00621             disposemenubarstack (hstack);
00622             
00623             return (false);
00624             }
00625         }
00626     
00627     if (!buildmenuarray (hstack, (hdlmenuarray *) hmenuarray))
00628         return (false);
00629     
00630     (**hstack).flclientowned = flclientowned;
00631     
00632     return (true);
00633     } /*langipcgetmenuarray*/
00634 
00635 
00636 void langipcdisposemenuarray (long id, Handle hmenusarray) {
00637     
00638     /*
00639     2.1b13 dmb: with apple event menu sharing, a client will never dispose
00640     a menu array unless we've already disposed the corresponding menulist
00641     and sent it an 'updm' message. except when it's quitting, but we're not 
00642     informed when that happens.
00643     
00644     with component menu sharing, a client may actually get menus before 
00645     it receives an 'updm' message (on launch). it's important that we 
00646     not assume that the menulist isn't there when it disposes a menu array, 
00647     'cause if it is there its handles are invalid. on top of that, since 
00648     the component manager informs us when the client quits, this gives us 
00649     a chance to release unneeded memory.
00650     */
00651     
00652     disposemenulist (id); /*release associated menu list*/
00653     
00654     disposehandle (hmenusarray);
00655     } /*langipcdisposemenuarray*/
00656 
00657 
00658 
00659 #if !flruntime
00660 
00661 static boolean langipcmenubarchanged (hdloutlinerecord houtline) {
00662     
00663     /*
00664     called from menubar.c when a menubar change (insert, delete, 
00665     reorg, etc.) occurs.
00666     
00667     since we maintain our own menubar stacks, we have to use the 
00668     outline itself as the key to finding a match in our list.
00669     
00670     this should probably be a callback, if there were menubarcallbacks.
00671     
00672     11/26/91 dmb: callback now gets called with outline, not menubarstack. 
00673     also, must disposemenulist before sending update message, in case 
00674     new menus are requested before message routine returns.
00675     */
00676     
00677     hdlmenulistrecord hmenus;
00678     
00679     if (langipcfindmenus (0L, houtline, &hmenus)) {
00680         
00681         register long id = (**hmenus).id;
00682         
00683         disposemenulist (id); /*must rebuild from scratch*/
00684         
00685         langipcsendmenumessage (id, idupdatemenus);
00686         }
00687     
00688     return (true);
00689     } /*langipcmenubarchanged*/
00690 
00691 #endif
00692 
00693 
00694 static boolean notifyappvisit (hdlhashnode hnode, ptrvoid refcon) {
00695 #pragma unused (refcon)
00696 
00697     /*
00698     if hnode is a menubar that may belong to an application, send the 
00699     updatemenustoken message to that application.
00700     
00701     always return true so all table nodes will be visited.
00702     
00703     2.1b13 dmb: under component menusharing, the client might ask for 
00704     (and get) its shared menus before we get here. do don't send a 
00705     notification if the menubar stack is already built.
00706     */
00707     
00708     register hdlhashnode h = hnode;
00709     bigstring bskey;
00710     long id;
00711     hdlmenubarstack hstack;
00712     
00713     if (langexternalgettype ((**h).val) != idmenuprocessor) /*not a menubar value*/
00714         return (true);
00715     
00716     gethashkey (h, bskey);
00717     
00718     if (!stringtoostype (bskey, (OSType *) &id)) /*name longer than 4 characters*/
00719         return (true);
00720     
00721     if (!langipcfindmenubarstack (id, &hstack)) /*didn't already get them*/
00722         langipcsendmenumessage (id, idupdatemenus);
00723     
00724     return (true);
00725     } /*notifyappvisit*/
00726 
00727 
00728 boolean langipcmenustartup (void) {
00729     
00730     /*
00731     visit the menubar table and send a message to each application 
00732     to let them know their menus are available
00733     */
00734     
00735     hdlhashtable lmenubartable;
00736     
00737     if (!getmenubartable (&lmenubartable))
00738         return (false);
00739     
00740     hashtablevisit (lmenubartable, &notifyappvisit, nil);
00741     
00742     return (true);
00743     } /*langipcmenustartup*/
00744 
00745 
00746 boolean langipcmenushutdown (void) {
00747     
00748     /*
00749     visit the menubar table and send a message to each application 
00750     to let them know their menus are no longer available
00751     
00752     2.1b8 dmb: since our component may have installed the 'done' handler, 
00753     we need to let the event be processed before quitting. so we have to 
00754     wait for a reply, and set the flshuttingmenusdown flag to prevent a 
00755     new set of menus from being built
00756     */
00757     
00758     hdlhashtable lmenubartable;
00759     
00760     disposeallmenulists ();
00761     
00762     if (!getmenubartable (&lmenubartable))
00763         return (false);
00764     
00765     flshuttingmenusdown = true;
00766     
00767     hashtablevisit (lmenubartable, &notifyappvisit, nil);
00768     
00769     flshuttingmenusdown = false;
00770     
00771     return (true);
00772     } /*langipcmenushutdown*/
00773 
00774 
00775 static boolean getmenubarid (hdlhashtable htable, const bigstring bs, tyapplicationid *id) {
00776     
00777     hdlhashtable lmenubartable;
00778     
00779     if (!getmenubartable (&lmenubartable))
00780         return (false);
00781     
00782     if (htable != lmenubartable)
00783         return (false);
00784     
00785     return (stringtoostype ((ptrstring) bs, id)); /*false if name is longer than 4 characters*/
00786     } /*getmenubarid*/
00787 
00788 
00789 boolean langipcsymbolchanged (hdlhashtable htable, const bigstring bs, boolean flvalue) {
00790 #pragma unused(flvalue)
00791 
00792     tyapplicationid id;
00793     
00794     if (getmenubarid (htable, bs, &id)) {
00795         
00796         langipcsendmenumessage (id, idupdatemenus);
00797         
00798         disposemenulist (id); /*must rebuild from scratch*/
00799         }
00800     
00801     return (true);
00802     } /*langipcsymbolchanged*/
00803 
00804 
00805 boolean langipcsymbolinserted (hdlhashtable htable, const bigstring bs) {
00806     
00807     return (langipcsymbolchanged (htable, bs, true));
00808     } /*langipcsymbolinserted*/
00809 
00810 
00811 boolean langipcsymboldeleted (hdlhashtable htable, const bigstring bs) {
00812     
00813     return (langipcsymbolchanged (htable, bs, true));
00814     } /*langipcsymboldeleted*/
00815 
00816 
00817 boolean langipcmenuinit (void) {
00818     
00819     #if !flruntime
00820     
00821     menubarcallbacks.menubarchangedroutine = &langipcmenubarchanged;
00822     
00823     #endif
00824     
00825     return (true);
00826     } /*langipcmenuinit*/
00827 
00828 
00829 
00830 
00831 

Generated on Wed May 31 18:19:52 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6