Пример #1
0
extern "C" __declspec(dllexport) int Load(void)
{
    mir_getLP(&pluginInfoEx);

    if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) {
        ReportError(TranslateT("Only one instance of SmileyAdd could be executed.\nRemove duplicate instances from 'Plugins' directory"));

        return 1;
    }

    InitImageCache();

    Icon_Register(g_hInst, "SmileyAdd", &icon, 1);

    g_SmileyCategories.SetSmileyPackStore(&g_SmileyPacks);

    opt.Load();

    // create smiley events
    hEvent1 = CreateHookableEvent(ME_SMILEYADD_OPTIONSCHANGED);

    HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
    HookEvent(ME_SYSTEM_PRESHUTDOWN, MirandaShutdown);
    HookEvent(ME_OPT_INITIALISE, SmileysOptionsInitialize);
    HookEvent(ME_CLIST_PREBUILDCONTACTMENU, RebuildContactMenu);
    HookEvent(ME_SMILEYADD_OPTIONSCHANGED, UpdateSrmmDlg);
    HookEvent(ME_PROTO_ACCLISTCHANGED, AccountListChanged);
    HookEvent(ME_DB_CONTACT_SETTINGCHANGED, DbSettingChanged);
    HookEvent(ME_COLOUR_RELOAD, ReloadColour);

    //create the smiley services
    CreateServiceFunction(MS_SMILEYADD_REPLACESMILEYS, ReplaceSmileysCommand);
    CreateServiceFunction(MS_SMILEYADD_SHOWSELECTION, ShowSmileySelectionCommand);
    CreateServiceFunction(MS_SMILEYADD_GETINFO2, GetInfoCommand2);
    CreateServiceFunction(MS_SMILEYADD_REGISTERCATEGORY, RegisterPack);
    CreateServiceFunction(MS_SMILEYADD_BATCHPARSE, ParseTextBatch);
    CreateServiceFunction(MS_SMILEYADD_BATCHFREE, FreeTextBatch);
    CreateServiceFunction(MS_SMILEYADD_CUSTOMCATMENU, CustomCatMenu);
    CreateServiceFunction(MS_SMILEYADD_RELOAD, ReloadPack);
    CreateServiceFunction(MS_SMILEYADD_LOADCONTACTSMILEYS, LoadContactSmileys);
    return 0;
}
Пример #2
0
int fontforge_main( int argc, char **argv ) {
    extern const char *source_modtime_str;
    extern const char *source_version_str;
    const char *load_prefs = getenv("FONTFORGE_LOADPREFS");
    int i;
    int recover=2;
    int any;
    int next_recent=0;
    GRect pos;
    GWindowAttrs wattrs;
    char *display = NULL;
    FontRequest rq;
    int ds, ld;
    int openflags=0;
    int doopen=0, quit_request=0;
    bool use_cairo = true;

#if !(GLIB_CHECK_VERSION(2, 35, 0))
    g_type_init();
#endif

    /* Must be done before we cache the current directory */
    /* Change to HOME dir if specified on the commandline */
    for ( i=1; i<argc; ++i ) {
	char *pt = argv[i];
	if ( pt[0]=='-' && pt[1]=='-' ) ++pt;
	if (strcmp(pt,"-home")==0 || strncmp(pt,"-psn_",5)==0) {
	    /* OK, I don't know what _-psn_ means, but to GW it means */
	    /* we've been started on the mac from the FontForge.app   */
	    /* structure, and the current directory is (shudder) "/"  */
	    if (getenv("HOME")!=NULL) chdir(getenv("HOME"));
	    break;	/* Done - Unnecessary to check more arguments */
	}
	if (strcmp(pt,"-quiet")==0)
	    quiet = 1;
    }

    if (!quiet) {
        fprintf( stderr, "Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.\n" );
        fprintf( stderr, " License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n" );
        fprintf( stderr, " with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.\n" );
        fprintf( stderr, " Based on sources from %s"
	        "-ML"
#ifdef FREETYPE_HAS_DEBUGGER
	        "-TtfDb"
#endif
#ifdef _NO_PYTHON
	        "-NoPython"
#endif
#ifdef FONTFORGE_CONFIG_USE_DOUBLE
	        "-D"
#endif
	        ".\n",
	        FONTFORGE_MODTIME_STR );
        fprintf( stderr, " Based on source from git with hash: %s\n", FONTFORGE_GIT_VERSION );
    }

#if defined(__Mac)
    /* Start X if they haven't already done so. Well... try anyway */
    /* Must be before we change DYLD_LIBRARY_PATH or X won't start */
    /* (osascript depends on a libjpeg which isn't found if we look in /sw/lib first */
    int local_x = uses_local_x(argc,argv);
    if ( local_x==1 && getenv("DISPLAY")==NULL ) {
	/* Don't start X if we're just going to quit. */
	/* if X exists, it isn't needed. If X doesn't exist it's wrong */
	if ( !hasquit(argc,argv)) {
	    /* This sequence is supposed to bring up an app without a window */
	    /*  but X still opens an xterm */
	    system( "osascript -e 'tell application \"X11\" to launch'" );
	    system( "osascript -e 'tell application \"X11\" to activate'" );
	}
	setenv("DISPLAY",":0.0",0);
    } else if ( local_x==1 && *getenv("DISPLAY")!='/' && strcmp(getenv("DISPLAY"),":0.0")!=0 && strcmp(getenv("DISPLAY"),":0")!=0 )
	/* 10.5.7 uses a named socket or something "/tmp/launch-01ftWX:0" */
	local_x = 0;
#endif

#if defined(__MINGW32__)
    if( getenv("DISPLAY")==NULL ) {
	putenv("DISPLAY=127.0.0.1:0.0");
    }
    if( getenv("LC_ALL")==NULL ){
	char lang[8];
	char env[32];
	if( GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, 8) > 0 ){
	    strcpy(env, "LC_ALL=");
	    strcat(env, lang);
	    putenv(env);
	}
    }
#endif

    FF_SetUiInterface(&gdraw_ui_interface);
    FF_SetPrefsInterface(&gdraw_prefs_interface);
    FF_SetSCInterface(&gdraw_sc_interface);
    FF_SetCVInterface(&gdraw_cv_interface);
    FF_SetBCInterface(&gdraw_bc_interface);
    FF_SetFVInterface(&gdraw_fv_interface);
    FF_SetFIInterface(&gdraw_fi_interface);
    FF_SetMVInterface(&gdraw_mv_interface);
    FF_SetClipInterface(&gdraw_clip_interface);
#ifndef _NO_PYTHON
    PythonUI_Init();
#endif

    FindProgDir(argv[0]);
    InitSimpleStuff();

#if defined(__MINGW32__)
    {
        char path[MAX_PATH];
        unsigned int len = GetModuleFileNameA(NULL, path, MAX_PATH);
        path[len] = '\0';
        
        //The '.exe' must be removed as resources presumes it's not there.
        GResourceSetProg(GFileRemoveExtension(GFileNormalizePath(path)));
    }
#else
    GResourceSetProg(argv[0]);
#endif

#if defined(__Mac)
    /* The mac seems to default to the "C" locale, LANG and LC_MESSAGES are not*/
    /*  defined. This means that gettext will not bother to look up any message*/
    /*  files -- even if we have a "C" or "POSIX" entry in the locale diretory */
    /* Now if X11 gives us the command key, I want to force a rebinding to use */
    /*  Cmd rather than Control key -- more mac-like. But I can't do that if   */
    /*  there is no locale. So I force a locale if there is none specified */
    /* I force the US English locale, because that's the what the messages are */
    /*  by default so I'm changing as little as I can. I think. */
    /* Now the locale command will treat a LANG which is "" as undefined, but */
    /*  gettext will not. So I don't bother to check for null strings or "C"  */
    /*  or "POSIX". If they've mucked with the locale perhaps they know what  */
    /*  they are doing */
    {
	int did_keybindings = 0;
	int useCommandKey = get_mac_x11_prop("enable_key_equivalents") <= 0;

	if ( local_x && useCommandKey ) {
	    hotkeySystemSetCanUseMacCommand( 1 );

	    /* Ok, we get the command key */
	    if ( getenv("LANG")==NULL && getenv("LC_MESSAGES")==NULL ) {
		setenv("LC_MESSAGES","en_US.UTF-8",0);
	    }
	    /* Can we find a set of keybindings designed for the mac with cmd key? */
	    bind_textdomain_codeset("Mac-FontForge-MenuShortCuts","UTF-8");
	    bindtextdomain("Mac-FontForge-MenuShortCuts", getLocaleDir());
	    if ( *dgettext("Mac-FontForge-MenuShortCuts","Flag0x10+")!='F' ) {
		GMenuSetShortcutDomain("Mac-FontForge-MenuShortCuts");
		did_keybindings = 1;
	    }
	}
	if ( !did_keybindings ) {
	    /* Nope. we can't. Fall back to the normal stuff */
#endif
	    GMenuSetShortcutDomain("FontForge-MenuShortCuts");
	    bind_textdomain_codeset("FontForge-MenuShortCuts","UTF-8");
	    bindtextdomain("FontForge-MenuShortCuts", getLocaleDir());
#if defined(__Mac)
	}
    }
#endif
    bind_textdomain_codeset("FontForge","UTF-8");
    bindtextdomain("FontForge", getLocaleDir());
    textdomain("FontForge");
    GResourceUseGetText();
    {
	char shareDir[PATH_MAX];
	char* sd = getShareDir();
	strncpy( shareDir, sd, PATH_MAX );
    shareDir[PATH_MAX-1] = '\0';
	if(!sd) {
	    strcpy( shareDir, SHAREDIR );
	}

	char path[PATH_MAX];
	snprintf(path, PATH_MAX, "%s%s", shareDir, "/pixmaps" );
	GGadgetSetImageDir( path );

	snprintf(path, PATH_MAX, "%s%s", shareDir, "/resources/fontforge.resource" );
	GResourceAddResourceFile(path, GResourceProgramName,false);
    }
    hotkeysLoad();
//    loadPrefsFiles();
    Prefs_LoadDefaultPreferences();

    if ( load_prefs!=NULL && strcasecmp(load_prefs,"Always")==0 )
	LoadPrefs();
    if ( default_encoding==NULL )
	default_encoding=FindOrMakeEncoding("ISO8859-1");
    if ( default_encoding==NULL )
	default_encoding=&custom;	/* In case iconv is broken */

    // This no longer starts embedded Python unless control passes to the Python executors,
    // which exit independently rather than returning here.
    CheckIsScript(argc,argv); /* Will run the script and exit if it is a script */
					/* If there is no UI, there is always a script */
			                /*  and we will never return from the above */
    if ( load_prefs==NULL ||
	    (strcasecmp(load_prefs,"Always")!=0 &&	/* Already loaded */
	     strcasecmp(load_prefs,"Never")!=0 ))
	LoadPrefs();
    GrokNavigationMask();
    for ( i=1; i<argc; ++i ) {
	char *pt = argv[i];
	if ( pt[0]=='-' && pt[1]=='-' )
	    ++pt;
	if ( strcmp(pt,"-sync")==0 )
	    GResourceAddResourceString("Gdraw.Synchronize: true",argv[0]);
	else if ( strcmp(pt,"-depth")==0 && i<argc-1 )
	    AddR(argv[0],"Gdraw.Depth", argv[++i]);
	else if ( strcmp(pt,"-vc")==0 && i<argc-1 )
	    AddR(argv[0],"Gdraw.VisualClass", argv[++i]);
	else if ( (strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0) && i<argc-1 )
	    AddR(argv[0],"Gdraw.Colormap", argv[++i]);
	else if ( (strcmp(pt,"-dontopenxdevices")==0) )
	    AddR(argv[0],"Gdraw.DontOpenXDevices", "true");
	else if ( strcmp(pt,"-keyboard")==0 && i<argc-1 )
	    AddR(argv[0],"Gdraw.Keyboard", argv[++i]);
	else if ( strcmp(pt,"-display")==0 && i<argc-1 )
	    display = argv[++i];
# if MyMemory
	else if ( strcmp(pt,"-memory")==0 )
	    __malloc_debug(5);
# endif
	else if ( strncmp(pt,"-usecairo",strlen("-usecairo"))==0 ) {
	    if ( strcmp(pt,"-usecairo=no")==0 )
	        use_cairo = false;
	    else
	        use_cairo = true;
	    GDrawEnableCairo(use_cairo);
	} else if ( strcmp(pt,"-nosplash")==0 )
	    splash = 0;
	else if ( strcmp(pt,"-quiet")==0 )
	    /* already checked for this earlier, no need to do it again */;
	else if ( strcmp(pt,"-unique")==0 )
	    unique = 1;
	else if ( strcmp(pt,"-forceuihidden")==0 )
	    cmdlinearg_forceUIHidden = 0;
	else if ( strcmp(pt,"-recover")==0 && i<argc-1 ) {
	    ++i;
	    if ( strcmp(argv[i],"none")==0 )
		recover=0;
	    else if ( strcmp(argv[i],"clean")==0 )
		recover= -1;
	    else if ( strcmp(argv[i],"auto")==0 )
		recover= 1;
	    else if ( strcmp(argv[i],"inquire")==0 )
		recover= 2;
	    else {
		fprintf( stderr, "Invalid argument to -recover, must be none, auto, inquire or clean\n" );
		dousage();
	    }
	} else if ( strcmp(pt,"-recover=none")==0 ) {
	    recover = 0;
	} else if ( strcmp(pt,"-recover=clean")==0 ) {
	    recover = -1;
	} else if ( strcmp(pt,"-recover=auto")==0 ) {
	    recover = 1;
	} else if ( strcmp(pt,"-recover=inquire")==0 ) {
	    recover = 2;
	} else if ( strcmp(pt,"-docs")==0 )
	    dohelp();
	else if ( strcmp(pt,"-help")==0 )
	    dousage();
	else if ( strcmp(pt,"-version")==0 || strcmp(pt,"-v")==0 || strcmp(pt,"-V")==0 )
	    doversion(FONTFORGE_MODTIME_STR);
	else if ( strcmp(pt,"-quit")==0 )
	    quit_request = true;
	else if ( strcmp(pt,"-home")==0 )
	    /* already did a chdir earlier, don't need to do it again */;
#if defined(__Mac)
	else if ( strncmp(pt,"-psn_",5)==0 ) {
	    /* OK, I don't know what _-psn_ means, but to GW it means */
	    /* we've been started on the mac from the FontForge.app   */
	    /* structure, and the current directory was (shudder) "/" */
	    /* (however, we changed to HOME earlier in main routine). */
	    unique = 1;
	    listen_to_apple_events = true; // This has been problematic on Mavericks and later.
	}
#endif
    }

    ensureDotFontForgeIsSetup();
#if defined(__MINGW32__) && !defined(_NO_LIBCAIRO)
    //Load any custom fonts for the user interface
    if (use_cairo) {
        char *system_load = getGResourceProgramDir();
        char *user_load = getFontForgeUserDir(Data);
        char lbuf[MAX_PATH];
        int lret;

        if (system_load != NULL) {
            //Follow the FontConfig APPSHAREFONTDIR location
            lret = snprintf(lbuf, MAX_PATH, "%s/../share/fonts", system_load);
            if (lret > 0 && lret < MAX_PATH) {
                WinLoadUserFonts(lbuf);
            }
        }
        if (user_load != NULL) {
            lret = snprintf(lbuf, MAX_PATH, "%s/%s", user_load, "ui-fonts");
            if (lret > 0 && lret < MAX_PATH) {
                WinLoadUserFonts(lbuf);
            }
            free(user_load);
        }
    }
#endif
    InitImageCache(); // This is in gtextinfo.c. It zeroes imagecache for us.
    atexit(&ClearImageCache); // We register the destructor, which is also in gtextinfo.c.
    GDrawCreateDisplays(display,argv[0]);
    atexit(&GDrawDestroyDisplays); // We register the destructor so that it runs even if we call exit without finishing this function.
    default_background = GDrawGetDefaultBackground(screen_display);
    InitToolIconClut(default_background);
    InitToolIcons();
    InitCursors();

    /**
     * we have to do a quick sniff of argv[] here to see if the user
     * wanted to skip loading these python init files.
     */
    for ( i=1; i<argc; ++i ) {
	char *pt = argv[i];

	if ( !strcmp(pt,"-SkipPythonInitFiles")) {
	    ProcessPythonInitFiles = 0;
	}
    }
    
#ifndef _NO_PYTHON
/*# ifndef GWW_TEST*/
    FontForge_InitializeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */
/*# endif*/
#endif

#ifndef _NO_PYTHON
    if( ProcessPythonInitFiles )
	PyFF_ProcessInitFiles();
#endif

    /* the splash screen used not to have a title bar (wam_nodecor) */
    /*  but I found I needed to know how much the window manager moved */
    /*  the window around, which I can determine if I have a positioned */
    /*  decorated window created at the begining */
    /* Actually I don't care any more */
    wattrs.mask = wam_events|wam_cursor|wam_bordwidth|wam_backcol|wam_positioned|wam_utf8_wtitle|wam_isdlg;
    wattrs.event_masks = ~(1<<et_charup);
    wattrs.positioned = 1;
    wattrs.cursor = ct_pointer;
    wattrs.utf8_window_title = "FontForge";
    wattrs.border_width = 2;
    wattrs.background_color = 0xffffff;
    wattrs.is_dlg = !listen_to_apple_events;
    pos.x = pos.y = 200;
    pos.width = splashimage.u.image->width;
    pos.height = splashimage.u.image->height-56;		/* 54 */
    GDrawBindSelection(NULL,sn_user1,"FontForge");
    if ( unique && GDrawSelectionOwned(NULL,sn_user1)) {
	/* Different event handler, not a dialog */
	wattrs.is_dlg = false;
	splashw = GDrawCreateTopWindow(NULL,&pos,request_e_h,NULL,&wattrs);
	PingOtherFontForge(argc,argv);
    } else {
	if ( quit_request )
exit( 0 );
	splashw = GDrawCreateTopWindow(NULL,&pos,splash_e_h,NULL,&wattrs);
    }

    memset(&rq,0,sizeof(rq));
    rq.utf8_family_name = SERIF_UI_FAMILIES;
    rq.point_size = 12;
    rq.weight = 400;
    splash_font = GDrawInstanciateFont(NULL,&rq);
    splash_font = GResourceFindFont("Splash.Font",splash_font);
    GDrawDecomposeFont(splash_font, &rq);
    rq.style = fs_italic;
    splash_italic = GDrawInstanciateFont(NULL,&rq);
    splash_italic = GResourceFindFont("Splash.ItalicFont",splash_italic);
    GDrawSetFont(splashw,splash_font);

    SplashLayout();
    localsplash = splash;

   if ( localsplash && !listen_to_apple_events )
	start_splash_screen();

    //
    // The below call will initialize the fontconfig cache if required.
    // That can take a while the first time it happens.
    //
   GDrawWindowFontMetrics(splashw,splash_font,&as,&ds,&ld);
   fh = as+ds+ld;

    if ( AutoSaveFrequency>0 )
	autosave_timer=GDrawRequestTimer(splashw,2*AutoSaveFrequency*1000,AutoSaveFrequency*1000,NULL);

    GDrawProcessPendingEvents(NULL);
    GDrawSetBuildCharHooks(BuildCharHook,InsCharHook);

    any = 0;
    if ( recover==-1 )
	CleanAutoRecovery();
    else if ( recover )
	any = DoAutoRecoveryExtended( recover-1 );
			
    openflags = 0;
    for ( i=1; i<argc; ++i ) {
	char buffer[1025];
	char *pt = argv[i];

	GDrawProcessPendingEvents(NULL);
	if ( pt[0]=='-' && pt[1]=='-' && pt[2]!='\0')
	    ++pt;
	if ( strcmp(pt,"-new")==0 ) {
	    FontNew();
	    any = 1;
#  if HANYANG
	} else if ( strcmp(pt,"-newkorean")==0 ) {
	    MenuNewComposition(NULL,NULL,NULL);
	    any = 1;
#  endif
	} else if ( !strcmp(pt,"-SkipPythonInitFiles")) {
	    // already handled above.
	} else if ( strcmp(pt,"-last")==0 ) {
	    if ( next_recent<RECENT_MAX && RecentFiles[next_recent]!=NULL )
		if ( ViewPostScriptFont(RecentFiles[next_recent++],openflags))
		    any = 1;
	} else if ( strcmp(pt,"-sync")==0 || strcmp(pt,"-memory")==0 ||
		    strcmp(pt,"-nosplash")==0 || strcmp(pt,"-recover=none")==0 ||
		    strcmp(pt,"-recover=clean")==0 || strcmp(pt,"-recover=auto")==0 ||
		    strcmp(pt,"-dontopenxdevices")==0 || strcmp(pt,"-unique")==0 ||
		    strncmp(pt,"-usecairo",strlen("-usecairo"))==0 ||
		    strcmp(pt,"-home")==0 || strcmp(pt,"-quiet")==0
		    || strcmp(pt,"-forceuihidden")==0 )
	    /* Already done, needed to be before display opened */;
	else if ( strncmp(pt,"-psn_",5)==0 )
	    /* Already done */;
	else if ( (strcmp(pt,"-depth")==0 || strcmp(pt,"-vc")==0 ||
		    strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0 ||
		    strcmp(pt,"-keyboard")==0 ||
		    strcmp(pt,"-display")==0 || strcmp(pt,"-recover")==0 ) &&
		i<argc-1 )
	    ++i; /* Already done, needed to be before display opened */
	else if ( strcmp(pt,"-allglyphs")==0 )
	    openflags |= of_all_glyphs_in_ttc;
	else if ( strcmp(pt,"-open")==0 )
	    doopen = true;
	else {
	    printf("else argv[i]:%s\n", argv[i] );
	    if ( strstr(argv[i],"://")!=NULL ) {		/* Assume an absolute URL */
		strncpy(buffer,argv[i],sizeof(buffer));
		buffer[sizeof(buffer)-1]= '\0';
	    } else
		GFileGetAbsoluteName(argv[i],buffer,sizeof(buffer));
	    if ( GFileIsDir(buffer) || (strstr(buffer,"://")!=NULL && buffer[strlen(buffer)-1]=='/')) {
		char *fname;
		fname = malloc(strlen(buffer)+strlen("/glyphs/contents.plist")+1);
		strcpy(fname,buffer); strcat(fname,"/glyphs/contents.plist");
		if ( GFileExists(fname)) {
		    /* It's probably a Unified Font Object directory */
		    free(fname);
		    if ( ViewPostScriptFont(buffer,openflags) )
			any = 1;
		} else {
		    strcpy(fname,buffer); strcat(fname,"/font.props");
		    if ( GFileExists(fname)) {
			/* It's probably a sf dir collection */
			free(fname);
			if ( ViewPostScriptFont(buffer,openflags) )
			    any = 1;
		    } else {
			free(fname);
			if ( buffer[strlen(buffer)-1]!='/' ) {
			    /* If dirname doesn't end in "/" we'll be looking in parent dir */
			    buffer[strlen(buffer)+1]='\0';
			    buffer[strlen(buffer)] = '/';
			}
			fname = GetPostScriptFontName(buffer,false);
			if ( fname!=NULL )
			    ViewPostScriptFont(fname,openflags);
			any = 1;	/* Even if we didn't get a font, don't bring up dlg again */
			free(fname);
		    }
		}
	    } else if ( ViewPostScriptFont(buffer,openflags)!=0 )
		any = 1;
	}
    }
    if ( !any && !doopen )
	any = ReopenLastFonts();

    collabclient_ensureClientBeacon();
    collabclient_sniffForLocalServer();
#ifndef _NO_PYTHON
    PythonUI_namedpipe_Init();
#endif

#if defined(__Mac)
    if ( listen_to_apple_events ) {
	install_apple_event_handlers();
	install_mac_timer();
	setup_cocoa_app();

	
	// WARNING: See declaration of RunApplicationEventLoop() above as to
	// why you might not want to call that function anymore.
	// RunApplicationEventLoop();
	
    } else
#endif
    if ( doopen || !any )
	_FVMenuOpen(NULL);
    GDrawEventLoop(NULL);
    GDrawDestroyDisplays();

#ifndef _NO_PYTHON
/*# ifndef GWW_TEST*/
    FontForge_FinalizeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */
/*# endif*/
#endif

    // These free menu translations, mostly.
    BitmapViewFinishNonStatic();
    MetricsViewFinishNonStatic();
    CharViewFinishNonStatic();
    FontViewFinishNonStatic();

    ClearImageCache(); // This frees the contents of imagecache.
    hotkeysSave();
    LastFonts_Save();

#ifndef _NO_LIBUNICODENAMES
    uninm_names_db_close(names_db);	/* close this database before exiting */
    uninm_blocks_db_close(blocks_db);
#endif

    lt_dlexit();

return( 0 );
}