This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/blenkernel/intern/blender.c

284 lines
5.9 KiB
C

/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/blender.c
* \ingroup bke
*
* Application level startup/shutdown functionality.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "BLI_callbacks.h"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
#include "BKE_blender.h" /* own include */
#include "BKE_blender_version.h" /* own include */
#include "BKE_blendfile.h"
#include "BKE_brush.h"
#include "BKE_cachefile.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "RE_pipeline.h"
#include "RE_render_ext.h"
#include "BLF_api.h"
Global G;
UserDef U;
char versionstr[48] = "";
/* ********** free ********** */
/* only to be called on exit blender */
void BKE_blender_free(void)
{
/* samples are in a global list..., also sets G.main->sound->sample NULL */
BKE_main_free(G.main);
G.main = NULL;
BKE_spacetypes_free(); /* after free main, it uses space callbacks */
IMB_exit();
BKE_cachefiles_exit();
BKE_images_exit();
DAG_exit();
BKE_brush_system_exit();
RE_texture_rng_exit();
BLI_callback_global_finalize();
BKE_sequencer_cache_destruct();
IMB_moviecache_destruct();
free_nodesystem();
}
void BKE_blender_globals_init(void)
{
memset(&G, 0, sizeof(Global));
U.savetime = 1;
G.main = BKE_main_new();
strcpy(G.ima, "//");
if (BLENDER_SUBVERSION)
BLI_snprintf(versionstr, sizeof(versionstr), "v%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
else
BLI_snprintf(versionstr, sizeof(versionstr), "v%d.%02d", BLENDER_VERSION / 100, BLENDER_VERSION % 100);
#ifndef WITH_PYTHON_SECURITY /* default */
G.f |= G_SCRIPT_AUTOEXEC;
#else
G.f &= ~G_SCRIPT_AUTOEXEC;
#endif
}
void BKE_blender_globals_clear(void)
{
BKE_main_free(G.main); /* free all lib data */
G.main = NULL;
}
/***/
static void keymap_item_free(wmKeyMapItem *kmi)
{
if (kmi->properties) {
IDP_FreeProperty(kmi->properties);
MEM_freeN(kmi->properties);
}
if (kmi->ptr)
MEM_freeN(kmi->ptr);
}
/**
* When loading a new userdef from file,
* or when exiting Blender.
*/
void BKE_blender_userdef_free(void)
{
wmKeyMap *km;
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
bAddon *addon, *addon_next;
uiFont *font;
for (km = U.user_keymaps.first; km; km = km->next) {
for (kmdi = km->diff_items.first; kmdi; kmdi = kmdi->next) {
if (kmdi->add_item) {
keymap_item_free(kmdi->add_item);
MEM_freeN(kmdi->add_item);
}
if (kmdi->remove_item) {
keymap_item_free(kmdi->remove_item);
MEM_freeN(kmdi->remove_item);
}
}
for (kmi = km->items.first; kmi; kmi = kmi->next)
keymap_item_free(kmi);
BLI_freelistN(&km->diff_items);
BLI_freelistN(&km->items);
}
for (addon = U.addons.first; addon; addon = addon_next) {
addon_next = addon->next;
if (addon->prop) {
IDP_FreeProperty(addon->prop);
MEM_freeN(addon->prop);
}
MEM_freeN(addon);
}
for (font = U.uifonts.first; font; font = font->next) {
BLF_unload_id(font->blf_id);
}
BLF_default_set(-1);
BLI_freelistN(&U.autoexec_paths);
BLI_freelistN(&U.uistyles);
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
BLI_freelistN(&U.user_keymaps);
}
/**
* Handle changes in settings that need refreshing.
*/
void BKE_blender_userdef_refresh(void)
{
/* prevent accidents */
if (U.pixelsize == 0) U.pixelsize = 1;
BLF_default_dpi(U.pixelsize * U.dpi);
U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
}
/* ***************** testing for break ************* */
static void (*blender_test_break_cb)(void) = NULL;
void BKE_blender_callback_test_break_set(void (*func)(void))
{
blender_test_break_cb = func;
}
int BKE_blender_test_break(void)
{
if (!G.background) {
if (blender_test_break_cb)
blender_test_break_cb();
}
return (G.is_break == true);
}
/** \name Blender's AtExit
*
* \note Don't use MEM_mallocN so functions can be registered at any time.
* \{ */
struct AtExitData {
struct AtExitData *next;
void (*func)(void *user_data);
void *user_data;
} *g_atexit = NULL;
void BKE_blender_atexit_register(void (*func)(void *user_data), void *user_data)
{
struct AtExitData *ae = malloc(sizeof(*ae));
ae->next = g_atexit;
ae->func = func;
ae->user_data = user_data;
g_atexit = ae;
}
void BKE_blender_atexit_unregister(void (*func)(void *user_data), const void *user_data)
{
struct AtExitData *ae = g_atexit;
struct AtExitData **ae_p = &g_atexit;
while (ae) {
if ((ae->func == func) && (ae->user_data == user_data)) {
*ae_p = ae->next;
free(ae);
return;
}
ae_p = &ae;
ae = ae->next;
}
}
void BKE_blender_atexit(void)
{
struct AtExitData *ae = g_atexit, *ae_next;
while (ae) {
ae_next = ae->next;
ae->func(ae->user_data);
free(ae);
ae = ae_next;
}
g_atexit = NULL;
}
/** \} */