diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-08-12 04:09:57 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-08-12 04:09:57 +0400 |
commit | 44e4c5f8316b34835c7900dc649bf8a1570afc0a (patch) | |
tree | 99027196ffd166c78c336126d36c36bbc1621a29 /source/blender/windowmanager | |
parent | 8a340981be174cae842d339f0458ba6b558330c3 (diff) | |
parent | 0682c3f1aefe315df5fe64ba8c814adacbd739e5 (diff) |
Merged changes in the trunk up to revision 49797.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 67 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 7 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 16 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 49 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_playanim.c | 1136 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_subwindow.c | 8 |
10 files changed, 1262 insertions, 34 deletions
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 7f7321f6f29..c7546196af8 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -54,6 +54,7 @@ set(INC_SYS set(SRC intern/wm.c + intern/wm_playanim.c intern/wm_cursors.c intern/wm_dragdrop.c intern/wm_draw.c diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 60efc3b3541..ee7b44fb1e9 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -208,6 +208,8 @@ void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring void WM_operator_properties_create_ptr(struct PointerRNA *ptr, struct wmOperatorType *ot); void WM_operator_properties_free(struct PointerRNA *ptr); void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type, short action, short flag, short display); +void WM_operator_properties_border(struct wmOperatorType *ot); +void WM_operator_properties_border_to_rcti(struct wmOperator *op, struct rcti *rect); void WM_operator_properties_gesture_border(struct wmOperatorType *ot, int extend); void WM_operator_properties_mouse_select(struct wmOperatorType *ot); void WM_operator_properties_gesture_straightline(struct wmOperatorType *ot, int cursor); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 72d2bf9d1f1..bcba7a76ec8 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -28,6 +28,73 @@ * \ingroup wm */ +/* + * Overview of WM structs + * ====================== + * + * > wmWindowManager (window manager stores a list of windows) + * > > wmWindow (window has an active screen) + * > > > bScreen (link to ScrAreas via 'areabase') + * > > > > ScrArea (stores multiple spaces via space links via 'spacedata') + * > > > > > SpaceLink (base struct for space data for all different space types) + * > > > > ScrArea (stores multiple regions via 'regionbase') + * > > > > > ARegion + * + * + * Window Layout + * ============= + * + * wmWindow -> bScreen + * +----------------------------------------------------------+ + * |+-----------------------------------------+-------------+ | + * ||ScrArea (links to 3D view) |ScrArea | | + * ||+-------++----------+-------------------+|(links to | | + * |||ARegion|| |ARegion (quad view)|| properties) | | + * |||(tools)|| | || | | + * ||| || | || | | + * ||| || | || | | + * ||| || | || | | + * ||| |+----------+-------------------+| | | + * ||| || | || | | + * ||| || | || | | + * ||| || | || | | + * ||| || | || | | + * ||| || | || | | + * ||+-------++----------+-------------------+| | | + * |+-----------------------------------------+-------------+ | + * +----------------------------------------------------------+ + * + * + * Space Data + * ========== + * + * ScrArea's store a list of space data (SpaceLinks), each of unique type. + * The first one is the displayed in the UI, others are added as needed. + * + * +----------------------------+ <-- sa->spacedata.first; + * | | + * | |---+ <-- other inactive SpaceLink's stored. + * | | | + * | | |---+ + * | | | | + * | | | | + * | | | | + * | | | | + * +----------------------------+ | | + * | | | + * +-----------------------------+ | + * | | + * +------------------------------+ + * + * A common way to get the space from the ScrArea: + * + * if (sa->spacetype == SPACE_VIEW3D) { + * View3D *v3d = sa->spacedata.first; + * ... + * } + * + */ + #ifndef __WM_TYPES_H__ #define __WM_TYPES_H__ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 8652870e280..66bb321e832 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -45,10 +45,11 @@ #include "BLI_utildefines.h" #include "BLI_math_base.h" +#include "BIF_gl.h" + #include "BKE_context.h" #include "BKE_global.h" - #include "GHOST_C-api.h" #include "ED_screen.h" @@ -505,8 +506,8 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) /* wmOrtho for the screen has this same offset */ ratiox = sizex; ratioy = sizey; - halfx = 0.375f; - halfy = 0.375f; + halfx = GLA_PIXEL_OFS; + halfy = GLA_PIXEL_OFS; /* texture rectangle has unnormalized coordinates */ if (triple->target == GL_TEXTURE_2D) { diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2c641b217a8..e3ad425d0f8 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -242,7 +242,7 @@ void wm_event_do_notifiers(bContext *C) /* XXX, quick frame changes can cause a crash if framechange and rendering * collide (happens on slow scenes), BKE_scene_update_for_newframe can be called * twice which can depgraph update the same object at once */ - if (!G.rendering) { + if (G.is_rendering == FALSE) { /* depsgraph gets called, might send more notifiers */ ED_update_for_newframe(CTX_data_main(C), win->screen->scene, 1); @@ -301,7 +301,7 @@ void wm_event_do_notifiers(bContext *C) } /* XXX make lock in future, or separated derivedmesh users in scene */ - if (!G.rendering) { + if (G.is_rendering == FALSE) { /* depsgraph & animation: update tagged datablocks */ Main *bmain = CTX_data_main(C); @@ -2906,7 +2906,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U /* if test_break set, it catches this. XXX Keep global for now? */ if (event.type == ESCKEY) - G.afbreek = 1; + G.is_break = TRUE; wm_event_add(win, &event); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 04035598a89..36e2cbae296 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -382,6 +382,8 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports) /* assume automated tasks with background, don't write recent file list */ const int do_history = (G.background == FALSE) && (CTX_wm_manager(C)->op_undo_depth == 0); + BKE_vfont_free_global_ttf(); + /* put aside screens to match with persistent windows later */ /* also exit screens and editors */ wm_window_match_init(C, &wmbase); @@ -492,7 +494,7 @@ int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory char tstr[FILE_MAX]; int success = 0; - BKE_vfont_free_global_ttf(); /* still weird... what does it here? */ + BKE_vfont_free_global_ttf(); G.relbase_valid = 0; if (!from_memory) { diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 5bf6c34cfb3..8ea644d6e5c 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -58,6 +58,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_mball.h" +#include "BKE_node.h" #include "BKE_report.h" #include "BKE_packedFile.h" @@ -334,10 +335,10 @@ static void free_openrecent(void) /* bad stuff*/ // XXX copy/paste buffer stuff... -extern void free_anim_copybuf(void); -extern void free_anim_drivers_copybuf(void); -extern void free_fmodifiers_copybuf(void); -extern void free_posebuf(void); +extern void free_anim_copybuf(void); +extern void free_anim_drivers_copybuf(void); +extern void free_fmodifiers_copybuf(void); +extern void free_posebuf(void); #if WIN32 /* Read console events until there is a key event. Also returns on any error. */ @@ -346,7 +347,7 @@ static void wait_for_console_key(void) HANDLE hConsoleInput = GetStdHandle(STD_INPUT_HANDLE); if (!ELEM(hConsoleInput, NULL, INVALID_HANDLE_VALUE) && FlushConsoleInputBuffer(hConsoleInput)) { - for(;;) { + for (;;) { INPUT_RECORD buffer; DWORD ignored; @@ -410,7 +411,7 @@ void WM_exit_ext(bContext *C, const short do_python) if (C && CTX_wm_manager(C)) wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */ - seq_free_clipboard(); /* sequencer.c */ + BKE_sequencer_free_clipboard(); /* sequencer.c */ BKE_tracking_clipboard_free(); free_blender(); /* blender.c, does entire library and spacetypes */ @@ -419,6 +420,7 @@ void WM_exit_ext(bContext *C, const short do_python) free_anim_drivers_copybuf(); free_fmodifiers_copybuf(); free_posebuf(); + BKE_node_clipboard_clear(); BLF_exit(); @@ -495,5 +497,5 @@ void WM_exit_ext(bContext *C, const short do_python) void WM_exit(bContext *C) { WM_exit_ext(C, 1); - exit(G.afbreek == 1); + exit(G.is_break == TRUE); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a55efc0b216..52436b6564c 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -906,16 +906,31 @@ void WM_operator_properties_select_all(wmOperatorType *ot) RNA_def_enum(ot->srna, "action", select_all_actions, SEL_TOGGLE, "Action", "Selection action to execute"); } -void WM_operator_properties_gesture_border(wmOperatorType *ot, int extend) +void WM_operator_properties_border(wmOperatorType *ot) { - RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); +} + +void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect) +{ + rect->xmin = RNA_int_get(op->ptr, "xmin"); + rect->ymin = RNA_int_get(op->ptr, "ymin"); + rect->xmax = RNA_int_get(op->ptr, "xmax"); + rect->ymax = RNA_int_get(op->ptr, "ymax"); +} + +void WM_operator_properties_gesture_border(wmOperatorType *ot, int extend) +{ + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); + + WM_operator_properties_border(ot); - if (extend) + if (extend) { RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); + } } void WM_operator_properties_mouse_select(wmOperatorType *ot) @@ -1194,7 +1209,7 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op) static int wm_debug_menu_exec(bContext *C, wmOperator *op) { - G.rt = RNA_int_get(op->ptr, "debug_value"); + G.debug_value = RNA_int_get(op->ptr, "debug_value"); ED_screen_refresh(CTX_wm_manager(C), CTX_wm_window(C)); WM_event_add_notifier(C, NC_WINDOW, NULL); @@ -1203,7 +1218,7 @@ static int wm_debug_menu_exec(bContext *C, wmOperator *op) static int wm_debug_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - RNA_int_set(op->ptr, "debug_value", G.rt); + RNA_int_set(op->ptr, "debug_value", G.debug_value); return WM_operator_props_dialog_popup(C, op, 9 * UI_UNIT_X, UI_UNIT_Y); } @@ -1862,9 +1877,9 @@ static void WM_OT_link_append(wmOperatorType *ot) ot->flag |= OPTYPE_UNDO; WM_operator_properties_filesel( - ot, FOLDERFILE | BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, - WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES, - FILE_DEFAULTDISPLAY); + ot, FOLDERFILE | BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES, + FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending"); RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects"); @@ -1945,20 +1960,21 @@ static void WM_OT_recover_auto_save(wmOperatorType *ot) ot->invoke = wm_recover_auto_save_invoke; ot->poll = WM_operator_winactive; - WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_LONGDISPLAY); + WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_LONGDISPLAY); } /* *************** save file as **************** */ -static void untitled(char *name) +static void untitled(char *filepath) { - if (G.save_over == 0 && strlen(name) < FILE_MAX - 16) { - char *c = BLI_last_slash(name); + if (G.save_over == 0 && strlen(filepath) < FILE_MAX - 16) { + char *c = BLI_last_slash(filepath); if (c) strcpy(&c[1], "untitled.blend"); else - strcpy(name, "untitled.blend"); + strcpy(filepath, "untitled.blend"); } } @@ -2065,8 +2081,8 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) ot->check = blend_save_check; /* ommit window poll so this can work in background mode */ - WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, - FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative", "Remap relative paths when saving in a different directory"); @@ -2137,7 +2153,8 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) ot->check = blend_save_check; /* ommit window poll so this can work in background mode */ - WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory"); } diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c new file mode 100644 index 00000000000..3c791cb6e5d --- /dev/null +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -0,0 +1,1136 @@ +/* + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/intern/wm_playanim.c + * \ingroup wm + * + * \note This file uses ghost directly and none of the WM definitions. + * this could be made into its own module, alongside creator/ + */ + +#include <sys/types.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#ifndef WIN32 +# include <unistd.h> +# include <sys/times.h> +# include <sys/wait.h> +#else +# include <io.h> +#endif +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" +#include "BLI_rect.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BKE_blender.h" +#include "BKE_global.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#ifdef WITH_QUICKTIME +# ifdef _WIN32 +# include <QTML.h> +# include <Movies.h> +# elif defined(__APPLE__) +# include <QuickTime/Movies.h> +# endif /* __APPLE__ */ +#endif /* WITH_QUICKTIME */ + +#include "DNA_scene_types.h" +#include "BLI_utildefines.h" +#include "ED_datafiles.h" /* for fonts */ +#include "wm_event_types.h" +#include "GHOST_C-api.h" +#include "BLF_api.h" + + +typedef struct PlayState { + + /* playback state */ + short direction; + short next; + short once; + short turbo; + short pingpong; + short noskip; + short sstep; + short pause; + short wait2; + short stopped; + short go; + + /* current picture */ + struct PlayAnimPict *picture; + + /* set once at the start */ + int ibufx, ibufy; + int fontid; + + /* saves passing args */ + struct ImBuf *curframe_ibuf; +} PlayState; + +/* for debugging */ +#if 0 +void print_ps(PlayState *ps) +{ + printf("ps:\n"); + printf(" direction=%d,\n", (int)ps->direction); + printf(" next=%d,\n", ps->next); + printf(" once=%d,\n", ps->once); + printf(" turbo=%d,\n", ps->turbo); + printf(" pingpong=%d,\n", ps->pingpong); + printf(" noskip=%d,\n", ps->noskip); + printf(" sstep=%d,\n", ps->sstep); + printf(" pause=%d,\n", ps->pause); + printf(" wait2=%d,\n", ps->wait2); + printf(" stopped=%d,\n", ps->stopped); + printf(" go=%d,\n\n", ps->go); + fflush(stdout); +} +#endif + +/* global for window and events */ +typedef enum eWS_Qual { + WS_QUAL_LSHIFT = (1 << 0), + WS_QUAL_RSHIFT = (1 << 1), + WS_QUAL_SHIFT = (WS_QUAL_LSHIFT | WS_QUAL_RSHIFT), + WS_QUAL_LALT = (1 << 2), + WS_QUAL_RALT = (1 << 3), + WS_QUAL_ALT = (WS_QUAL_LALT | WS_QUAL_RALT), + WS_QUAL_LCTRL = (1 << 4), + WS_QUAL_RCTRL = (1 << 5), + WS_QUAL_LMOUSE = (1 << 16), + WS_QUAL_MMOUSE = (1 << 17), + WS_QUAL_RMOUSE = (1 << 18), + WS_QUAL_MOUSE = (WS_QUAL_LMOUSE | WS_QUAL_MMOUSE | WS_QUAL_RMOUSE) +} eWS_Qual; + +static struct WindowStateGlobal { + GHOST_SystemHandle ghost_system; + void *ghost_window; + + /* events */ + eWS_Qual qual; +} g_WS = {NULL}; + +void playanim_window_get_size(int *width_r, int *height_r) +{ + GHOST_RectangleHandle bounds = GHOST_GetClientBounds(g_WS.ghost_window); + *width_r = GHOST_GetWidthRectangle(bounds); + *height_r = GHOST_GetHeightRectangle(bounds); + GHOST_DisposeRectangle(bounds); +} + +/* implementation */ +static void playanim_event_qual_update(void) +{ + int val; + + /* Shift */ + GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyLeftShift, &val); + if (val) g_WS.qual |= WS_QUAL_LSHIFT; + else g_WS.qual &= ~WS_QUAL_LSHIFT; + + GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyRightShift, &val); + if (val) g_WS.qual |= WS_QUAL_RSHIFT; + else g_WS.qual &= ~WS_QUAL_RSHIFT; + + /* Control */ + GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyLeftControl, &val); + if (val) g_WS.qual |= WS_QUAL_LCTRL; + else g_WS.qual &= ~WS_QUAL_LCTRL; + + GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyRightControl, &val); + if (val) g_WS.qual |= WS_QUAL_RCTRL; + else g_WS.qual &= ~WS_QUAL_RCTRL; + + /* Alt */ + GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyLeftAlt, &val); + if (val) g_WS.qual |= WS_QUAL_LCTRL; + else g_WS.qual &= ~WS_QUAL_LCTRL; + + GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyRightAlt, &val); + if (val) g_WS.qual |= WS_QUAL_RCTRL; + else g_WS.qual &= ~WS_QUAL_RCTRL; + + /* LMB */ + GHOST_GetButtonState(g_WS.ghost_system, GHOST_kButtonMaskLeft, &val); + if (val) g_WS.qual |= WS_QUAL_LMOUSE; + else g_WS.qual &= ~WS_QUAL_LMOUSE; + + /* MMB */ + GHOST_GetButtonState(g_WS.ghost_system, GHOST_kButtonMaskMiddle, &val); + if (val) g_WS.qual |= WS_QUAL_MMOUSE; + else g_WS.qual &= ~WS_QUAL_MMOUSE; + + /* RMB */ + GHOST_GetButtonState(g_WS.ghost_system, GHOST_kButtonMaskRight, &val); + if (val) g_WS.qual |= WS_QUAL_RMOUSE; + else g_WS.qual &= ~WS_QUAL_RMOUSE; +} + +typedef struct PlayAnimPict { + struct PlayAnimPict *next, *prev; + char *mem; + int size; + char *name; + struct ImBuf *ibuf; + struct anim *anim; + int frame; + int IB_flags; +} PlayAnimPict; + +static struct ListBase picsbase = {NULL, NULL}; +static int fromdisk = FALSE; +static int fstep = 1; +static float zoomx = 1.0, zoomy = 1.0; +static double ptottime = 0.0, swaptime = 0.04; + +static int pupdate_time(void) +{ + static double ltime; + double time; + + time = PIL_check_seconds_timer(); + + ptottime += (time - ltime); + ltime = time; + return (ptottime < 0); +} + +static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid) +{ + + if (ibuf == NULL) { + printf("no ibuf !\n"); + return; + } + if (ibuf->rect == NULL && ibuf->rect_float) { + IMB_rect_from_float(ibuf); + imb_freerectfloatImBuf(ibuf); + } + if (ibuf->rect == NULL) + return; + + GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); + + glRasterPos2f(0.0f, 0.0f); + + glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + + pupdate_time(); + + if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) { + int sizex, sizey; + float fsizex_inv, fsizey_inv; + char str[32 + FILE_MAX]; + cpack(-1); + BLI_snprintf(str, sizeof(str), "%s | %.2f frames/s", picture->name, fstep / swaptime); + + playanim_window_get_size(&sizex, &sizey); + fsizex_inv = 1.0f / sizex; + fsizey_inv = 1.0f / sizey; + + BLF_enable(fontid, BLF_ASPECT); + BLF_aspect(fontid, fsizex_inv, fsizey_inv, 1.0f); + BLF_position(fontid, 10.0f * fsizex_inv, 10.0f * fsizey_inv, 0.0f); + BLF_draw(fontid, str, sizeof(str)); + } + + GHOST_SwapWindowBuffers(g_WS.ghost_window); +} + +static void build_pict_list(char *first, int totframes, int fstep, int fontid) +{ + char *mem, filepath[FILE_MAX]; +// short val; + PlayAnimPict *picture = NULL; + struct ImBuf *ibuf = NULL; + char str[32 + FILE_MAX]; + struct anim *anim; + + if (IMB_isanim(first)) { + anim = IMB_open_anim(first, IB_rect, 0); + if (anim) { + int pic; + ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); + if (ibuf) { + playanim_toscreen(NULL, ibuf, fontid); + IMB_freeImBuf(ibuf); + } + + for (pic = 0; pic < IMB_anim_get_duration(anim, IMB_TC_NONE); pic++) { + picture = (PlayAnimPict *)MEM_callocN(sizeof(PlayAnimPict), "Pict"); + picture->anim = anim; + picture->frame = pic; + picture->IB_flags = IB_rect; + BLI_snprintf(str, sizeof(str), "%s : %4.d", first, pic + 1); + picture->name = strdup(str); + BLI_addtail(&picsbase, picture); + } + } + else { + printf("couldn't open anim %s\n", first); + } + } + else { + int count = 0; + + BLI_strncpy(filepath, first, sizeof(filepath)); + + pupdate_time(); + ptottime = 1.0; + + /* O_DIRECT + * + * If set, all reads and writes on the resulting file descriptor will + * be performed directly to or from the user program buffer, provided + * appropriate size and alignment restrictions are met. Refer to the + * F_SETFL and F_DIOINFO commands in the fcntl(2) manual entry for + * information about how to determine the alignment constraints. + * O_DIRECT is a Silicon Graphics extension and is only supported on + * local EFS and XFS file systems. + */ + + while (IMB_ispic(filepath) && totframes) { + size_t size; + int file; + + file = open(filepath, O_BINARY | O_RDONLY, 0); + if (file < 0) return; + picture = (PlayAnimPict *)MEM_callocN(sizeof(PlayAnimPict), "picture"); + if (picture == NULL) { + printf("Not enough memory for pict struct '%s'\n", filepath); + close(file); + return; + } + size = BLI_file_descriptor_size(file); + + if (size < 1) { + close(file); + MEM_freeN(picture); + return; + } + + picture->size = size; + picture->IB_flags = IB_rect; + + if (fromdisk == FALSE) { + mem = (char *)MEM_mallocN(size, "build pic list"); + if (mem == NULL) { + printf("Couldn't get memory\n"); + close(file); + MEM_freeN(picture); + return; + } + + if (read(file, mem, size) != size) { + printf("Error while reading %s\n", filepath); + close(file); + MEM_freeN(picture); + MEM_freeN(mem); + return; + } + } + else { + mem = NULL; + } + + picture->mem = mem; + picture->name = strdup(filepath); + close(file); + BLI_addtail(&picsbase, picture); + count++; + + pupdate_time(); + + if (ptottime > 1.0) { + if (picture->mem) { + ibuf = IMB_ibImageFromMemory((unsigned char *)picture->mem, picture->size, + picture->IB_flags, picture->name); + } + else { + ibuf = IMB_loadiffname(picture->name, picture->IB_flags); + } + if (ibuf) { + playanim_toscreen(picture, ibuf, fontid); + IMB_freeImBuf(ibuf); + } + pupdate_time(); + ptottime = 0.0; + } + + BLI_newname(filepath, +fstep); + +#if 0 // XXX25 + while (qtest()) { + switch (qreadN(&val)) { + case ESCKEY: + if (val) return; + break; + } + } +#endif + totframes--; + } + } + return; +} + +static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) +{ + PlayState *ps = (PlayState *)ps_void; + GHOST_TEventType type = GHOST_GetEventType(evt); + int val; + + // print_ps(ps); + + playanim_event_qual_update(); + + /* convert ghost event into value keyboard or mouse */ + val = ELEM(type, GHOST_kEventKeyDown, GHOST_kEventButtonDown); + + if (ps->wait2 && ps->stopped) { + ps->stopped = FALSE; + } + + switch (type) { + case GHOST_kEventKeyDown: + case GHOST_kEventKeyUp: + { + GHOST_TEventKeyData *key_data; + + key_data = (GHOST_TEventKeyData *)GHOST_GetEventData(evt); + switch (key_data->key) { + case GHOST_kKeyA: + if (val) ps->noskip = !ps->noskip; + break; + case GHOST_kKeyP: + if (val) ps->pingpong = !ps->pingpong; + break; + case GHOST_kKeyNumpad1: + if (val) swaptime = fstep / 60.0; + break; + case GHOST_kKeyNumpad2: + if (val) swaptime = fstep / 50.0; + break; + case GHOST_kKeyNumpad3: + if (val) swaptime = fstep / 30.0; + break; + case GHOST_kKeyNumpad4: + if (g_WS.qual & WS_QUAL_SHIFT) + swaptime = fstep / 24.0; + else + swaptime = fstep / 25.0; + break; + case GHOST_kKeyNumpad5: + if (val) swaptime = fstep / 20.0; + break; + case GHOST_kKeyNumpad6: + if (val) swaptime = fstep / 15.0; + break; + case GHOST_kKeyNumpad7: + if (val) swaptime = fstep / 12.0; + break; + case GHOST_kKeyNumpad8: + if (val) swaptime = fstep / 10.0; + break; + case GHOST_kKeyNumpad9: + if (val) swaptime = fstep / 6.0; + break; + case GHOST_kKeyLeftArrow: + if (val) { + ps->sstep = TRUE; + ps->wait2 = FALSE; + if (g_WS.qual & WS_QUAL_SHIFT) { + ps->picture = picsbase.first; + ps->next = 0; + } + else { + ps->next = -1; + } + } + break; + case GHOST_kKeyDownArrow: + if (val) { + ps->wait2 = FALSE; + if (g_WS.qual & WS_QUAL_SHIFT) { + ps->next = ps->direction = -1; + } + else { + ps->next = -10; + ps->sstep = TRUE; + } + } + break; + case GHOST_kKeyRightArrow: + if (val) { + ps->sstep = TRUE; + ps->wait2 = FALSE; + if (g_WS.qual & WS_QUAL_SHIFT) { + ps->picture = picsbase.last; + ps->next = 0; + } + else { + ps->next = 1; + } + } + break; + case GHOST_kKeyUpArrow: + if (val) { + ps->wait2 = FALSE; + if (g_WS.qual & WS_QUAL_SHIFT) { + ps->next = ps->direction = 1; + } + else { + ps->next = 10; + ps->sstep = TRUE; + } + } + break; + + case GHOST_kKeySlash: + case GHOST_kKeyNumpadSlash: + if (val) { + if (g_WS.qual & WS_QUAL_SHIFT) { + if (ps->curframe_ibuf) + printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, fstep / swaptime); + } + else { + swaptime = fstep / 5.0; + } + } + break; + case GHOST_kKeyEqual: + if (val) { + if (g_WS.qual & WS_QUAL_SHIFT) { + ps->pause++; + printf("pause:%d\n", ps->pause); + } + else { + swaptime /= 1.1; + } + } + break; + case GHOST_kKeyMinus: + if (val) { + if (g_WS.qual & WS_QUAL_SHIFT) { + ps->pause--; + printf("pause:%d\n", ps->pause); + } + else { + swaptime *= 1.1; + } + } + break; + case GHOST_kKeyNumpad0: + if (val) { + if (ps->once) { + ps->once = ps->wait2 = FALSE; + } + else { + ps->picture = NULL; + ps->once = TRUE; + ps->wait2 = FALSE; + } + } + break; + case GHOST_kKeyEnter: + case GHOST_kKeyNumpadEnter: + if (val) { + ps->wait2 = ps->sstep = FALSE; + } + break; + case GHOST_kKeyNumpadPeriod: + if (val) { + if (ps->sstep) ps->wait2 = FALSE; + else { + ps->sstep = TRUE; + ps->wait2 = !ps->wait2; + } + } + break; + case GHOST_kKeyNumpadPlus: + if (val == 0) break; + zoomx += 2.0; + zoomy += 2.0; + /* no break??? - is this intentional? - campbell XXX25 */ + case GHOST_kKeyNumpadMinus: + { + int sizex, sizey; + /* int ofsx, ofsy; */ /* UNUSED */ + + if (val == 0) break; + if (zoomx > 1.0) zoomx -= 1.0; + if (zoomy > 1.0) zoomy -= 1.0; + // playanim_window_get_position(&ofsx, &ofsy); + playanim_window_get_size(&sizex, &sizey); + /* ofsx += sizex / 2; */ /* UNUSED */ + /* ofsy += sizey / 2; */ /* UNUSED */ + sizex = zoomx * ps->ibufx; + sizey = zoomy * ps->ibufy; + /* ofsx -= sizex / 2; */ /* UNUSED */ + /* ofsy -= sizey / 2; */ /* UNUSED */ + // window_set_position(g_WS.ghost_window,sizex,sizey); + GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey); + break; + } + case GHOST_kKeyEsc: + ps->go = FALSE; + break; + default: + break; + } + break; + } + case GHOST_kEventCursorMove: + { + if (g_WS.qual & WS_QUAL_LMOUSE) { + int sizex, sizey; + int i; + + GHOST_TEventCursorData *cd = GHOST_GetEventData(evt); + int cx, cy; + + GHOST_ScreenToClient(g_WS.ghost_window, cd->x, cd->y, &cx, &cy); + + playanim_window_get_size(&sizex, &sizey); + ps->picture = picsbase.first; + /* TODO - store in ps direct? */ + i = 0; + while (ps->picture) { + i++; + ps->picture = ps->picture->next; + } + i = (i * cx) / sizex; + ps->picture = picsbase.first; + for (; i > 0; i--) { + if (ps->picture->next == NULL) break; + ps->picture = ps->picture->next; + } + ps->sstep = TRUE; + ps->wait2 = FALSE; + ps->next = 0; + } + break; + } + case GHOST_kEventWindowSize: + case GHOST_kEventWindowMove: + { + int sizex, sizey; + + playanim_window_get_size(&sizex, &sizey); + GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); + + glViewport(0, 0, sizex, sizey); + glScissor(0, 0, sizex, sizey); + + zoomx = (float) sizex / ps->ibufx; + zoomy = (float) sizey / ps->ibufy; + zoomx = floor(zoomx + 0.5); + zoomy = floor(zoomy + 0.5); + if (zoomx < 1.0) zoomx = 1.0; + if (zoomy < 1.0) zoomy = 1.0; + + sizex = zoomx * ps->ibufx; + sizey = zoomy * ps->ibufy; + + glPixelZoom(zoomx, zoomy); + glEnable(GL_DITHER); + ptottime = 0.0; + playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid); + + break; + } + case GHOST_kEventQuit: + case GHOST_kEventWindowClose: + { + ps->go = FALSE; + break; + } + default: + /* quiet warnings */ + break; + } + + return 1; +} + +void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey, int start_maximized) +{ + GHOST_TWindowState inital_state; + GHOST_TUns32 scr_w, scr_h; + + GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &scr_w, &scr_h); + + posy = (scr_h - posy - sizey); + + if (start_maximized == G_WINDOWSTATE_FULLSCREEN) + inital_state = start_maximized ? GHOST_kWindowStateFullScreen : GHOST_kWindowStateNormal; + else + inital_state = start_maximized ? GHOST_kWindowStateMaximized : GHOST_kWindowStateNormal; +#if defined(__APPLE__) && !defined(GHOST_COCOA) + { + extern int macPrefState; /* creator.c */ + initial_state += macPrefState; + } +#endif + + g_WS.ghost_window = GHOST_CreateWindow(g_WS.ghost_system, + title, + posx, posy, sizex, sizey, + inital_state, + GHOST_kDrawingContextTypeOpenGL, + FALSE /* no stereo */, FALSE); + + //if (ghostwin) { + //if (win) { + // GHOST_SetWindowUserData(ghostwin, win); + //} else { + // GHOST_DisposeWindow(g_WS.ghost_system, ghostwin); + //} + //} +} + + +void playanim(int argc, const char **argv) +{ + struct ImBuf *ibuf = NULL; + char filepath[FILE_MAX]; + GHOST_TUns32 maxwinx, maxwiny; + /* short c233 = FALSE, yuvx = FALSE; */ /* UNUSED */ + int i; + /* This was done to disambiguate the name for use under c++. */ + struct anim *anim = NULL; + int start_x = 0, start_y = 0; + int sfra = -1; + int efra = -1; + int totblock; + + PlayState ps = {0}; + + /* ps.doubleb = TRUE;*/ /* UNUSED */ + ps.go = TRUE; + ps.direction = TRUE; + ps.next = TRUE; + ps.once = FALSE; + ps.turbo = FALSE; + ps.pingpong = FALSE; + ps.noskip = FALSE; + ps.sstep = FALSE; + ps.pause = FALSE; + ps.wait2 = FALSE; + ps.stopped = FALSE; + ps.picture = NULL; + /* resetmap = FALSE */ + + ps.fontid = -1; + + while (argc > 1) { + if (argv[1][0] == '-') { + switch (argv[1][1]) { + case 'm': + fromdisk = TRUE; + break; + case 'p': + if (argc > 3) { + start_x = atoi(argv[2]); + start_y = atoi(argv[3]); + argc -= 2; + argv += 2; + } + else { + printf("too few arguments for -p (need 2): skipping\n"); + } + break; + case 'f': + if (argc > 3) { + double fps = atof(argv[2]); + double fps_base = atof(argv[3]); + if (fps == 0.0) { + fps = 1; + printf("invalid fps," + "forcing 1\n"); + } + swaptime = fps_base / fps; + argc -= 2; + argv += 2; + } + else { + printf("too few arguments for -f (need 2): skipping\n"); + } + break; + case 's': + sfra = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]) )); + argc--; + argv++; + break; + case 'e': + efra = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]) )); + argc--; + argv++; + break; + case 'j': + fstep = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]))); + swaptime *= fstep; + argc--; + argv++; + break; + default: + printf("unknown option '%c': skipping\n", argv[1][1]); + break; + } + argc--; + argv++; + } + else { + break; + } + } + +#ifdef WITH_QUICKTIME +#if defined(_WIN32) || defined(__APPLE__) && !defined(GHOST_COCOA) + /* Initialize QuickTime */ +#ifndef noErr +#define noErr 0 +#endif + +#ifdef _WIN32 + if (InitializeQTML(0) != noErr) + G.have_quicktime = FALSE; + else + G.have_quicktime = TRUE; +#endif /* _WIN32 */ + if (EnterMovies() != noErr) + G.have_quicktime = FALSE; + else +#endif /* _WIN32 || __APPLE__ && !defined(GHOST_COCOA)*/ + G.have_quicktime = TRUE; +#endif /* WITH_QUICKTIME */ + + if (argc > 1) { + BLI_strncpy(filepath, argv[1], sizeof(filepath)); + } + else { + BLI_current_working_dir(filepath, sizeof(filepath)); + BLI_add_slash(filepath); + } + + if (IMB_isanim(filepath)) { + anim = IMB_open_anim(filepath, IB_rect, 0); + if (anim) { + ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); + IMB_close_anim(anim); + anim = NULL; + } + } + else if (!IMB_ispic(filepath)) { + exit(1); + } + + if (ibuf == NULL) { + ibuf = IMB_loadiffname(filepath, IB_rect); + } + + if (ibuf == NULL) { + printf("couldn't open %s\n", filepath); + exit(1); + } + +#if 0 //XXX25 + #if !defined(WIN32) && !defined(__APPLE__) + if (fork()) exit(0); + #endif +#endif //XXX25 + + /* XXX, fixme zr */ + { +// extern void add_to_mainqueue(wmWindow *win, void *user_data, short evt, short val, char ascii); + + GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, &ps); + + g_WS.ghost_system = GHOST_CreateSystem(); + GHOST_AddEventConsumer(g_WS.ghost_system, consumer); + + + + playanim_window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y, 0); +//XXX25 window_set_handler(g_WS.ghost_window, add_to_mainqueue, NULL); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + glMatrixMode(GL_MODELVIEW); + } + + GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &maxwinx, &maxwiny); + + //GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); + + /* initialize the font */ + BLF_init(11, 72); + ps.fontid = BLF_load_mem("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); + BLF_size(ps.fontid, 11, 72); + + ps.ibufx = ibuf->x; + ps.ibufy = ibuf->y; + + if (maxwinx % ibuf->x) maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x)); + if (maxwiny % ibuf->y) maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y)); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + GHOST_SwapWindowBuffers(g_WS.ghost_window); + + if (sfra == -1 || efra == -1) { + /* one of the frames was invalid, just use all images */ + sfra = 1; + efra = MAXFRAME; + } + + build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + + for (i = 2; i < argc; i++) { + BLI_strncpy(filepath, argv[i], sizeof(filepath)); + build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + } + + IMB_freeImBuf(ibuf); + ibuf = NULL; + + pupdate_time(); + ptottime = 0; + + /* newly added in 2.6x, without this images never get freed */ +#define USE_IMB_CACHE + + while (ps.go) { + if (ps.pingpong) + ps.direction = -ps.direction; + + if (ps.direction == 1) { + ps.picture = picsbase.first; + } + else { + ps.picture = picsbase.last; + } + + if (ps.picture == NULL) { + printf("couldn't find pictures\n"); + ps.go = FALSE; + } + if (ps.pingpong) { + if (ps.direction == 1) { + ps.picture = ps.picture->next; + } + else { + ps.picture = ps.picture->prev; + } + } + if (ptottime > 0.0) ptottime = 0.0; + + while (ps.picture) { +#ifndef USE_IMB_CACHE + if (ibuf != NULL && ibuf->ftype == 0) IMB_freeImBuf(ibuf); +#endif + if (ps.picture->ibuf) { + ibuf = ps.picture->ibuf; + } + else if (ps.picture->anim) { + ibuf = IMB_anim_absolute(ps.picture->anim, ps.picture->frame, IMB_TC_NONE, IMB_PROXY_NONE); + } + else if (ps.picture->mem) { + ibuf = IMB_ibImageFromMemory((unsigned char *) ps.picture->mem, ps.picture->size, + ps.picture->IB_flags, ps.picture->name); + } + else { + ibuf = IMB_loadiffname(ps.picture->name, ps.picture->IB_flags); + } + + if (ibuf) { + +#ifdef USE_IMB_CACHE + ps.picture->ibuf = ibuf; +#endif + + BLI_strncpy(ibuf->name, ps.picture->name, sizeof(ibuf->name)); + + /* why only windows? (from 2.4x) - campbell */ +#ifdef _WIN32 + GHOST_SetTitle(g_WS.ghost_window, ps.picture->name); +#endif + + while (pupdate_time()) PIL_sleep_ms(1); + ptottime -= swaptime; + playanim_toscreen(ps.picture, ibuf, ps.fontid); + } /* else deleten */ + else { + printf("error: can't play this image type\n"); + exit(0); + } + + if (ps.once) { + if (ps.picture->next == NULL) { + ps.wait2 = TRUE; + } + else if (ps.picture->prev == NULL) { + ps.wait2 = TRUE; + } + } + + ps.next = ps.direction; + + + { + int hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0); + if (hasevent) { + GHOST_DispatchEvents(g_WS.ghost_system); + } + } + + /* XXX25 - we should not have to do this, but it makes scrubbing functional! */ + if (g_WS.qual & WS_QUAL_LMOUSE) { + ps.next = 0; + } + else { + ps.sstep = 0; + } + + ps.wait2 = ps.sstep; + + if (ps.wait2 == 0 && ps.stopped == 0) { + ps.stopped = TRUE; + } + + pupdate_time(); + + if (ps.picture && ps.next) { + /* always at least set one step */ + while (ps.picture) { + if (ps.next < 0) { + ps.picture = ps.picture->prev; + } + else { + ps.picture = ps.picture->next; + } + + if (ps.once && ps.picture != NULL) { + if (ps.picture->next == NULL) { + ps.wait2 = TRUE; + } + else if (ps.picture->prev == NULL) { + ps.wait2 = TRUE; + } + } + + if (ps.wait2 || ptottime < swaptime || ps.turbo || ps.noskip) break; + ptottime -= swaptime; + } + if (ps.picture == NULL && ps.sstep) { + if (ps.next < 0) { + ps.picture = picsbase.last; + } + else if (ps.next > 0) { + ps.picture = picsbase.first; + } + } + } + if (ps.go == FALSE) { + break; + } + } + } + ps.picture = picsbase.first; + anim = NULL; + while (ps.picture) { + if (ps.picture && ps.picture->anim && (anim != ps.picture->anim)) { + // to prevent divx crashes + anim = ps.picture->anim; + IMB_close_anim(anim); + } + + if (ps.picture->ibuf) { + IMB_freeImBuf(ps.picture->ibuf); + } + if (ps.picture->mem) { + MEM_freeN(ps.picture->mem); + } + + ps.picture = ps.picture->next; + } +#ifdef WITH_QUICKTIME +#if defined(_WIN32) || defined(__APPLE__) && !defined(GHOST_COCOA) + if (G.have_quicktime) { + ExitMovies(); +#ifdef _WIN32 + TerminateQTML(); +#endif /* _WIN32 */ + } +#endif /* _WIN32 || __APPLE__ && !defined(GHOST_COCOA) */ +#endif /* WITH_QUICKTIME */ + + /* cleanup */ +#ifndef USE_IMB_CACHE + if (ibuf) IMB_freeImBuf(ibuf); +#endif + + BLI_freelistN(&picsbase); +#if 0 // XXX25 + free_blender(); +#else + /* we still miss freeing a lot!, + * but many areas could skip initialization too for anim play */ + IMB_exit(); + BLF_exit(); +#endif + GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window); + + totblock = MEM_get_memory_blocks_in_use(); + if (totblock != 0) { + /* prints many bAKey, bArgument's which are tricky to fix */ +#if 0 + printf("Error Totblock: %d\n", totblock); + MEM_printmemlist(); +#endif + } +} diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 0b9dc441227..529910d220e 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -141,7 +141,7 @@ void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]) int width, height; wm_subwindow_getsize(win, swin->swinid, &width, &height); - orthographic_m4(mat, -0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f, -100, 100); + orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100); } else glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat); @@ -175,7 +175,7 @@ int wm_subwindow_open(wmWindow *win, rcti *winrct) /* extra service */ wm_subwindow_getsize(win, swin->swinid, &width, &height); - wmOrtho2(-0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f); + wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS); glLoadIdentity(); return swin->swinid; @@ -229,7 +229,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct) /* extra service */ wmSubWindowSet(win, swinid); wm_subwindow_getsize(win, swinid, &width, &height); - wmOrtho2(-0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f); + wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS); } else { printf("%s: Internal error, bad winid: %d\n", __func__, swinid); @@ -268,7 +268,7 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) else glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); - wmOrtho2(-0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f); + wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS); glLoadIdentity(); glFlush(); |