/**************************************************************************** * pvengine.c * * This module implements Windows specific routines. * * Copyright © POV-Team(tm) 1996-1998. All Rights Reserved. * This windows version of POV-Ray is Copyright 1996-1998 Christopher J. Cason. * Authors : Christopher J. Cason and Kendall Bennett (palette/display code). * * NOTE : As this is Windows code, it was edited using a wide Windows-hosted * editor. Accordingly, expect text to exceed 80 columns regularly. * * from Persistence of Vision Raytracer(tm) * Copyright 1996-1998 Persistence of Vision Team * * The terms POV-Ray, POV, and Persistence of Vision Raytracer are trademarks * of the Persistence of Vision Team. *--------------------------------------------------------------------------- * NOTICE: This source code file is provided so that users may experiment * with enhancements to POV-Ray(tm) and to port the software to platforms other * than those supported by the POV-Ray Team. There are strict rules under * which you are permitted to use this file. The rules are in the file * named POVLEGAL.DOC which should be distributed with this file. If * POVLEGAL.DOC is not available or for more info please contact the POV-Ray(tm) * Team Coordinator by leaving a message in CompuServe's POVRAY forum. The * The latest version of POV-Ray may be found there as well. POVRAY files can * also be found on the world wide web at http://www.povray.org/. * * In the case of this particular program, POVLEGAL.DOC is also embedded * in the source code. See the file PVLEGAL.H. * * This program is based on the popular DKB raytracer version 2.12. * DKBTrace was originally written by David K. Buck. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins. * * Thanks to the makers of PERFORCE (http://www.perforce.com/) for donating the * copy of their Perforce revision control system that is now used to maintain * the POVWIN source. * * $Id: //depot/POVRAY/povwin/source/windows/PVENGINE.C#17$ * *****************************************************************************/ #define POVWIN_FILE #define _WIN32_IE COMMONCTRL_VERSION #include #include #include #include #include "frame.h" #include "colour.h" #include "povray.h" #include "povproto.h" #include "optout.h" #include "userio.h" #pragma hdrstop #define DECLARE_TABLES #include #include #include #include #include #include #include #include "optin.h" #include "pvengine.h" #include "pvengine.rh" #include "pvdialog.h" #include "pvguiext.h" #include "pvedit.h" int alert_sound ; int statistics_count = -1 ; int run_count ; int render_anim_count ; char command_line [_MAX_PATH * 3] ; char old_command_line [_MAX_PATH * 3] ; char extra_commands [_MAX_PATH * 3] ; char *argv [MAX_ARGV] ; char source_file_name [_MAX_PATH] ; char ourPath [_MAX_PATH] ; char engineHelpPath [_MAX_PATH] ; char rendererHelpPath [_MAX_PATH] ; char lastRenderName [_MAX_PATH] ; char lastBitmapName [_MAX_PATH] ; char lastRenderPath [_MAX_PATH] ; char lastBitmapPath [_MAX_PATH] ; char lastQueuePath [_MAX_PATH] ; char lastSecondaryIniFilePath [_MAX_PATH] ; char DefaultRenderIniFileName [_MAX_PATH] ; char SecondaryRenderIniFileName [_MAX_PATH] ; char SecondaryRenderIniFileSection [64] ; char background_file [_MAX_PATH] ; char HomePath [_MAX_PATH] ; char EngineIniFileName [_MAX_PATH] ; char RerunIniPath [_MAX_PATH] ; char CurrentRerunFileName [_MAX_PATH] ; char ToolIniFileName [_MAX_PATH] ; char tool_commands [MAX_TOOLCMD] [MAX_TOOLCMDTEXT] ; char tool_help [MAX_TOOLCMD] [MAX_TOOLHELPTEXT] ; char requested_render_file [_MAX_PATH] ; char ErrorMessage [768] ; char ErrorFilename [_MAX_PATH] ; char RegionStr [128] ; char TempRegionStr [128] ; unsigned class_registered = 0 ; unsigned currentX = 0 ; unsigned currentY = 0 ; unsigned percentage_complete = 0 ; unsigned screen_width ; unsigned screen_height ; unsigned screen_depth ; unsigned background_width ; unsigned background_height ; unsigned argc ; unsigned povray_return_code ; unsigned loadRerun ; unsigned continueRerun ; unsigned seconds = 0 ; unsigned pixels = 0 ; unsigned toolheight = 0 ; unsigned statusheight = 0 ; unsigned GUI_priority = CM_GUIPRIORITY_NORMAL ; unsigned render_priority = CM_RENDERPRIORITY_NORMAL ; unsigned on_completion = CM_COMPLETION_BEEP ; unsigned window_count = 0 ; unsigned ErrorLine ; unsigned ErrorCol ; BOOL quit ; BOOL rendering ; BOOL stop_rendering ; BOOL alert_on_completion ; BOOL using_ctl3d ; BOOL save_settings ; BOOL IsWin32 ; BOOL IsW95UserInterface ; BOOL IsW98 ; BOOL running_demo ; BOOL fast_scroll ; BOOL no_shellout_wait ; BOOL tile_background = TRUE ; BOOL debugging ; BOOL no_palette_warn ; BOOL render_lock_up ; BOOL render_main_icon ; BOOL hide_render_window = TRUE ; BOOL render_above_main = TRUE ; BOOL tips_enabled = TRUE ; BOOL demo_mode ; BOOL ignore_auto_ini ; BOOL use_template ; BOOL newVersion ; BOOL exit_after_render ; BOOL system_noactive ; BOOL terminating ; BOOL need_output_filename ; BOOL one_instance = TRUE ; BOOL run_renderer ; BOOL use_toolbar = TRUE ; BOOL use_tooltips = TRUE ; BOOL use_editors = TRUE ; BOOL resizing ; BOOL drop_to_editor ; BOOL restore_command_line ; BOOL render_requested ; BOOL render_auto_close ; BOOL rendersleep ; BOOL noexec ; BOOL ExtensionsEnabled = TRUE ; BOOL use_taskbar = TRUE ; BOOL main_window_hidden ; BOOL splash_show_about ; BOOL use_renderanim = TRUE ; BOOL NoRestore ; HWND toolbar_window ; HWND aux_toolbar_window ; HWND window_list [MAX_WINDOWS] ; HWND toolbar_combobox ; HWND rebar_window ; HWND StatusWindow ; FILE *debugFile ; HICON ourIcon ; HACCEL hAccelerators ; time_t render_start_time ; time_t render_finish_time ; HANDLE hRenderThread ; HANDLE hMainThread ; jmp_buf jump_buffer ; HBITMAP hBmpBackground ; HBITMAP hBmpRendering ; HBITMAP hBmpIcon ; HBITMAP hBmpSplash ; HPALETTE hPalApp ; HPALETTE hPalBitmap ; COLORREF background_colour ; COLORREF text_colour ; COLORREF custom_colours [16] ; COLORREF background_shade = RGB (1, 1, 1) ; HINSTANCE hInstance ; HINSTANCE hLibCtl3d ; OSVERSIONINFO version_info ; CRITICAL_SECTION critical_section ; char queued_files [MAX_QUEUE] [_MAX_PATH] ; char dir [_MAX_PATH] ; unsigned queued_file_count = 0 ; unsigned auto_render = TRUE ; unsigned timer_id ; unsigned panel_size ; char PovMainWinClass [] = "PovMainWinClass" ; unsigned mainwin_xpos ; unsigned mainwin_ypos ; HWND main_window ; HWND message_window ; WINDOWPLACEMENT mainwin_placement ; int renderwin_xoffset ; int renderwin_yoffset ; int renderwin_left = CW_USEDEFAULT ; int renderwin_top = CW_USEDEFAULT ; char PovRenderWinClass [] = "PovRenderWinClass" ; unsigned renderwin_max_width ; unsigned renderwin_max_height ; unsigned renderwin_8bits ; unsigned renderwin_flags = 0 ; BOOL renderwin_active ; BOOL renderwin_destroyed ; HWND render_window ; int render_bitmap_depth = -1 ; long render_bitmap_bpl ; unsigned render_width ; unsigned render_height ; uchar *render_bitmap_surface ; BitmapInfo render_bitmap ; BitmapInfo bitmap_template ; char PovSplashWinClass [] = "PovSplashWinClass" ; HWND splash_window ; unsigned splash_width ; unsigned splash_height ; int raw ; int rah ; char PovRenderAnimWinClass [] = "PovRenderAnimWinClass" ; HWND renderanim_window ; char PovMessageWinClass [] = "PovMessageWinClass" ; extern int message_xchar ; extern int message_ychar ; extern int message_scroll_pos_x ; extern int message_scroll_pos_y ; extern int top_message_row ; extern int message_count ; extern int message_cols ; extern int message_rows ; extern int pre_init_flag ; extern int listbox_xchar ; extern int listbox_ychar ; extern int EditFileCount ; extern char message_font_name [256] ; extern char *EditFiles [] ; extern unsigned message_font_size ; extern unsigned message_font_weight ; extern BOOL keep_messages ; extern BOOL MenuBarDraw ; extern Opts opts ; extern HFONT message_font ; extern HFONT tab_font ; extern HMENU hMenuBar ; extern HMENU hMainMenu ; extern HMENU hPopupMenus ; BOOL handle_main_command (WPARAM wParam, LPARAM lParam) ; typedef struct { WORD wVirtkey ; int iMessage ; WORD wRequest ; } SCROLLKEYS ; SCROLLKEYS key2scroll [] = { { VK_END, WM_VSCROLL, SB_BOTTOM }, { VK_PRIOR, WM_VSCROLL, SB_PAGEUP }, { VK_NEXT, WM_VSCROLL, SB_PAGEDOWN }, { VK_UP, WM_VSCROLL, SB_LINEUP }, { VK_DOWN, WM_VSCROLL, SB_LINEDOWN }, { VK_LEFT, WM_HSCROLL, SB_PAGEUP }, { VK_RIGHT, WM_HSCROLL, SB_PAGEDOWN }, { -1, -1, -1 } } ; #if 0 LONG PovUnhandledExceptionFilter (EXCEPTION_POINTERS *lpexpExceptionInfo) { //int i ; char str [256] ; //DWORD ebp ; PCONTEXT c ; c = lpexpExceptionInfo->ContextRecord ; sprintf (str, "An exception was generated at address %08lX\n\nPOV-Ray will now exit", c->Eip) ; MessageBox (NULL, str, "Error", MB_ICONSTOP | MB_SYSTEMMODAL) ; //if (MessageBox (NULL, "POV - Unhandled exception. Unwind stack ?", "Error", MB_ICONSTOP | MB_YESNO | MB_SYSTEMMODAL) == IDYES) //{ // c = lpexpExceptionInfo->ContextRecord ; // sprintf (str, "An exception was generated at address %08lX", c->Eip) ; // MessageBox (NULL, str, "Oops", MB_ICONINFORMATION | MB_SYSTEMMODAL) ; // ebp = c->Ebp ; // // add in stack walking code here. //} ExitProcess (1) ; return (EXCEPTION_CONTINUE_SEARCH) ; // make compiler happy } #endif void debug (char *format, ...) { char str [2048] ; va_list arg_ptr ; FILE *f ; if ((f = fopen ("debug.txt", "a+t")) != NULL) { va_start (arg_ptr, format) ; vsprintf (str, format, arg_ptr) ; va_end (arg_ptr) ; fprintf (f, "%s", str) ; fclose (f) ; } } void getvars (ExternalVarStruct *v) { strcpy (v->command_line, command_line) ; strcpy (v->source_file_name, source_file_name) ; strcpy (v->lastRenderName, lastRenderName) ; strcpy (v->lastRenderPath, lastRenderPath) ; strcpy (v->lastQueuePath, lastQueuePath) ; strcpy (v->lastSecondaryIniFilePath, lastSecondaryIniFilePath) ; strcpy (v->DefaultRenderIniFileName, DefaultRenderIniFileName) ; strcpy (v->SecondaryRenderIniFileName, SecondaryRenderIniFileName) ; strcpy (v->SecondaryRenderIniFileSection, SecondaryRenderIniFileSection) ; strcpy (v->ourPath, ourPath) ; strcpy (v->engineHelpPath, engineHelpPath) ; strcpy (v->rendererHelpPath, rendererHelpPath) ; strcpy (v->HomePath, HomePath) ; strcpy (v->EngineIniFileName, EngineIniFileName) ; strcpy (v->ToolIniFileName, ToolIniFileName) ; memcpy (v->queued_files, queued_files, sizeof (v->queued_files)) ; v->loadRerun = loadRerun ; v->continueRerun = continueRerun ; v->povray_return_code = povray_return_code ; v->rendering = rendering ; v->IsWin32 = IsWin32 ; v->IsW95UserInterface = IsW95UserInterface ; v->running_demo = running_demo ; v->debugging = debugging ; v->isMaxiMinimized = FALSE ; v->newVersion = newVersion ; v->use_threads = TRUE ; v->use_toolbar = use_toolbar ; v->use_tooltips = use_tooltips ; v->use_editors = use_editors ; v->drop_to_editor = drop_to_editor ; v->rendersleep = rendersleep ; v->ExtensionsEnabled = ExtensionsEnabled ; v->queued_file_count = queued_file_count ; v->auto_render = auto_render ; } void setvars (ExternalVarStruct *v) { strncpy (command_line, v->command_line, sizeof (command_line) - 1) ; strncpy (source_file_name, v->source_file_name, sizeof (source_file_name) - 1) ; strncpy (lastRenderName, v->lastRenderName, sizeof (lastRenderName) - 1) ; strncpy (lastRenderPath, v->lastRenderPath, sizeof (lastRenderPath) - 1) ; strncpy (lastQueuePath, v->lastQueuePath, sizeof (lastQueuePath) - 1) ; strncpy (lastSecondaryIniFilePath, v->lastSecondaryIniFilePath, sizeof (lastSecondaryIniFilePath) - 1) ; strncpy (DefaultRenderIniFileName, v->DefaultRenderIniFileName, sizeof (DefaultRenderIniFileName) - 1) ; strncpy (SecondaryRenderIniFileName, v->SecondaryRenderIniFileName, sizeof (SecondaryRenderIniFileName) - 1) ; strncpy (SecondaryRenderIniFileSection, v->SecondaryRenderIniFileSection, sizeof (SecondaryRenderIniFileSection) - 1) ; } BOOL HaveWin32s (void) { return (version_info.dwPlatformId == VER_PLATFORM_WIN32s) ; } BOOL HaveWin95OrLater (void) { return (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ; } BOOL HaveWin98OrLater (void) { return (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && version_info.dwMinorVersion >= 10) ; } BOOL HaveWinNT (void) { return (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT) ; } #ifdef __WATCOMC__ /* Watcom C/C++ C32 */ void Fix_Watcom_Bug(char *s) { char *p=s; while(*p != '\0') { if (*p==' ') { *p='0'; } p++; } } #endif DWORD render_thread (LPDWORD lpdwParam) { WIN_Povray (argc, argv) ; run_renderer = FALSE ; return (0) ; } void set_render_priority (unsigned priority) { switch (priority) { case CM_RENDERPRIORITY_LOWEST : SetThreadPriority (hRenderThread, THREAD_PRIORITY_LOWEST) ; break ; case CM_RENDERPRIORITY_LOW : SetThreadPriority (hRenderThread, THREAD_PRIORITY_BELOW_NORMAL) ; break ; case CM_RENDERPRIORITY_NORMAL : SetThreadPriority (hRenderThread, THREAD_PRIORITY_NORMAL) ; break ; case CM_RENDERPRIORITY_HIGH : SetThreadPriority (hRenderThread, THREAD_PRIORITY_ABOVE_NORMAL) ; break ; case CM_RENDERPRIORITY_HIGHEST : SetThreadPriority (hRenderThread, THREAD_PRIORITY_HIGHEST) ; break ; } } void set_GUI_priority (unsigned priority) { switch (GUI_priority) { case CM_GUIPRIORITY_LOWEST : SetThreadPriority (hMainThread, THREAD_PRIORITY_LOWEST) ; break ; case CM_GUIPRIORITY_LOW : SetThreadPriority (hMainThread, THREAD_PRIORITY_BELOW_NORMAL) ; break ; case CM_GUIPRIORITY_NORMAL : SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL) ; break ; case CM_GUIPRIORITY_HIGH : SetThreadPriority (hMainThread, THREAD_PRIORITY_ABOVE_NORMAL) ; break ; case CM_GUIPRIORITY_HIGHEST : SetThreadPriority (hMainThread, THREAD_PRIORITY_HIGHEST) ; break ; } } void display_cleanup (void) { if (render_window != NULL) { DestroyWindow (render_window) ; render_window = NULL ; renderwin_destroyed = FALSE ; PVEnableMenuItem (CM_RENDERSHOW, MF_ENABLED) ; PVEnableMenuItem (CM_RENDERCLOSE, MF_GRAYED) ; } if (render_bitmap_surface != NULL) { free (render_bitmap_surface) ; render_bitmap_surface = NULL ; } } // we can't allow LoadBitmap to load our background bitmaps 'cause if we're running // a 256-colour mode, it will map the incoming resource to 16 colours ... // LoadImage () doesn't exist under Win32s, either. sigh. HBITMAP NonBogusLoadBitmap (HINSTANCE hInst, LPSTR lpszBitmap) { void *p ; HRSRC hres ; HGLOBAL hg ; HBITMAP hBitmap ; if ((hres = FindResource (hInst, lpszBitmap, RT_BITMAP)) == NULL) return (NULL) ; if ((hg = LoadResource (hInst, hres)) == NULL) return (NULL) ; if ((p = LockResource (hg)) == NULL) return (NULL) ; hBitmap = lpDIBToBitmap (p, hPalApp) ; GlobalUnlock (hg) ; FreeResource (hg) ; return (hBitmap) ; } HBITMAP NonBogusLoadBitmapAndPalette (HINSTANCE hInst, LPSTR lpszBitmap) { void *p ; HRSRC hres ; HGLOBAL hg ; HBITMAP hBitmap ; if ((hres = FindResource (hInst, lpszBitmap, RT_BITMAP)) == NULL) return (NULL) ; if ((hg = LoadResource (hInst, hres)) == NULL) return (NULL) ; if ((p = LockResource (hg)) == NULL) return (NULL) ; hBitmap = lpDIBToBitmapAndPalette (p) ; GlobalUnlock (hg) ; FreeResource (hg) ; return (hBitmap) ; } // You must recreate the bitmaps splash5-8bpp.cmp and splash5-pal.bmp that are // in the bitmaps\ dir if you want to distribute your compile. When you do you // must include our copyright statement and clearly indicate that you have made // a derived version. You MAY NOT remove the splash screen code that shows this // bitmap at startup ! void SplashScreen (HWND hwnd) { BITMAP bm ; if ((hBmpSplash = NonBogusLoadBitmapAndPalette (hInstance, MAKEINTRESOURCE (screen_depth > 8 ? BMP_SPLASH_8BPP : BMP_SPLASH_8BPP_PAL))) != NULL) { GetObject (hBmpSplash, sizeof (BITMAP), (LPSTR) &bm) ; splash_width = bm.bmWidth ; splash_height = bm.bmHeight ; splash_window = CreateWindowEx (WS_EX_TOOLWINDOW, PovSplashWinClass, "POV-Ray", WS_POPUP, (screen_width - splash_width) / 2, (screen_height - splash_height) / 2, splash_width, splash_height, hwnd, NULL, hInstance, NULL) ; CenterWindowRelative (hwnd, splash_window, FALSE) ; ShowWindow (splash_window, SW_SHOWNORMAL) ; } } void validatePath (char *s) { if (s [1] == ':' && strlen (s) < 4) return ; s += strlen (s) - 1 ; if (*s == '\\') *s = '\0' ; } int joinPath (char *out, char *path, char *name) { strcpy (out, path) ; if (path [strlen (path) - 1] != '\\') strcat (out, "\\") ; strcat (out, name) ; return (strlen (out)) ; } void setRunOnce (void) { char str [_MAX_PATH] ; HKEY key ; DWORD result ; if (RegCreateKeyEx (HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, &result) == ERROR_SUCCESS) { GetModuleFileName (hInstance, str, sizeof (str)) ; RegSetValueEx (key, "POV-Ray for Windows v3.1", 0, REG_SZ, str, strlen (str) + 1) ; RegCloseKey (key) ; } } void getHome (void) { HKEY key ; DWORD len = sizeof (HomePath) ; if (debugFile) fprintf (debugFile, "querying registry\n") ; HomePath [0] = '\0' ; if (IsWin32) { if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\POV-Ray\\v3.1\\Windows", 0, KEY_READ, &key) == ERROR_SUCCESS) { RegQueryValueEx (key, "Home", 0, NULL, HomePath, &len) ; RegCloseKey (key) ; if (debugFile) fprintf (debugFile, "Win32 getHome () succeeded, HomePath is '%s'\n", HomePath) ; } } else { if (RegOpenKey (HKEY_CLASSES_ROOT, "POV-Ray\\Home", &key) == ERROR_SUCCESS) { RegQueryValue (key, NULL, HomePath, (LONG *) &len) ; RegCloseKey (key) ; if (debugFile) fprintf (debugFile, "Win16 getHome () succeeded, HomePath is '%s'\n", HomePath) ; } } } void setCommandLine (char *s) { HKEY key ; DWORD result ; if (IsWin32) { if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, "Software\\POV-Ray\\v3.1\\Windows", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, &result) == ERROR_SUCCESS) { RegSetValueEx (key, "Command Line", 0, REG_SZ, s, strlen (s) + 1) ; RegCloseKey (key) ; } } else { if (RegCreateKey (HKEY_CLASSES_ROOT, "POV-Ray\\CommandLine", &key) == ERROR_SUCCESS) { RegSetValue (key, NULL, REG_SZ, s, strlen (s)) ; RegCloseKey (key) ; } } } char *getCommandLine (void) { HKEY key ; static char str [2048] ; DWORD len = sizeof (str) ; str [0] = '\0' ; if (IsWin32) { if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\POV-Ray\\v3.1\\Windows", 0, KEY_READ, &key) == ERROR_SUCCESS) { RegQueryValueEx (key, "Command Line", 0, NULL, str, &len) ; RegCloseKey (key) ; } } else { if (RegOpenKey (HKEY_CLASSES_ROOT, "POV-Ray\\CommandLine", &key) == ERROR_SUCCESS) { RegQueryValue (key, NULL, str, (LONG *) &len) ; RegCloseKey (key) ; } } return (str) ; } int parse_commandline (char *s) { char *prevWord = NULL ; BOOL inQuote = FALSE ; BOOL noStrip = FALSE ; static char str [_MAX_PATH * 3] ; static char filename [_MAX_PATH] ; argc = 0 ; GetModuleFileName (hInstance, filename, sizeof (filename) - 1) ; argv [argc++] = filename ; s = strncpy (str, s, sizeof (str) - 1) ; while (*s) { switch (*s) { case '"' : if (prevWord != NULL) { if (inQuote) { if (!noStrip) *s = '\0' ; argv [argc++] = prevWord ; prevWord = NULL ; } else noStrip = TRUE ; } inQuote = !inQuote ; break ; case ' ' : case '\t' : if (!inQuote) { if (prevWord != NULL) { *s = '\0' ; argv [argc++] = prevWord ; prevWord = NULL ; noStrip = FALSE ; } } break ; default : if (prevWord == NULL) prevWord = s ; break ; } if (argc >= MAX_ARGV - 1) break ; s++ ; } if ((prevWord != NULL || (inQuote && prevWord != NULL)) && argc < MAX_ARGV - 1) { *s = '\0' ; argv [argc++] = prevWord ; } argv [argc] = NULL ; return (argc) ; } int execute_tool (char *s) { int error ; STARTUPINFO startupInfo ; PROCESS_INFORMATION procInfo ; if (strlen (s) == 0) { PovMessageBox ("No command to run!", "Tool Error") ; return (0) ; } if (*s == '$') { switch (toupper (s [1])) { case 'S' : s += 2 ; while (*s == ' ') s++ ; if (strlen (s) == 0) { PovMessageBox ("No file to open!", "Tool Error") ; return (0) ; } if ((error = (int) ShellExecute (main_window, "open", s, NULL, NULL, SW_SHOWNORMAL)) <= 32) PovMessageBox ("ShellExecute failed", "Tool Error") ; return (error) ; } } startupInfo.cb = sizeof (STARTUPINFO) ; startupInfo.lpReserved = 0 ; startupInfo.lpDesktop = NULL ; startupInfo.lpTitle = NULL ; startupInfo.dwX = 0 ; startupInfo.dwY = 0 ; startupInfo.dwXSize = 0 ; startupInfo.dwYSize = 0 ; startupInfo.dwXCountChars = 0 ; startupInfo.dwYCountChars = 0 ; startupInfo.dwFillAttribute = 0 ; startupInfo.dwFlags = IsWin32 ? STARTF_USESHOWWINDOW : 0 ; startupInfo.wShowWindow = SW_SHOW ; startupInfo.cbReserved2 = 0 ; startupInfo.lpReserved2 = 0 ; if (CreateProcess (NULL, s, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &procInfo) == FALSE) { error = GetLastError () ; PovMessageBox ("Could not run program", "Tool Error") ; return (error) ; } // clean up CloseHandle (procInfo.hProcess) ; CloseHandle (procInfo.hThread) ; return (0) ; } void start_rendering (BOOL is_auto_render, BOOL ignore_source_file) { int i ; char str [_MAX_PATH] ; char filename [_MAX_PATH] ; char rerunfile [_MAX_PATH] ; char section [16] ; MSG msg ; DWORD threadId = 0 ; DWORD threadParam = 0 ; extra_commands [0] = '\0' ; ErrorMessage [0] = '\0' ; ErrorFilename [0] = '\0' ; renderwin_destroyed = FALSE ; rendersleep = FALSE ; PVEnableMenuItem (CM_RENDERSHOW, MF_GRAYED) ; update_menu_for_render (TRUE) ; display_cleanup () ; render_anim_count = 0 ; //SendMessage (toolbar_combobox, WM_GETTEXT, sizeof (SecondaryRenderIniFileSection), (LPARAM) SecondaryRenderIniFileSection) ; SendMessage (toolbar_combobox, CB_GETLBTEXT, SendMessage (toolbar_combobox, CB_GETCURSEL, 0, 0), (LPARAM) SecondaryRenderIniFileSection) ; threadParam = SendMessage (toolbar_combobox, CB_GETITEMDATA, SendMessage (toolbar_combobox, CB_GETCURSEL, 0, 0), 0) ; if (debugging) message_printf ("Input command line is '%s'\n", command_line) ; /* ** This is the count used by the write statistics routine for the line number */ statistics_count = 0 ; if (loadRerun) { strcpy (section, "Renderer") ; // if loadRerun == 1, load last failed render. otherwise, load render number loadRerun - 2, where render number 0 is the most recent. switch (loadRerun) { case 1 : strcpy (rerunfile, CurrentRerunFileName) ; break ; default : sprintf (rerunfile, "%sRerun%02d.Ini", RerunIniPath, loadRerun - 2) ; break ; } // turn off continue trace in case it's on, since it seems to confuse people. WritePrivateProfileString (section, "Continue_Trace", "Off", rerunfile) ; // flush the INI file WritePrivateProfileString (NULL, NULL, NULL, rerunfile) ; sprintf (str, "\"Include_Ini=%s[%s]\" ", rerunfile, section) ; strcat (extra_commands, str) ; if (continueRerun) strcat (extra_commands, "+c ") ; GetPrivateProfileString (section, "Input_File_Name", "", filename, sizeof (filename), rerunfile) ; if (strlen (filename)) { message_printf ("%s file '%s' using rerun information.\n", continueRerun ? "Continuing" : "Rendering", filename) ; GetPrivateProfileString ("Environment", "CurrentDirectory", "", dir, sizeof (dir), rerunfile) ; if (strlen (dir)) { SetCurrentDirectory (dir) ; message_printf ("Render directory is '%s'.\n", dir) ; } } else { message_printf ("Error : Specified rerun information not found.\n") ; loadRerun = continueRerun = 0 ; update_menu_for_render (FALSE) ; return ; } } else { // non-rerun processing if (running_demo == 0) { splitpath (SecondaryRenderIniFileName, NULL, str) ; if (str [0] != '\0') { message_printf ("Preset INI file is '%s'", SecondaryRenderIniFileName) ; if (SecondaryRenderIniFileSection [0] != '\0') message_printf (", section is '%s'", SecondaryRenderIniFileSection) ; message_printf (".\n") ; strcat (extra_commands, "\"Include_INI=") ; strcat (extra_commands, SecondaryRenderIniFileName) ; strcat (extra_commands, SecondaryRenderIniFileSection) ; strcat (extra_commands, "\" ") ; } if (!ignore_source_file && strlen (source_file_name) != 0) { message_printf ("Preset source file is '%s'.\n", source_file_name) ; switch (get_file_type (source_file_name)) { case filePOV : sprintf (str, "\"Input_File_Name=%s\" ", source_file_name) ; break ; case fileINI : sprintf (str, "\"Include_INI=%s\" ", source_file_name) ; break ; default : message_printf ("POV-Ray for Windows doesn't recognize this file type ; assuming POV source.\n") ; sprintf (str, "\"Input_File_Name=%s\" ", source_file_name) ; break ; } strcat (extra_commands, str) ; splitpath (source_file_name, dir, NULL) ; SetCurrentDirectory (dir) ; } } } if (strlen (command_line)) { if (!running_demo) message_printf ("Rendering using command line '%s'.\n", command_line) ; strncat (extra_commands, command_line, sizeof (extra_commands) - 1) ; } if (RegionStr [0] != 0) { if (strstr (command_line, RegionStr) == NULL && strstr (command_line, RegionStr + 1) == NULL) { if (!running_demo) message_printf ("Selected render region is '%s'.\n", RegionStr + 1) ; strncat (extra_commands, RegionStr, sizeof (extra_commands) - 1) ; RegionStr [0] = '\0' ; } } if (debugging) message_printf ("Extra command string is '%s'\n", extra_commands) ; parse_commandline (extra_commands) ; if (debugging) { message_printf ("%d arguments parsed\n", argc) ; for (i = 0 ; i < argc ; i++) message_printf (" arg %d is '%s'\n", i, argv [i]) ; } stop_rendering = FALSE ; percentage_complete = 0 ; loadRerun = continueRerun = 0 ; WIN_Pre_Pixel (-1, -1, 0) ; if (MenuBarDraw) { DrawMenuBar (main_window) ; MenuBarDraw = FALSE ; } EditShowMessages (TRUE) ; CalculateClientWindows (TRUE) ; ShowWindow (message_window, SW_SHOW) ; ExternalEvent (EventStartRendering, 0) ; hRenderThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) render_thread, &threadParam, 0, &threadId) ; if (hRenderThread != NULL) { run_renderer = TRUE ; set_render_priority (render_priority) ; set_GUI_priority (GUI_priority) ; while (run_renderer) { while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) == TRUE) { if (!TranslateAccelerator (main_window, hAccelerators, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } Sleep (5) ; } CloseHandle (hRenderThread) ; hRenderThread = NULL ; set_GUI_priority (CM_GUIPRIORITY_NORMAL) ; } else MessageBox (NULL, "Error", "Cannot create thread for render process!", MB_OK | MB_ICONSTOP) ; if (quit) { WinHelp (main_window, "pvengine.hlp", HELP_QUIT, NULL) ; WinHelp (main_window, "povray31.hlp", HELP_QUIT, NULL) ; DestroyWindow (main_window) ; return ; } rendersleep = FALSE ; SetWindowText (main_window, "POV-Ray for Windows") ; if (render_window) { SetWindowText (render_window, "Render Window") ; if (render_auto_close) handle_main_command (CM_RENDERCLOSE, 0) ; } say_status_message (StatusMessage, "") ; update_menu_for_render (FALSE) ; ExternalEvent (EventStopRendering, povray_return_code) ; InvalidateRect (renderanim_window, NULL, FALSE) ; if (povray_return_code == 0) { EditShowMessages (FALSE) ; CalculateClientWindows (FALSE) ; switch (on_completion) { case CM_COMPLETION_EXIT : WinHelp (main_window, "pvengine.hlp", HELP_QUIT, NULL) ; WinHelp (main_window, "povray31.hlp", HELP_QUIT, NULL) ; DestroyWindow (main_window) ; break ; case CM_COMPLETION_BEEP : MessageBeep (alert_sound) ; break ; case CM_COMPLETION_BEEPMESSAGE : MessageBeep (alert_sound) ; // fall through case CM_COMPLETION_MESSAGE : PovMessageBox ("Render completed", "Message from POV-Ray for Windows") ; break ; } } else if (ErrorFilename [0] != '\0') EditShowParseError (ErrorFilename, ErrorMessage, ErrorLine, ErrorCol) ; } UINT WINAPI ofn_hook_fn (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG : SetupExplorerDialog (hwnd) ; break ; } return (FALSE) ; } void init_ofn (OPENFILENAME *ofn, HWND hWnd, char *title, char *name, int maxlen, char *lastPath, char *defaultExt) { ofn->lStructSize = sizeof (OPENFILENAME) ; ofn->hwndOwner = hWnd ; ofn->hInstance = hInstance ; ofn->lpstrCustomFilter = NULL ; ofn->nMaxCustFilter = 0 ; ofn->nFilterIndex = 1 ; ofn->lpstrTitle = title ; ofn->lpstrFile = name ; ofn->nMaxFile = maxlen ; ofn->lpstrFileTitle = NULL ; ofn->nMaxFileTitle = 0 ; ofn->lpstrInitialDir = lastPath ; ofn->Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR ; if (IsW95UserInterface) ofn->Flags |= OFN_EXPLORER ; if (use_template) { if (IsW95UserInterface) ofn->Flags |= OFN_ENABLEHOOK ; else ofn->Flags = OFN_ENABLETEMPLATE ; } ofn->nFileOffset = 0 ; ofn->nFileExtension = 0 ; ofn->lpstrDefExt = defaultExt ; ofn->lCustData = 0L ; ofn->lpfnHook = ofn_hook_fn ; ofn->lpTemplateName = MAKEINTRESOURCE (HaveWinNT () ? IDD_NTCOMMFILE : IDD_COMMFILE) ; } char *file_open (HWND hWnd) { BOOL result ; OPENFILENAME ofnTemp ; static char name [_MAX_PATH] ; strcpy (name, lastRenderName) ; validatePath (lastRenderPath) ; init_ofn (&ofnTemp, hWnd, "Render File", name, sizeof (name), lastRenderPath, "pov") ; ofnTemp.lpstrFilter = "POV source and INI (*.pov;*.ini)\0*.pov;*.ini\0INI files (*.ini)\0*.ini\0Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0" ; if ((result = GetOpenFileName (&ofnTemp)) != FALSE) { strcpy (lastRenderPath, name) ; // this removes the name AND the trailing '\' [which is what we want] lastRenderPath [ofnTemp.nFileOffset - 1] = '\0' ; validatePath (lastRenderPath) ; strcpy (lastRenderName, name + ofnTemp.nFileOffset) ; } return (result ? name : NULL) ; } void add_queue (HWND hWnd, HWND hlb) { int queue_count ; char name [8192] ; char *s ; char str [_MAX_PATH] ; OPENFILENAME ofnTemp ; queue_count = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; if (queue_count >= MAX_QUEUE) { PovMessageBox ("File queue is full", "Cannot add any more files!") ; return ; } strcpy (name, lastRenderName) ; name [strlen (name) + 1] = '\0' ; validatePath (lastQueuePath) ; init_ofn (&ofnTemp, hWnd, "Add to Queue", name, sizeof (name), lastQueuePath, "pov") ; ofnTemp.lpstrFilter = "POV source and INI (*.pov;*.ini)\0*.pov;*.ini\0INI files (*.ini)\0*.ini\0All Files (*.*)\0*.*\0" ; ofnTemp.Flags |= OFN_ALLOWMULTISELECT ; if (GetOpenFileName (&ofnTemp) != FALSE) { // convert spaces into NULL's if we're not using the new interface so it works with the below code if (!IsW95UserInterface) for (s = name ; *s ; s++) if (*s == ' ') *s = '\0' ; if (ofnTemp.nFileOffset < strlen (name)) { strcpy (lastQueuePath, name) ; lastQueuePath [ofnTemp.nFileOffset - 1] = '\0' ; SendMessage (hlb, LB_ADDSTRING, 0, (LPARAM) name) ; } else { s = name ; strcpy (lastQueuePath, name) ; for (s += strlen (s) + 1 ; *s ; s += strlen (s) + 1) { if (queue_count++ >= MAX_QUEUE) { PovMessageBox ("File queue is full", "Cannot add any more files!") ; return ; } joinPath (str, lastQueuePath, s) ; strlwr (str) ; SendMessage (hlb, LB_ADDSTRING, 0, (LPARAM) str) ; } } } } char *get_ini_file (HWND hWnd, char *path) { BOOL result ; OPENFILENAME ofnTemp ; static char name [_MAX_PATH] ; validatePath (path) ; init_ofn (&ofnTemp, hWnd, "Choose INI File", name, sizeof (name), path, "ini") ; ofnTemp.lpstrFilter = "INI files (*.ini)\0*.ini\0Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0" ; if ((result = GetOpenFileName (&ofnTemp)) != FALSE) { strcpy (path, name) ; path [ofnTemp.nFileOffset - 1] = '\0' ; } return (result ? name : NULL) ; } char *get_background_file (HWND hWnd) { BOOL result ; OPENFILENAME ofnTemp ; static char name [_MAX_PATH] ; strcpy (name, lastBitmapName) ; validatePath (lastBitmapPath) ; init_ofn (&ofnTemp, hWnd, "Tile Bitmap File", name, sizeof (name), lastBitmapPath, "bmp") ; ofnTemp.lpstrFilter = "BMP files (*.bmp)\0*.bmp\0" ; if ((result = GetOpenFileName (&ofnTemp)) != FALSE) { strcpy (lastBitmapPath, name) ; lastBitmapPath [ofnTemp.nFileOffset - 1] = '\0' ; strcpy (lastBitmapName, name + ofnTemp.nFileOffset) ; } return (result ? name : NULL) ; } void get_font (void) { HDC hdc ; HFONT hfont ; HFONT hfontOld ; LOGFONT lf ; CHOOSEFONT cf ; TEXTMETRIC tm ; hdc = GetDC (message_window) ; memset(&cf, 0, sizeof (CHOOSEFONT)) ; cf.lStructSize = sizeof (CHOOSEFONT) ; cf.hwndOwner = main_window ; cf.lpLogFont = &lf ; cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT ; cf.nFontType = SCREEN_FONTTYPE ; get_logfont (hdc, &lf) ; if (ChooseFont (&cf)) { if ((hfont = CreateFontIndirect (&lf)) == NULL) { PovMessageBox ("Failed to create message font", "Cannot change to selected font") ; ReleaseDC (message_window, hdc) ; return ; } hfontOld = SelectObject (hdc, hfont) ; GetTextMetrics (hdc, &tm) ; message_xchar = tm.tmAveCharWidth ; message_ychar = tm.tmHeight + tm.tmExternalLeading ; SelectObject (hdc, hfontOld) ; DeleteObject (message_font) ; message_font = hfont ; PovInvalidateRect (message_window, NULL, TRUE) ; message_font_size = -MulDiv (lf.lfHeight, 72, GetDeviceCaps (hdc, LOGPIXELSY)) ; message_font_weight = lf.lfWeight ; strncpy (message_font_name, lf.lfFaceName, sizeof (message_font_name) - 1) ; } ReleaseDC (message_window, hdc) ; } void DragFunction (HANDLE handle) { int cFiles ; int i ; char szFile [_MAX_PATH] ; HDIB hDIB ; BOOL calc = 0 ; BITMAP bm ; cFiles = DragQueryFile (handle, -1, NULL, 0) ; if (rendering) message_printf ("\n") ; for (i = 0 ; i < cFiles ; i++) { DragQueryFile (handle, i, szFile, sizeof (szFile)) ; switch (get_file_type (szFile)) { case filePOV : case fileINI : case fileINC : if (!use_editors || !drop_to_editor) break ; if ((EditGetFlags () & EDIT_CAN_OPEN) == 0) { say_status_message (StatusMessage, "Cannot open dropped file - max editor count reached") ; message_printf ("Cannot open dropped file - max editor count reached\n") ; } else EditOpenFile (szFile) ; continue ; case fileBMP : if (screen_depth < 8) { PovMessageBox ("Tiled bitmaps not supported in this color depth", "File ignored") ; continue ; } if ((hDIB = LoadDIB (szFile)) != NULL) { strcpy (background_file, szFile) ; DeleteObject (hBmpBackground) ; hBmpBackground = DIBToBitmap (hDIB, hPalApp) ; DeleteObject (hDIB) ; GetObject (hBmpBackground, sizeof (BITMAP), (LPSTR) &bm) ; background_width = bm.bmWidth ; background_height = bm.bmHeight ; tile_background = TRUE ; PovInvalidateRect (message_window, NULL, TRUE) ; } else PovMessageBox ("Failed to load bitmap file", "Error") ; continue ; default : if (!ExternalDragFunction (szFile, dfRealDrop)) { if (!use_editors || !drop_to_editor) { say_status_message (StatusMessage, "Dropped file ignored (must be .POV, .INC, or .INI if destination is renderer)") ; message_printf ("Dropped file '%s' ignored (must be .POV, .INC, or .INI if destination is renderer)\n", szFile) ; } else { if ((EditGetFlags () & EDIT_CAN_OPEN) == 0) { say_status_message (StatusMessage, "Cannot open dropped file - max editor count reached") ; message_printf ("Cannot open dropped file - max editor count reached\n") ; } else EditOpenFile (szFile) ; } } continue ; } if (queued_file_count < MAX_QUEUE) { strcpy (queued_files [queued_file_count++], szFile) ; message_printf ("File '%s' dropped as queue entry %d\n", szFile, queued_file_count) ; } else message_printf ("render queue full ; file '%s' ignored\n", szFile) ; } if (rendering) message_printf ("\n") ; DragFinish (handle) ; update_queue_status (TRUE) ; if (calc) CalculateClientWindows (TRUE) ; } HPALETTE create_palette (RGBQUAD *rgb, int entries) { int i ; HDC hdc ; LogPal Palette = { 0x300, 256 } ; if (screen_depth == 8 || render_bitmap_depth == 8) { if (rgb) { Palette.entries = entries ; for (i = 0 ; i < entries ; i++, rgb++) { Palette.pe [i].peRed = rgb->rgbRed ; Palette.pe [i].peGreen = rgb->rgbGreen ; Palette.pe [i].peBlue = rgb->rgbBlue ; Palette.pe [i].peFlags = PC_NOCOLLAPSE ; } } else { // Copy the halftone palette into the DIB palette entries, and read the // current system palette entries to ensure we have an identity palette mapping. hdc = GetDC (NULL) ; memcpy (bitmap_template.colors, halftonePal, sizeof (halftonePal)) ; GetSystemPaletteEntries (hdc, 0, 256, Palette.pe) ; for (i = 0 ; i < 10 ; i++) { bitmap_template.colors [i].rgbRed = Palette.pe [i].peRed ; bitmap_template.colors [i].rgbGreen = Palette.pe [i].peGreen ; bitmap_template.colors [i].rgbBlue = Palette.pe [i].peBlue ; Palette.pe [i].peFlags = 0 ; bitmap_template.colors [i + 246].rgbRed = Palette.pe [i + 246].peRed ; bitmap_template.colors [i + 246].rgbGreen = Palette.pe [i + 246].peGreen ; bitmap_template.colors [i + 246].rgbBlue = Palette.pe [i + 246].peBlue ; Palette.pe [i + 246].peFlags = 0 ; } while (i < 246) { Palette.pe [i].peRed = bitmap_template.colors [i].rgbRed ; Palette.pe [i].peGreen = bitmap_template.colors [i].rgbGreen ; Palette.pe [i].peBlue = bitmap_template.colors [i].rgbBlue ; Palette.pe [i++].peFlags = PC_NOCOLLAPSE ; } ReleaseDC (NULL, hdc) ; } return (CreatePalette ((LOGPALETTE *) &Palette)) ; } return (NULL) ; } BOOL create_render_bitmap (int width, int height) { render_bitmap = bitmap_template ; render_bitmap.header.biSize = sizeof (BITMAPINFOHEADER) ; render_bitmap.header.biWidth = width ; render_bitmap.header.biHeight = height ; render_bitmap.header.biPlanes = 1 ; render_bitmap.header.biBitCount = (WORD) render_bitmap_depth ; render_bitmap.header.biCompression = BI_RGB ; if (render_bitmap_depth == 8) { // round out the bits per line to a multiple of four render_bitmap_bpl = (width + 3) & ~3 ; render_bitmap.header.biClrUsed = 256 ; } else { render_bitmap_bpl = (width * 3 + 3) & ~3 ; render_bitmap.header.biClrUsed = 0 ; } render_bitmap.header.biSizeImage = render_bitmap_bpl * height ; render_bitmap.header.biClrImportant = 0 ; return ((render_bitmap_surface = calloc (1, render_bitmap.header.biSizeImage)) != NULL) ; } BOOL create_render_window (void) { unsigned flags ; RECT rect ; if (render_window) DestroyWindow (render_window) ; renderwin_destroyed = FALSE ; renderwin_xoffset = renderwin_yoffset = 0 ; rect.left = 0 ; rect.top = 0 ; rect.right = render_width ; rect.bottom = render_height ; flags = WS_OVERLAPPEDWINDOW ; if (IsIconic (main_window) && render_above_main) render_main_icon = TRUE ; AdjustWindowRect (&rect, flags, FALSE) ; // left and top will probably be negative renderwin_max_width = rect.right - rect.left ; renderwin_max_height = rect.bottom - rect.top ; if (renderwin_left < 0) renderwin_left = 0 ; if (renderwin_top < 0) renderwin_top = 0 ; if (renderwin_left - screen_width / 8 + renderwin_max_width > screen_width) renderwin_left = screen_width / 8 ; if (renderwin_top - screen_height / 8 + renderwin_max_height > screen_height) renderwin_top = screen_height / 8 ; if ((render_window = CreateWindowEx (0, PovRenderWinClass, "POVRAY", flags | renderwin_flags, renderwin_left, renderwin_top, renderwin_max_width, renderwin_max_height, render_above_main ? main_window : NULL, NULL, hInstance, NULL)) == NULL) { return (FALSE) ; } if (!render_main_icon && !main_window_hidden) { flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOCOPYBITS | SWP_SHOWWINDOW | SWP_NOACTIVATE ; if (GetForegroundWindow () == main_window && render_above_main) flags &= ~SWP_NOACTIVATE ; if (renderwin_active) flags &= ~SWP_NOACTIVATE ; SetWindowPos (render_window, main_window, 0, 0, 0, 0, flags) ; } return (TRUE) ; } int renderwin_init (void) { display_cleanup () ; if (create_render_window () == FALSE) { PovMessageBox ("Failed to create display window", "Initialize Display - Fatal Error") ; display_cleanup () ; return (1) ; } if (create_render_bitmap (render_width, render_height) == FALSE) { PovMessageBox ("Failed to allocate display bitmap", "Initialize Display - Fatal Error") ; display_cleanup () ; return (1) ; } return (0) ; } void WIN_Display_Init (int x, int y) { render_width = x ; render_height = y ; if (SendMessage (main_window, CREATE_RENDERWIN_MESSAGE, 0, 0L)) Terminate_POV (-1) ; WIN_Display_Plot (-1, -1, 0, 0, 0, 0) ; ExternalEvent (EventDisplayInit, MAKELONG (x, y)) ; } void WIN_Display_Finished (void) { PovInvalidateRect (render_window, NULL, FALSE) ; ExternalEvent (EventDisplayFinished, 0) ; } void WIN_Display_Close (void) { ExternalEvent (EventDisplayClose, 0) ; } void WIN_Display_Plot (int x, int y, int Red, int Green, int Blue, int Alpha) { int oldMode ; char str [128] ; uchar *p ; uchar dither ; HDC hdc ; RECT rect ; static int lastx = 0, lasty = 0 ; static char laststr [128] ; ExternalDisplayPlot (x, y, Red, Green, Blue, Alpha) ; if (x == -1 || y == -1) { lastx = lasty = 0 ; laststr [0] = '\0' ; return ; } if (x < 0 || x >= render_width || y < 0 || y >= render_height) return ; if (render_bitmap_surface == NULL) return ; percentage_complete = (y - opts.First_Line + 1) * 100 / (opts.Last_Line - opts.First_Line + 1) ; if (render_window != NULL && (x < lastx || y != lasty)) { // Blt the completed scanline to the display if (render_main_icon) { if ((hdc = GetDC (main_window)) == NULL) return ; oldMode = SetStretchBltMode (hdc, STRETCH_DELETESCANS) ; if (hPalApp) { SelectPalette (hdc, hPalApp, FALSE) ; RealizePalette (hdc) ; } SelectClipRgn (hdc, NULL) ; StretchDIBits (hdc, 0, percentage_complete * 36 / 100, 36, 1, 0, render_bitmap.header.biHeight - 1 - (percentage_complete * render_bitmap.header.biHeight / 100), render_bitmap.header.biWidth, (render_bitmap.header.biHeight + 35) / 36, render_bitmap_surface, (LPBITMAPINFO) &render_bitmap, DIB_RGB_COLORS, SRCCOPY) ; SetStretchBltMode (hdc, oldMode) ; ReleaseDC (main_window, hdc) ; } else { if ((hdc = GetDC (render_window)) == NULL) return ; oldMode = SetStretchBltMode (hdc, STRETCH_DELETESCANS) ; if (hPalApp) { SelectPalette (hdc, hPalApp, FALSE) ; RealizePalette (hdc) ; } if (IsIconic (render_window)) { SelectClipRgn (hdc, NULL) ; StretchDIBits (hdc, 0, percentage_complete * 36 / 100, 36, 1, 0, render_bitmap.header.biHeight - 1 - (percentage_complete * render_bitmap.header.biHeight / 100), render_bitmap.header.biWidth, (render_bitmap.header.biHeight + 35) / 36, render_bitmap_surface, (LPBITMAPINFO) &render_bitmap, DIB_RGB_COLORS, SRCCOPY) ; if (opts.Radiosity_Preview_Done) //MH { sprintf (str, "POV %d%%", (y - opts.First_Line + 1) * 100 / (opts.Last_Line - opts.First_Line + 1)) ; SetWindowText (render_window, str) ; } } else { if (IsZoomed (render_window)) { GetClientRect (render_window, &rect) ; StretchDIBits (hdc, 0, (rect.bottom * lasty + render_height - 1) / render_height, rect.right, (rect.bottom + render_height - 1) / render_height, 0, render_bitmap.header.biHeight - 1 - lasty, render_bitmap.header.biWidth, 1, render_bitmap_surface, (LPBITMAPINFO) &render_bitmap, DIB_RGB_COLORS, SRCCOPY) ; } else { StretchDIBits (hdc, -renderwin_xoffset, lasty - renderwin_yoffset, render_width, 1, 0, render_bitmap.header.biHeight - 1 - lasty, render_bitmap.header.biWidth, 1, render_bitmap_surface, (LPBITMAPINFO) &render_bitmap, DIB_RGB_COLORS, SRCCOPY) ; } //MH if (opts.Radiosity_Preview_Done) { sprintf (str, "%d%% complete", (y - opts.First_Line + 1) * 100 / (opts.Last_Line - opts.First_Line + 1)) ; } } //MH if ((strcmp (str, laststr) != 0) & (opts.Radiosity_Preview_Done)) { SetWindowText (render_window, str) ; strcpy (laststr, str) ; } SetStretchBltMode (hdc, oldMode) ; ReleaseDC (render_window, hdc) ; } } lastx = x ; lasty = y ; if (render_bitmap_depth == 8) { p = render_bitmap_surface + (render_bitmap.header.biHeight - 1 - y) * render_bitmap_bpl + x ; dither = dither8x8 [((x & 7) << 3) | (y & 7)] ; *p = 20 + div51 [Red] + (mod51 [Red] > dither) + mul6 [div51 [Green] + (mod51 [Green] > dither)] + mul36 [div51 [Blue] + (mod51 [Blue] > dither)] ; } else { p = render_bitmap_surface + (render_bitmap.header.biHeight - 1 - y) * render_bitmap_bpl + x * 3 ; p [0] = Blue ; p [1] = Green ; p [2] = Red ; } } void WIN_Display_Plot_Rect (int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha) { int x ; int y ; int width ; int height ; int oldMode ; uchar *p ; uchar dither ; HDC hdc ; RECT rect ; ExternalDisplayPlotRect (x1, y1, x2, y2, Red, Green, Blue, Alpha) ; if (render_bitmap_surface == NULL) return ; if (x1 < 0 || x1 >= render_width || x2 < 0 || x2 >= render_width) return ; if (y1 < 0 || y1 >= render_height || y2 < 0 || y2 >= render_height) return ; if (x1 == x2 && y1 == y2) { WIN_Display_Plot (x1, y1, Red, Green, Blue, Alpha) ; return ; } for (y = y1 ; y <= y2 ; y++) { if (render_bitmap_depth == 8) { p = render_bitmap_surface + (render_bitmap.header.biHeight - 1 - y) * render_bitmap_bpl + x1 ; for (x = x1 ; x <= x2 ; x++) { dither = dither8x8 [((x & 7) << 3) | (y & 7)] ; *p++ = 20 + div51 [Red] + (mod51 [Red] > dither) + mul6 [div51 [Green] + (mod51 [Green] > dither)] + mul36 [div51 [Blue] + (mod51 [Blue] > dither)] ; } } else { p = render_bitmap_surface + (render_bitmap.header.biHeight - 1 - y) * render_bitmap_bpl + x1 * 3 ; for (x = x1 ; x <= x2 ; x++) { *p++ = Blue ; *p++ = Green ; *p++ = Red ; } } } if (render_window != NULL && !IsIconic (main_window) && !IsIconic (render_window)) { hdc = GetDC (render_window) ; oldMode = SetStretchBltMode (hdc, STRETCH_DELETESCANS) ; if (hPalApp) { SelectPalette (hdc, hPalApp, FALSE) ; RealizePalette (hdc) ; } if (IsZoomed (render_window)) { GetClientRect (render_window, &rect) ; x = rect.right * x1 / render_width ; y = rect.bottom * y1 / render_height ; width = (rect.right * (x2 - x1 + 1) + render_width - 1) / render_width ; height = (rect.bottom * (y2 - y1 + 1) + render_height - 1) / render_height ; } else { x = x1 ; y = y1 ; width = x2 - x1 + 1 ; height = y2 - y1 + 1 ; } StretchDIBits (hdc, x - renderwin_xoffset, y - renderwin_yoffset, width, height, x1, render_bitmap.header.biHeight - 1 - y2, x2 - x1 + 1, y2 - y1 + 1, render_bitmap_surface, (LPBITMAPINFO) &render_bitmap, DIB_RGB_COLORS, SRCCOPY) ; SetStretchBltMode (hdc, oldMode) ; ReleaseDC (render_window, hdc) ; } } void WIN_Pre_Pixel (int x, int y, COLOUR colour) { char str1 [_MAX_PATH] ; char str2 [128] ; static int lastY = -1 ; static int last_seconds = -1 ; ExternalWinPrePixel (x, y, colour) ; if (need_output_filename) { WritePrivateProfileString ("LastRender", "HistogramFile", get_full_name (opts.Histogram_File_Name), EngineIniFileName) ; if (opts.Output_Path [0] != '\0') { sprintf (str1, "%s%s", opts.Output_Path, opts.Output_File_Name) ; WritePrivateProfileString ("LastRender", "OutputFile", str1, EngineIniFileName) ; } else WritePrivateProfileString ("LastRender", "OutputFile", get_full_name (opts.Output_File_Name), EngineIniFileName) ; need_output_filename = 0 ; } currentX = x ; /* Short circuit unless scanline has changed */ //mosaic problem? //MH if (opts.Radiosity_Preview_Done) /*Turn percent bar off for radiosity pre-pass */ { if (y == -1) { last_seconds = lastY = -1 ; return ; } if (y == lastY) return ; lastY = currentY = y ; if (seconds != last_seconds) { last_seconds = seconds ; percentage_complete = (y - opts.First_Line + 1) * 100 / (opts.Last_Line - opts.First_Line + 1) ; if (!IsIconic (main_window)) { splitpath (opts.Input_File_Name, NULL, str2) ; sprintf (str1, "%s:line %d (of %d)", str2, y - opts.First_Line + 1, opts.Last_Line - opts.First_Line) ; } else sprintf (str1, "POV %d%%", percentage_complete) ; SetWindowText (main_window, str1) ; } } } void WIN_Post_Pixel (int x, int y, COLOUR colour) { ExternalWinPostPixel (x, y, colour) ; pixels++ ; } void WIN_Banner (char *s) { buffer_message (mBanner, s) ; } void WIN_Warning (char *s) { buffer_message (mWarning, s) ; } void WIN_Render_Info (char *s) { buffer_message (mRender, s) ; } void WIN_Status_Info (char *s) { // as a general rule, we don't display any message that starts with a space // these are usually continuations of previous messages if (strlen (s) > 3 && *s != ' ') say_status_message (StatusMessage, clean_str (s)) ; } void WIN_Debug_Info (char *s) { buffer_message (mDebug, s) ; } void WIN_WhereError (char *FileName, int Line, char *SrcLine, int Index, char *Token) { if (ErrorFilename [0] || Token == NULL) return ; strcpy (ErrorFilename, FileName) ; ErrorLine = Line ; ErrorCol = Index - strlen (Token) + 1 ; } void WIN_Fatal (char *s) { strncat (ErrorMessage, s, sizeof (ErrorMessage) - 1) ; buffer_message (mFatal, s) ; } void WIN_Statistics (char *s) { buffer_message (mStatistics, s) ; } void WIN_Startup (void) { if (!keep_messages) clear_messages () ; ExternalEvent (EventWinStartup, 0) ; } void WIN_Finish (int n) { if (keep_messages) buffer_message (mIDE, "\n") ; povray_return_code = n ; ExternalEvent (EventWinFinish, n) ; longjmp (jump_buffer, 1) ; } // priority == 0 when called from a higher level (e.g. in Trace_Pixel()). void WIN_Cooperate (int priority) { while (rendersleep && !(quit || stop_rendering)) { if (IsWin32) Sleep (100) ; ExternalEvent (EventWinCooperate, priority) ; } ExternalEvent (EventWinCooperate, priority) ; if (terminating == FALSE && (quit || stop_rendering)) { terminating = TRUE ; // warning - this function call doesn't return ! Terminate_POV (-1) ; } } int WIN_Povray (int argc, char **argv) { int rval ; pre_init_flag = 0 ; pre_init_povray () ; povray_return_code = -1 ; if ((rval = setjmp (jump_buffer)) != 0) { if (povray_return_code == 0) { PutPrivateProfileInt ("Statistics", "FinishRender", time (NULL), CurrentRerunFileName) ; buffer_message (mIDE, "Returned from renderer\n") ; rotate_rerun_entries () ; buffer_message (mIDE, "POV-Ray finished\n") ; } else { buffer_message (mIDE, "\n") ; buffer_message (mIDE, "Returned from renderer (non-zero return value)\n") ; close_all () ; mem_release_all (FALSE) ; pre_init_flag = 0 ; } } else { // setjmp succeeded, so we call POV-Ray. we expect POV to return via a longjmp always. rendering = TRUE ; terminating = FALSE ; render_start_time = time (NULL) ; pixels = 0 ; alt_main (argc, argv) ; assert (FALSE) ; } HEAPSHRINK render_finish_time = time (NULL) ; rendering = FALSE ; if (use_renderanim) InvalidateRect (renderanim_window, NULL, FALSE) ; terminating = FALSE ; if (render_finish_time != render_start_time) status_printf (StatusPPS, "%u PPS", pixels / (render_finish_time - render_start_time)) ; if (render_main_icon) PostMessage (main_window, WM_NCPAINT, 0, 0L) ; say_status_message (StatusRendertime, get_elapsed_time (render_start_time, render_finish_time)) ; running_demo = FALSE ; buffer_message (mDivider, "\n") ; add_rerun_to_menu () ; fcloseall () ; if (debugFile) debugFile = fopen ("c:\\povray.dbg", "at") ; return (rval) ; } int WIN_System (char *s) { int n ; char *message = "POV-Ray is running an external application. Do you want to halt this application ?\n\n" "If you specify YES this application will be terminated, but note that this could lead\nto an incomplete clean-up. " "The use of this facility is not recommended.\n\n" "If you specify NO the application will remain running\n\nIf you specify CANCEL POV-Ray will continue rendering." ; MSG msg ; DWORD code = WAIT_TIMEOUT ; STARTUPINFO startupInfo ; PROCESS_INFORMATION procInfo ; if (noexec) { message_printf ("External exec request '%s' made but NOEXEC set\n", s) ; MessageBox (main_window, "External exec request made but NOEXEC set\n\nPOV-Ray will now exit", "Security warning", MB_ICONSTOP) ; quit = TRUE ; return (-1) ; } if (ExternalWinSystem (s, &n)) return (n) ; buffer_message (mHorzLine, "\n") ; buffer_message (mIDE, "POV-Ray is creating another process\n") ; message_printf (" %s\n", s) ; startupInfo.cb = sizeof (STARTUPINFO) ; startupInfo.lpReserved = 0 ; startupInfo.lpDesktop = NULL ; startupInfo.lpTitle = NULL ; startupInfo.dwX = 0 ; startupInfo.dwY = 0 ; startupInfo.dwXSize = 0 ; startupInfo.dwYSize = 0 ; startupInfo.dwXCountChars = 0 ; startupInfo.dwYCountChars = 0 ; startupInfo.dwFillAttribute = 0 ; startupInfo.dwFlags = system_noactive ? STARTF_USESHOWWINDOW : 0 ; startupInfo.wShowWindow = SW_SHOWMINNOACTIVE ; startupInfo.cbReserved2 = 0 ; startupInfo.lpReserved2 = 0 ; if (CreateProcess (NULL, s, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &procInfo) == FALSE) { buffer_message (mIDE, "Could not create process\n") ; buffer_message (mIDE, "\n") ; return (GetLastError ()) ; } if (no_shellout_wait == 0) { // now wait for the process to exit while (code == WAIT_TIMEOUT && no_shellout_wait == 0) { if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator (main_window, hAccelerators, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } code = WaitForSingleObject (procInfo.hProcess, 25) ; if (quit || stop_rendering) { GetExitCodeProcess (procInfo.hProcess, &code) ; if (code == STILL_ACTIVE) { // find out what the user wants to do with the process switch (MessageBox (main_window, message, quit ? "Exit POV-Ray" : "Stop rendering", MB_ICONQUESTION | MB_APPLMODAL | MB_YESNOCANCEL | MB_DEFBUTTON2)) { case IDYES : TerminateProcess (procInfo.hProcess, 1) ; break ; case IDNO : break ; case IDCANCEL : quit = FALSE ; stop_rendering = FALSE ; code = WAIT_TIMEOUT ; continue ; } } CloseHandle (procInfo.hProcess) ; CloseHandle (procInfo.hThread) ; buffer_message (mHorzLine, "\n") ; Terminate_POV (-1) ; } } GetExitCodeProcess (procInfo.hProcess, &code) ; } else code = 0 ; // clean up CloseHandle (procInfo.hProcess) ; CloseHandle (procInfo.hThread) ; buffer_message (mHorzLine, "\n") ; // code now has the application's return code return (code) ; } void WIN_SaveRerun (void) { write_rerun_information () ; PutPrivateProfileInt ("Statistics", "StartRender", time (NULL), CurrentRerunFileName) ; } void WIN_ParseINI (void) { if (!ignore_auto_ini) { parse_ini_file (DefaultRenderIniFileName) ; if (getenv("POVINI") == NULL) parse_ini_file ("povray.ini"); } } void WIN_Write_Line (COLOUR *line, int y) { } void WIN_Assign_Pixel (int x, int y, COLOUR colour) { ExternalAssignPixel (x, y, colour) ; } void WIN_PrintOtherCredits (void) { buffer_message (mIDE, "This is an UNSUPPORTED UNOFFICIAL COMPILE by " UNOFFICIALCOMPILE ".\n") ; } void PovMessageBox (char *message, char *title) { MessageBox (main_window, message, title, MB_ICONEXCLAMATION) ; } void detect_graphics_config (void) { HDC hdc ; hdc = GetDC (NULL) ; screen_depth = GetDeviceCaps (hdc, BITSPIXEL) ; render_bitmap_depth = (GetDeviceCaps (hdc, BITSPIXEL) > 8 && renderwin_8bits == 0) ? 24 : 8 ; screen_width = GetDeviceCaps (hdc, HORZRES) ; screen_height = GetDeviceCaps (hdc, VERTRES) ; ReleaseDC (NULL, hdc) ; } // Clear the system palette when we start to ensure an identity palette mapping void clear_system_palette (void) { int Counter ; HDC ScreenDC ; LogPal Palette = { 0x300, 256 } ; HPALETTE ScreenPalette ; // Reset everything in the system palette to black for (Counter = 0 ; Counter < 256 ; Counter++) { Palette.pe [Counter].peRed = 0 ; Palette.pe [Counter].peGreen = 0 ; Palette.pe [Counter].peBlue = 0 ; Palette.pe [Counter].peFlags = PC_NOCOLLAPSE ; } // Create, select, realize, deselect, and delete the palette ScreenDC = GetDC (NULL) ; ScreenPalette = CreatePalette ((LOGPALETTE *) &Palette) ; if (ScreenPalette) { ScreenPalette = SelectPalette (ScreenDC, ScreenPalette, FALSE) ; RealizePalette (ScreenDC) ; ScreenPalette = SelectPalette (ScreenDC, ScreenPalette, FALSE) ; DeleteObject (ScreenPalette) ; } ReleaseDC (NULL, ScreenDC) ; } BOOL FAR PASCAL PovAboutDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { struct stat st ; switch (message) { case WM_INITDIALOG : splash_show_about = 0 ; CenterWindowRelative ((HWND) lParam, hDlg, TRUE) ; FitWindowInWindow (NULL, hDlg) ; SendMessage (GetDlgItem (hDlg, IDC_VERSION), WM_SETTEXT, 0, (LPARAM) "Version " POV_RAY_VERSION COMPILER_VER "." PVENGINE_VER " [" OPTIMISATION " optimized]") ; return (TRUE) ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDOK : case IDCANCEL : EndDialog (hDlg, TRUE) ; return (TRUE) ; case IDC_READPOVLEGAL : // if help file is missing or something, default to internal viewer if (stat (engineHelpPath, &st) == 0) WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 0L) ; else DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_VIEW), hDlg, (DLGPROC) PovLegalDialogProc, (LPARAM) hDlg) ; return (TRUE) ; case IDC_SAVEPOVLEGAL : save_povlegal () ; return (TRUE) ; case IDC_ACCESSORIES : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 4L) ; return (TRUE) ; } break ; } return (FALSE) ; } BOOL FAR PASCAL PovCommandLineDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { char *s ; char str [_MAX_PATH * 2] ; char str1 [_MAX_PATH] ; char str2 [_MAX_PATH] ; struct stat statbuf1 ; struct stat statbuf2 ; static char editINIname [_MAX_PATH] ; static char editFilename [_MAX_PATH] ; static char lastIniFilename [_MAX_PATH] ; switch (message) { case WM_INITDIALOG : if (use_editors) { if ((EditGetFlags () & EDIT_MSG_SELECTED) == 0) { if ((s = EditGetFilename ()) != NULL) { EnableWindow (GetDlgItem (hDlg, IDC_PRESETSOURCEPATH), FALSE) ; EnableWindow (GetDlgItem (hDlg, IDC_PRESETSOURCENAME), FALSE) ; EnableWindow (GetDlgItem (hDlg, IDC_SOURCEDEFAULT), FALSE) ; EnableWindow (GetDlgItem (hDlg, IDC_BROWSESOURCEFILE), FALSE) ; EnableWindow (GetDlgItem (hDlg, IDC_EDITRENDER), FALSE) ; splitpath (s, lastRenderPath, lastRenderName) ; EnableWindow (GetDlgItem (hDlg, IDC_EDITRENDER), FALSE) ; } } SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, lastRenderPath) ; SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, lastRenderName) ; } else { SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, lastRenderPath) ; SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, lastRenderName) ; EnableWindow (GetDlgItem (hDlg, IDC_EDITRENDER), FALSE) ; EnableWindow (GetDlgItem (hDlg, IDC_EDITINI), FALSE) ; } SendDlgItemMessage (hDlg, IDC_PRESETSOURCENAME, EM_LIMITTEXT, 64, 0L) ; SendDlgItemMessage (hDlg, IDC_INIFILENAME, EM_LIMITTEXT, 64, 0L) ; strupr (SecondaryRenderIniFileName) ; validatePath (lastRenderPath) ; CenterWindowRelative ((HWND) lParam, hDlg, TRUE) ; FitWindowInWindow (NULL, hDlg) ; if (strlen (TempRegionStr)) { if (strlen (command_line)) { sprintf (str, command_line) ; strcat (str, TempRegionStr) ; } else strcpy (str, TempRegionStr + 1) ; strcpy (RegionStr, TempRegionStr) ; TempRegionStr [0] = '\0' ; SetDlgItemText (hDlg, IDC_COMMANDLINE, str) ; } else SetDlgItemText (hDlg, IDC_COMMANDLINE, command_line) ; splitpath (SecondaryRenderIniFileName, str1, str2) ; validatePath (str1) ; strcpy (editINIname, str2) ; SetDlgItemText (hDlg, IDC_INIFILEPATH, str1) ; SetDlgItemText (hDlg, IDC_INIFILENAME, str2) ; extract_ini_sections (SecondaryRenderIniFileName, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; SendMessage (toolbar_combobox, CB_GETLBTEXT, SendMessage (toolbar_combobox, CB_GETCURSEL, 0, 0), (LPARAM) SecondaryRenderIniFileSection) ; SendDlgItemMessage (hDlg, IDC_INIFILESECTION, CB_SELECTSTRING, -1, (LPARAM) SecondaryRenderIniFileSection) ; strcpy (lastIniFilename, SecondaryRenderIniFileName) ; stat (SecondaryRenderIniFileName, &statbuf1) ; return (TRUE) ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_INIFILESECTION : if (HIWORD (wParam) == CBN_SETFOCUS) { stat (lastIniFilename, &statbuf2) ; if (statbuf1.st_atime != statbuf2.st_atime) { statbuf1 = statbuf2 ; GetDlgItemText (hDlg, IDC_INIFILESECTION, str, sizeof (str)) ; extract_ini_sections (lastIniFilename, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; SendDlgItemMessage (hDlg, IDC_INIFILESECTION, CB_SELECTSTRING, -1, (LPARAM) str) ; } return (TRUE) ; } return (FALSE) ; case IDC_EDITRENDER : GetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, str1, sizeof (str1)) ; GetDlgItemText (hDlg, IDC_PRESETSOURCENAME, str2, sizeof (str2)) ; validatePath (str1) ; strcat (str1, "\\") ; strcat (str1, str2) ; if (EditOpenFile (str1)) { EndDialog (hDlg, FALSE) ; return (TRUE) ; } return (TRUE) ; case IDC_EDITINI : GetDlgItemText (hDlg, IDC_INIFILEPATH, str1, sizeof (str1)) ; GetDlgItemText (hDlg, IDC_INIFILENAME, str2, sizeof (str2)) ; validatePath (str1) ; strcat (str1, "\\") ; strcat (str1, str2) ; if (EditOpenFile (str1)) { EndDialog (hDlg, FALSE) ; return (TRUE) ; } return (TRUE) ; case IDC_BROWSEINIFILE : if ((s = get_ini_file (hDlg, lastSecondaryIniFilePath)) != NULL) { strupr (s) ; splitpath (s, str1, str2) ; validatePath (str1) ; SetDlgItemText (hDlg, IDC_INIFILEPATH, str1) ; SetDlgItemText (hDlg, IDC_INIFILENAME, str2) ; if (strcmp (s, lastIniFilename)) { extract_ini_sections (s, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; strcpy (lastIniFilename, s) ; stat (lastIniFilename, &statbuf1) ; } } return (TRUE) ; case IDC_INIFILENAME : if (HIWORD (wParam) == EN_KILLFOCUS) { GetDlgItemText (hDlg, IDC_INIFILEPATH, str1, sizeof (str1)) ; GetDlgItemText (hDlg, IDC_INIFILENAME, str2, sizeof (str2)) ; validatePath (str1) ; joinPath (str, str1, str2) ; if (stricmp (str, lastIniFilename)) { extract_ini_sections (str, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; strcpy (lastIniFilename, str) ; } return (TRUE) ; } if (HIWORD (wParam) == EN_UPDATE) { GetDlgItemText (hDlg, IDC_INIFILENAME, str, sizeof (str)) ; if (strchr (str, '\\') != NULL) SetDlgItemText (hDlg, IDC_INIFILENAME, editINIname) ; else strcpy (editINIname, str) ; } return (TRUE) ; case IDC_RESETINI : SetDlgItemText (hDlg, IDC_INIFILENAME, "") ; GetDlgItemText (hDlg, IDC_INIFILEPATH, lastIniFilename, sizeof (lastIniFilename)) ; SendMessage (GetDlgItem (hDlg, IDC_INIFILESECTION), CB_RESETCONTENT, 0, 0L) ; return (TRUE) ; case IDC_INIDEFAULT : sprintf (str, "%sRENDERER", HomePath) ; SetDlgItemText (hDlg, IDC_INIFILEPATH, str) ; SetDlgItemText (hDlg, IDC_INIFILENAME, "QUICKRES.INI") ; SendMessage (hDlg, WM_COMMAND, (EN_KILLFOCUS << 16) | IDC_INIFILENAME, 0L) ; return (TRUE) ; case IDC_PRESETSOURCENAME : if (HIWORD (wParam) == EN_UPDATE) { GetDlgItemText (hDlg, IDC_PRESETSOURCENAME, str, sizeof (str)) ; if (strchr (str, '\\') != NULL) SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, editFilename) ; else strcpy (editFilename, str) ; } return (TRUE) ; case IDC_BROWSESOURCEFILE : if ((s = file_open (hDlg)) != NULL) { splitpath (s, str1, str2) ; validatePath (str1) ; SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, str1) ; SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, str2) ; } return (TRUE) ; case IDC_SOURCEDEFAULT : sprintf (str, "%sSCENES\\OBJECTS", HomePath) ; SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, str) ; SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, "TORUS1.POV") ; return (TRUE) ; case IDC_SET : case IDC_RENDER : if (!running_demo) { GetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, lastRenderPath, sizeof (lastRenderPath)) ; GetDlgItemText (hDlg, IDC_PRESETSOURCENAME, lastRenderName, sizeof (lastRenderName)) ; validatePath (lastRenderPath) ; // strupr (lastRenderPath) ; // strupr (lastRenderName) ; joinPath (source_file_name, lastRenderPath, lastRenderName) ; } GetDlgItemText (hDlg, IDC_INIFILEPATH, str1, sizeof (str1)) ; GetDlgItemText (hDlg, IDC_INIFILENAME, str2, sizeof (str2)) ; validatePath (str1) ; strcpy (lastSecondaryIniFilePath, str1) ; joinPath (SecondaryRenderIniFileName, str1, str2) ; strupr (SecondaryRenderIniFileName) ; GetDlgItemText (hDlg, IDC_INIFILESECTION, SecondaryRenderIniFileSection, sizeof (SecondaryRenderIniFileSection)) ; GetDlgItemText (hDlg, IDC_COMMANDLINE, command_line, sizeof (command_line)) ; extract_ini_sections_ex (SecondaryRenderIniFileName, toolbar_combobox) ; select_combo_item_ex (toolbar_combobox, SecondaryRenderIniFileSection) ; if (LOWORD (wParam) == IDC_RENDER) { if (EditSaveModified (NULL) == 0) return (TRUE) ; EndDialog (hDlg, TRUE) ; } else EndDialog (hDlg, FALSE) ; return (TRUE) ; case IDC_CONTEXTHELP : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 1L) ; return (TRUE) ; case IDCANCEL : EndDialog (hDlg, FALSE) ; return (TRUE) ; } break ; } return (FALSE) ; } BOOL FAR PASCAL PovShortCommandLineDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG : CenterWindowRelative ((HWND) lParam, hDlg, TRUE) ; FitWindowInWindow (NULL, hDlg) ; SetDlgItemText (hDlg, IDC_COMMANDLINE, command_line) ; return (TRUE) ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_RENDER : GetDlgItemText (hDlg, IDC_COMMANDLINE, command_line, sizeof (command_line) - 1) ; EndDialog (hDlg, TRUE) ; return (TRUE) ; case IDC_SET : GetDlgItemText (hDlg, IDC_COMMANDLINE, command_line, sizeof (command_line) - 1) ; EndDialog (hDlg, FALSE) ; return (TRUE) ; case IDCANCEL : EndDialog (hDlg, FALSE) ; return (TRUE) ; case IDC_COMMANDHELP : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 1L) ; return (TRUE) ; } break ; } return (FALSE) ; } BOOL FAR PASCAL PovFileQueueDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { int i ; char str [64] ; HWND hlb ; DRAWITEMSTRUCT *d ; MEASUREITEMSTRUCT *m ; static HBRUSH hbr ; switch (message) { case WM_CTLCOLORLISTBOX : return ((BOOL) hbr) ; case WM_INITDIALOG : CenterWindowRelative ((HWND) lParam, hDlg, TRUE) ; FitWindowInWindow (NULL, hDlg) ; hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; hbr = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)) ; for (i = 0 ; i < queued_file_count ; i++) SendMessage (hlb, LB_ADDSTRING, 0, (LPARAM) queued_files [i]) ; sprintf (str, "Queue has %d entr%s", queued_file_count, queued_file_count != 1 ? "ies" : "y") ; SetDlgItemText (hDlg, IDC_QUEUEENTRIES, str) ; CheckDlgButton (hDlg, IDC_RELOADQUEUE, GetPrivateProfileInt ("FileQueue", "ReloadOnStartup", 0, EngineIniFileName)) ; CheckDlgButton (hDlg, IDC_AUTORENDER, auto_render) ; return (TRUE) ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDOK : hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; queued_file_count = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; if (queued_file_count > MAX_QUEUE) queued_file_count = MAX_QUEUE ; for (i = 0 ; i < queued_file_count ; i++) SendMessage (hlb, LB_GETTEXT, i, (LPARAM) queued_files [i]) ; auto_render = IsDlgButtonChecked (hDlg, IDC_AUTORENDER) ; PVCheckMenuItem (CM_AUTORENDER, auto_render ? MF_CHECKED : MF_UNCHECKED) ; PutPrivateProfileInt ("FileQueue", "ReloadOnStartup", IsDlgButtonChecked (hDlg, IDC_RELOADQUEUE), EngineIniFileName) ; update_queue_status (TRUE) ; DeleteObject (hbr) ; EndDialog (hDlg, TRUE) ; return (TRUE) ; case IDCANCEL : DeleteObject (hbr) ; EndDialog (hDlg, TRUE) ; return (TRUE) ; case IDC_DELETEFILE : hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; if ((i = SendMessage (hlb, LB_GETCURSEL, 0, 0)) != LB_ERR) { SendMessage (hlb, LB_DELETESTRING, i, 0) ; if (i) i-- ; SendMessage (hlb, LB_SETCURSEL, i, 0) ; } i = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; sprintf (str, "Queue will have %d entr%s", i, i != 1 ? "ies" : "y") ; SetDlgItemText (hDlg, IDC_QUEUEENTRIES, str) ; return (TRUE) ; case IDC_ADDFILE : hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; add_queue (hDlg, hlb) ; i = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; sprintf (str, "Queue will have %d entr%s", i, i != 1 ? "ies" : "y") ; SetDlgItemText (hDlg, IDC_QUEUEENTRIES, str) ; return (TRUE) ; case IDC_CONTEXTHELP : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 1L) ; return (TRUE) ; } break ; case WM_MEASUREITEM : if (wParam == IDC_FILEQUEUE) { m = (MEASUREITEMSTRUCT *) lParam ; m->itemHeight = listbox_ychar ; return (TRUE) ; } else return (FALSE) ; case WM_DRAWITEM : if (wParam == IDC_FILEQUEUE) { d = (DRAWITEMSTRUCT *) lParam ; draw_ordinary_listbox (d) ; return (TRUE) ; } else return (FALSE) ; } return (FALSE) ; } BOOL FAR PASCAL PovStatisticsDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { unsigned long *data = (unsigned long *) lParam ; HWND hlb ; DRAWITEMSTRUCT *d ; MEASUREITEMSTRUCT *m ; static HBRUSH hbr ; switch (message) { case WM_CTLCOLORLISTBOX : return ((BOOL) hbr) ; case WM_INITDIALOG : resize_listbox_dialog (hDlg, IDC_LISTBOX, 76) ; CenterWindowRelative ((HWND) data [0], hDlg, TRUE) ; FitWindowInWindow (NULL, hDlg) ; SetWindowText (hDlg, "Render Statistics") ; hlb = GetDlgItem (hDlg, IDC_LISTBOX) ; hbr = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)) ; fill_statistics_listbox (hlb, (int) data [1]) ; return (TRUE) ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDOK : case IDCANCEL : DeleteObject (hbr) ; EndDialog (hDlg, 0) ; return (TRUE) ; } break ; case WM_MEASUREITEM : if (wParam == IDC_LISTBOX) { m = (MEASUREITEMSTRUCT *) lParam ; m->itemHeight = listbox_ychar ; return (TRUE) ; } else return (FALSE) ; case WM_DRAWITEM : if (wParam == IDC_LISTBOX) { d = (DRAWITEMSTRUCT *) lParam ; d->itemState &= ~ODS_SELECTED ; draw_ordinary_listbox (d) ; return (TRUE) ; } else return (FALSE) ; } return (FALSE) ; } BOOL FAR PASCAL PovRerunDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { int selItem ; unsigned long data [2] ; HWND hlb ; DRAWITEMSTRUCT *d ; MEASUREITEMSTRUCT *m ; static char rerunID [MAX_RERUN] ; static HBRUSH hbr ; switch (message) { case WM_CTLCOLORLISTBOX : return ((BOOL) hbr) ; case WM_INITDIALOG : hlb = GetDlgItem (hDlg, IDC_RERUNLIST) ; fill_rerun_listbox (hlb, rerunID) ; SendMessage (hlb, LB_SETCURSEL, 0, 0) ; CenterWindowRelative ((HWND) lParam, hDlg, TRUE) ; FitWindowInWindow (NULL, hDlg) ; hbr = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)) ; if (rendering) EnableWindow (GetDlgItem (hDlg, IDC_RERUN), FALSE) ; return (TRUE) ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDCANCEL : DeleteObject (hbr) ; EndDialog (hDlg, 0) ; return (TRUE) ; case IDC_RERUN : selItem = SendDlgItemMessage (hDlg, IDC_RERUNLIST, LB_GETCURSEL, 0, 0) ; if (!rendering && selItem != LB_ERR) { DeleteObject (hbr) ; EndDialog (hDlg, rerunID [selItem] + 2) ; } return (TRUE) ; case IDC_RERUNLIST : if (HIWORD (wParam) == LBN_DBLCLK) { selItem = SendMessage ((HWND) lParam, LB_GETCURSEL, 0, 0) ; if (!rendering && selItem != LB_ERR) { DeleteObject (hbr) ; EndDialog (hDlg, rerunID [selItem] + 2) ; } } return (TRUE) ; case IDC_STATISTICS : selItem = SendDlgItemMessage (hDlg, IDC_RERUNLIST, LB_GETCURSEL, 0, 0) ; if (selItem != LB_ERR) { data [0] = (unsigned long) hDlg ; data [1] = (unsigned long) rerunID [selItem] ; DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_VIEW), hDlg, (DLGPROC) PovStatisticsDialogProc, (LPARAM) data) ; } return (TRUE) ; case IDC_CONTEXTHELP : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 2L) ; return (TRUE) ; } break ; case WM_MEASUREITEM : if (wParam == IDC_RERUNLIST) { m = (MEASUREITEMSTRUCT *) lParam ; m->itemHeight = listbox_ychar ; return (TRUE) ; } else return (FALSE) ; case WM_DRAWITEM : if (wParam == IDC_RERUNLIST) { d = (DRAWITEMSTRUCT *) lParam ; draw_rerun_listbox (d) ; return (TRUE) ; } else return (FALSE) ; } return (FALSE) ; } void CalculateClientWindows (BOOL redraw) { RECT rect ; GetClientRect (main_window, &rect) ; rect.left = 0 ; rect.top = toolheight ; rect.bottom -= toolheight + statusheight - 1 ; if (!use_editors) { MoveWindow (message_window, rect.left, toolheight, rect.right - rect.left + 1, rect.bottom, FALSE) ; PovInvalidateRect (message_window, NULL, redraw) ; } else SetEditorPosition (rect.left, toolheight, rect.right - rect.left + 1, rect.bottom) ; } /* ** Return TRUE if we are to return 0 to Windows, FALSE if we are to continue. */ BOOL handle_main_command (WPARAM wParam, LPARAM lParam) { int n ; char *s ; char filename [_MAX_PATH] ; HDIB hDIB ; HWND oldHwnd ; RECT rect ; BITMAP bm ; HBITMAP hBMP ; //pvncStruct pvnc ; CHOOSECOLOR cc ; struct stat st ; static char str1 [_MAX_PATH] ; static char str2 [_MAX_PATH] ; if (process_toggles (wParam)) return (TRUE) ; if (LOWORD (wParam) >= CM_FIRSTTOOL && LOWORD (wParam) <= CM_LASTTOOL) { s = parse_tool_command (tool_commands [LOWORD (wParam) - CM_FIRSTTOOL]) ; if (GetPrivateProfileInt ("General", "Debug", 0, ToolIniFileName)) message_printf ("Tool request - in '%s', out '%s'\n", tool_commands [LOWORD (wParam) - CM_FIRSTTOOL], s) ; else execute_tool (s) ; return (TRUE) ; } if (LOWORD (wParam) >= CM_FIRSTEDITNOTIFY && LOWORD (wParam) <= CM_LASTEDITNOTIFY) { switch (LOWORD (wParam) - CM_FIRSTEDITNOTIFY) { case NotifyTabChange : if ((lParam & EDIT_MSG_SELECTED) == 0) { build_editor_menu (hMainMenu) ; PVEnableMenuItem (CM_FILESAVE, (lParam & EDIT_CURRENT_MODIFIED) ? MF_ENABLED : MF_GRAYED) ; if (strlen (EditGetFilename ()) != 0) { sprintf (str1, "POV-Ray - %s", EditGetFilename ()) ; SetWindowText (main_window, str1) ; } else SetWindowText (main_window, "POV-Ray for Windows") ; } else { build_main_menu (hMainMenu, TRUE) ; PVEnableMenuItem (CM_FILESAVE, MF_GRAYED) ; SetWindowText (main_window, "POV-Ray for Windows") ; } break ; case NotifyModifiedChange : PVEnableMenuItem (CM_FILESAVE, lParam ? MF_ENABLED : MF_GRAYED) ; break ; } return (TRUE) ; } switch (LOWORD (wParam)) { case CM_SHOWMAINWINDOW : if (main_window_hidden) { ShowWindow (main_window, SW_SHOW) ; if (render_window) ShowWindow (render_window, SW_SHOW) ; PVModifyMenu (CM_SHOWMAINWINDOW, MF_STRING, CM_SHOWMAINWINDOW, "Minimize to System &Tray\tAlt+W") ; main_window_hidden = 0 ; TaskBarDeleteIcon (main_window, 0) ; return (0) ; } if (use_taskbar) { if (TaskBarAddIcon (main_window, 0, ourIcon, "POV-Ray (double-click to restore, right button for menu)")) { ShowWindow (main_window, SW_HIDE) ; if ((render_above_main || hide_render_window) && render_window != NULL) ShowWindow (render_window, SW_HIDE) ; PVModifyMenu (CM_SHOWMAINWINDOW, MF_STRING, CM_SHOWMAINWINDOW, "Restore &Main Window from System Tray") ; main_window_hidden++ ; return (0) ; } } return (0) ; case CM_FILENEW : EditOpenFile (NULL) ; return (0) ; case CM_FILEOPEN : EditBrowseFile (TRUE) ; return (0) ; case CM_FILESAVE : EditSaveFile (NULL) ; return (0) ; case CM_FILECLOSE : EditCloseFile (NULL) ; return (0) ; case CM_RENDERSLEEP : if (!(rendersleep = SendMessage (toolbar_window, TB_ISBUTTONCHECKED, (WPARAM) CM_RENDERSLEEP, 0L))) { SetWindowText (main_window, "POV-Ray for Windows") ; FlashWindow (main_window, 0) ; } else SetWindowText (main_window, "POV-Ray - render paused") ; break ; case CM_DROPEDITOR : case CM_DROPRENDERER : PVCheckMenuItem (CM_DROPEDITOR, LOWORD (wParam) == CM_DROPEDITOR ? MF_CHECKED : MF_UNCHECKED) ; PVCheckMenuItem (CM_DROPRENDERER, LOWORD (wParam) == CM_DROPRENDERER ? MF_CHECKED : MF_UNCHECKED) ; drop_to_editor = LOWORD (wParam) == CM_DROPEDITOR ; break ; case CM_GUIPRIORITY_LOWEST : case CM_GUIPRIORITY_LOW : case CM_GUIPRIORITY_NORMAL : case CM_GUIPRIORITY_HIGH : case CM_GUIPRIORITY_HIGHEST : PVCheckMenuItem (GUI_priority, MF_UNCHECKED) ; GUI_priority = LOWORD (wParam) ; PVCheckMenuItem (LOWORD (wParam), MF_CHECKED) ; // only change GUI priority when the renderer is running if (hRenderThread != NULL) set_GUI_priority (GUI_priority) ; return (TRUE) ; case CM_RENDERPRIORITY_LOWEST : case CM_RENDERPRIORITY_LOW : case CM_RENDERPRIORITY_NORMAL : case CM_RENDERPRIORITY_HIGH : case CM_RENDERPRIORITY_HIGHEST : PVCheckMenuItem (render_priority, MF_UNCHECKED) ; render_priority = LOWORD (wParam) ; PVCheckMenuItem (LOWORD (wParam), MF_CHECKED) ; if (hRenderThread != NULL) set_render_priority (render_priority) ; return (TRUE) ; case CM_COMPLETION_EXIT : case CM_COMPLETION_BEEP : case CM_COMPLETION_NOTHING : case CM_COMPLETION_MESSAGE : case CM_COMPLETION_BEEPMESSAGE : PVCheckMenuItem (on_completion, MF_UNCHECKED) ; on_completion = LOWORD (wParam) ; PVCheckMenuItem (on_completion, MF_CHECKED) ; return (TRUE) ; case CM_PREVWINDOW : EditNextTab (FALSE) ; return (TRUE) ; case CM_NEXTWINDOW : EditNextTab (TRUE) ; return (TRUE) ; case CM_USETOOLBAR : if (rebar_window == NULL) return (TRUE) ; ShowWindow (rebar_window, use_toolbar ? SW_SHOW : SW_HIDE) ; // this seems to be needed to get the rebar to redraw properly with v4.72 of comctrl32.dll. InvalidateRect (main_window, NULL, TRUE) ; toolheight = 0 ; GetClientRect (main_window, &rect) ; SendMessage (main_window, WM_SIZE, SIZE_RESTORED, MAKELPARAM (rect.right + 1, rect.bottom + 1)) ; return (TRUE) ; case CM_USERENDERANIM : use_renderanim = !use_renderanim ; InvalidateRect (renderanim_window, NULL, TRUE) ; return (TRUE) ; case CM_SINGLEINSTANCE : PutPrivateProfileInt ("General", "OneInstance", one_instance, EngineIniFileName) ; return (TRUE) ; case CM_FILEEXIT : if (rendering || hRenderThread) { if (MessageBox (main_window, "POV-Ray is currently rendering - do you want to stop ?", "Stop rendering ?", MB_ICONQUESTION | MB_YESNO) == IDYES) { if (!EditCanClose (TRUE)) return (TRUE) ; quit = TRUE ; } } else { if (!EditCanClose (TRUE)) return (TRUE) ; WinHelp (main_window, "pvengine.hlp", HELP_QUIT, NULL) ; WinHelp (main_window, "povray31.hlp", HELP_QUIT, NULL) ; DestroyWindow (main_window) ; } return (TRUE) ; case CM_FILERENDER : case CM_STOPRENDER : if (!rendering && !hRenderThread) { if (EditSaveModified (NULL) == 0) return (TRUE) ; // EDIT_MSG_SELECTED is only ever set if use_editors == TRUE if ((EditGetFlags () & EDIT_MSG_SELECTED) == 0) { if ((s = EditGetFilename ()) == NULL) { PovMessageBox ("No file to render in current editor tab!", "Cannot render") ; return (TRUE) ; } n = get_file_type (s) ; if (n == filePOV || n == fileINI || !ExternalDragFunction (s, dfRenderEditor)) PostMessage (main_window, EDITOR_RENDER_MESSAGE, 0, (LPARAM) s) ; return (TRUE) ; } SetForegroundWindow (main_window) ; if (!ExternalDragFunction (source_file_name, dfRenderMessage)) start_rendering (FALSE, FALSE) ; } else stop_rendering = TRUE ; return (TRUE) ; case CM_SAVE_SETTINGS : PutPrivateProfileInt ("General", "SaveSettingsOnExit", save_settings, EngineIniFileName) ; return (TRUE) ; case CM_DUMPPANE : dump_pane_to_clipboard () ; return (TRUE) ; case CM_CLEARMESSAGES : clear_messages () ; PovInvalidateRect (message_window, NULL, FALSE) ; UpdateWindow (message_window) ; return (TRUE) ; case CM_FORCE8BITS : detect_graphics_config () ; if (hPalApp) DeleteObject (hPalApp) ; hPalApp = create_palette (NULL, 0) ; buffer_message (mIDE, render_bitmap_depth == 24 ? "Using 24-bit internal bitmap\n" : renderwin_8bits ? "Using 8-bit dithered internal bitmap (menu setting)\n" : "Using 8-bit dithered internal bitmap (4 or 8-bit video mode)\n") ; return (TRUE) ; case CM_RENDERABOVEMAIN : // simply re-parenting doesn't seem to have the desired effect. sigh. if (render_window != NULL) { oldHwnd = render_window ; render_window = NULL ; ShowWindow (oldHwnd, SW_HIDE) ; SetForegroundWindow (main_window) ; DestroyWindow (oldHwnd) ; create_render_window () ; } PVEnableMenuItem (CM_RENDERHIDE, render_above_main ? MF_GRAYED : MF_ENABLED) ; return (TRUE) ; case CM_USEEDITOR : if (MessageBox (main_window, "POV-Ray for Windows needs to re-start for this to take effect.\n\n" "Re-start POV-ray ?", "Re-start POV-Ray for Windows ?", MB_ICONEXCLAMATION | MB_YESNO) == IDYES) { PutPrivateProfileInt ("General", "UseEditors", !use_editors, EngineIniFileName) ; GetModuleFileName (hInstance, filename, sizeof (filename) - 1) ; if (save_settings) { SendMessage (toolbar_combobox, CB_GETLBTEXT, SendMessage (toolbar_combobox, CB_GETCURSEL, 0, 0), (LPARAM) SecondaryRenderIniFileSection) ; if (restore_command_line) strcpy (command_line, old_command_line) ; write_INI_settings (EngineIniFileName) ; EditSaveState () ; } DestroyWindow (main_window) ; execute_tool (filename) ; } return (TRUE) ; case CM_HELPABOUT : if (splash_show_about) return (TRUE) ; splash_show_about = TRUE ; SplashScreen (main_window) ; return (TRUE) ; case CM_SHOWNEXTTIP : DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_TIP), main_window, (DLGPROC) PovTipDialogProc, (LPARAM) main_window) ; return (TRUE) ; case CM_COMMANDLINE : if (!rendering && !hRenderThread) { if (DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_COMMANDLINE), main_window, (DLGPROC) PovCommandLineDialogProc, (LPARAM) main_window)) { if (!ExternalDragFunction (source_file_name, dfRenderCommandLine)) start_rendering (FALSE, FALSE) ; } } return (TRUE) ; case CM_TILEDBACKGROUND : PVModifyMenu (CM_TILEDBACKGROUND, MF_STRING, CM_TILEDBACKGROUND, tile_background ? "&Select Plain Background" : "&Select Tiled Background") ; if (tile_background && hBmpBackground == NULL) { if ((hBmpBackground = NonBogusLoadBitmap (hInstance, MAKEINTRESOURCE (BMP_BACKGROUND00))) != NULL) { GetObject (hBmpBackground, sizeof (BITMAP), (LPSTR) &bm) ; background_width = bm.bmWidth ; background_height = bm.bmHeight ; tile_background = TRUE ; PovInvalidateRect (message_window, NULL, TRUE) ; } else { tile_background = FALSE ; // make sure this messagebox is AFTER we set tile_background to false ! PovMessageBox ("Failed to load internal bitmap", "Error") ; PVModifyMenu (CM_TILEDBACKGROUND, MF_STRING, CM_TILEDBACKGROUND, "&Select Tiled Background") ; background_file [0] = '\0' ; } return (TRUE) ; } else PovInvalidateRect (message_window, NULL, TRUE) ; return (TRUE) ; case CM_BACKGROUNDCOLOUR : memset (&cc, 0, sizeof (CHOOSECOLOR)) ; cc.lStructSize = sizeof (CHOOSECOLOR) ; cc.hwndOwner = main_window ; cc.rgbResult = background_colour ; cc.Flags = CC_PREVENTFULLOPEN | CC_RGBINIT ; cc.lpCustColors = custom_colours ; if (ChooseColor (&cc)) { background_colour = cc.rgbResult ; PovInvalidateRect (message_window, NULL, TRUE) ; } return (TRUE) ; case CM_BACKGROUNDBITMAP : if ((s = get_background_file (main_window)) != NULL) { if ((hDIB = LoadDIB (s)) != NULL) { strcpy (background_file, s) ; DeleteObject (hBmpBackground) ; hBmpBackground = DIBToBitmap (hDIB, hPalApp) ; DeleteObject (hDIB) ; GetObject (hBmpBackground, sizeof (BITMAP), (LPSTR) &bm) ; background_width = bm.bmWidth ; background_height = bm.bmHeight ; tile_background = TRUE ; PVModifyMenu (CM_TILEDBACKGROUND, MF_STRING, CM_TILEDBACKGROUND, "&Select Plain Background") ; background_shade = RGB (1, 1, 1) ; PovInvalidateRect (message_window, NULL, TRUE) ; } else PovMessageBox ("Failed to load bitmap file", "Error") ; } return (TRUE) ; case CM_BACKGROUNDSTD + 0 : case CM_BACKGROUNDSTD + 1 : case CM_BACKGROUNDSTD + 2 : case CM_BACKGROUNDSTD + 3 : case CM_BACKGROUNDSTD + 4 : case CM_BACKGROUNDSTD + 5 : case CM_BACKGROUNDSTD + 6 : case CM_BACKGROUNDSTD + 7 : case CM_BACKGROUNDSTD + 8 : case CM_BACKGROUNDSTD + 9 : if ((hBMP = NonBogusLoadBitmap (hInstance, MAKEINTRESOURCE (BMP_BACKGROUND00 + (LOWORD (wParam) - CM_BACKGROUNDSTD)))) != NULL) { DeleteObject (hBmpBackground) ; hBmpBackground = hBMP ; GetObject (hBmpBackground, sizeof (BITMAP), (LPSTR) &bm) ; background_width = bm.bmWidth ; background_height = bm.bmHeight ; background_file [0] = '0' + (char) (LOWORD (wParam) - CM_BACKGROUNDSTD) ; background_file [1] = '\0' ; switch (LOWORD (wParam)) { case CM_BACKGROUNDSTD + 0 : background_shade = RGB (1, 1, 1) ; if (lParam != 1) text_colour = RGB (255, 255, 255) ; break ; case CM_BACKGROUNDSTD + 1 : background_shade = RGB (0, 0, 0) ; if (lParam != 1) text_colour = RGB (255, 255, 255) ; break ; case CM_BACKGROUNDSTD + 2 : background_shade = RGB (1, 1, 1) ; if (lParam != 1) text_colour = RGB (255, 255, 255) ; break ; case CM_BACKGROUNDSTD + 3 : background_shade = RGB (1, 1, 1) ; if (lParam != 1) text_colour = RGB (255, 255, 255) ; break ; case CM_BACKGROUNDSTD + 4 : background_shade = RGB (1, 1, 1) ; if (lParam != 1) text_colour = RGB (255, 255, 255) ; break ; case CM_BACKGROUNDSTD + 5 : background_shade = RGB (1, 1, 1) ; if (lParam != 1) text_colour = RGB (0, 0, 0) ; break ; } tile_background = TRUE ; PVModifyMenu (CM_TILEDBACKGROUND, MF_STRING, CM_TILEDBACKGROUND, "&Select Plain Background") ; PovInvalidateRect (message_window, NULL, TRUE) ; } else PovMessageBox ("Failed to load internal bitmap", "Error") ; return (TRUE) ; case CM_TEXTCOLOUR : memset (&cc, 0, sizeof (CHOOSECOLOR)) ; cc.lStructSize = sizeof (CHOOSECOLOR) ; cc.hwndOwner = main_window ; cc.rgbResult = text_colour ; cc.Flags = CC_PREVENTFULLOPEN | CC_RGBINIT ; cc.lpCustColors = custom_colours ; if (ChooseColor (&cc)) { text_colour = cc.rgbResult ; PovInvalidateRect (message_window, NULL, TRUE) ; } return (TRUE) ; case CM_FONT : get_font () ; return (TRUE) ; case CM_RENDERSHOW : if (renderwin_destroyed) { create_render_window () ; PVEnableMenuItem (CM_RENDERSHOW, MF_GRAYED) ; PVEnableMenuItem (CM_RENDERCLOSE, MF_ENABLED) ; renderwin_destroyed = FALSE ; } return (TRUE) ; case CM_RENDERCLOSE : if (render_above_main && GetForegroundWindow () == render_window) SetForegroundWindow (main_window) ; if (render_window != NULL) DestroyWindow (render_window) ; return (TRUE) ; case CM_CLEARQUEUE : queued_file_count = 0 ; update_queue_status (TRUE) ; return (TRUE) ; case CM_FILEQUEUE : DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_FILEQUEUE), main_window, (DLGPROC) PovFileQueueDialogProc, (LPARAM) main_window) ; return (TRUE) ; case CM_SOURCEFILE : if (!rendering && !hRenderThread) { if ((s = file_open (main_window)) != NULL) { strcpy (source_file_name, s) ; splitpath (source_file_name, lastRenderPath, lastRenderName) ; validatePath (lastRenderPath) ; if (!ExternalDragFunction (source_file_name, dfRenderSourceFile)) start_rendering (FALSE, FALSE) ; } } return (TRUE) ; case CM_RERUN + 0 : case CM_RERUN + 1 : case CM_RERUN + 2 : case CM_RERUN + 3 : case CM_RERUN + 4 : case CM_RERUN + 5 : case CM_RERUN + 6 : case CM_RERUN + 7 : case CM_RERUN + 8 : case CM_RERUN + 9 : case CM_RERUN + 10 : case CM_RERUN + 11 : case CM_RERUN + 12 : case CM_RERUN + 13 : case CM_RERUN + 14 : case CM_RERUN + 15 : if (!rendering && !hRenderThread) { loadRerun = LOWORD (wParam) - CM_RERUN + 2 ; if (DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_SHORTCOMMANDLINE), main_window, (DLGPROC) PovShortCommandLineDialogProc, (LPARAM) main_window)) start_rendering (FALSE, FALSE) ; } return (TRUE) ; case CM_RERUNCURRENT : if (!rendering && !hRenderThread) { loadRerun = 1 ; if (DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_SHORTCOMMANDLINE), main_window, (DLGPROC) PovShortCommandLineDialogProc, (LPARAM) main_window)) start_rendering (FALSE, FALSE) ; } return (TRUE) ; case CM_CONTINUECURRENT : if (!rendering && !hRenderThread) { loadRerun = 1 ; continueRerun = 1 ; start_rendering (FALSE, FALSE) ; } return (TRUE) ; case CM_RERUNDIALOG : if ((loadRerun = DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_RERUN), main_window, (DLGPROC) PovRerunDialogProc, (LPARAM) main_window)) != 0) if (DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_SHORTCOMMANDLINE), main_window, (DLGPROC) PovShortCommandLineDialogProc, (LPARAM) main_window)) start_rendering (FALSE, FALSE) ; return (TRUE) ; case CM_DEMO : if (!rendering && !hRenderThread) { if (save_demo_file (str1, str2) != NULL) { if (!demo_mode) { running_demo = TRUE ; if (DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_SHORTCOMMANDLINE), main_window, (DLGPROC) PovShortCommandLineDialogProc, (LPARAM) main_window)) { if (!restore_command_line) strcpy (old_command_line, command_line) ; restore_command_line = TRUE ; sprintf (command_line, "\"Include_Ini=%s\" \"Input_File_Name=%s\" ", str2, str1) ; strupr (command_line) ; strcat (command_line, old_command_line) ; ignore_auto_ini = TRUE ; start_rendering (FALSE, TRUE) ; ignore_auto_ini = FALSE ; strcpy (command_line, old_command_line) ; restore_command_line = FALSE ; } running_demo = FALSE ; } else { if (!restore_command_line) strcpy (old_command_line, command_line) ; restore_command_line = TRUE ; sprintf (command_line, "\"Include_Ini=%s\" \"Input_File_Name=%s\" ", str2, str1) ; running_demo = TRUE ; start_rendering (FALSE, TRUE) ; running_demo = FALSE ; strcpy (command_line, old_command_line) ; restore_command_line = FALSE ; } unlink (str1) ; unlink (str2) ; } } return (TRUE) ; case CM_LOADTOOLMENU : ExternalEvent (EventLoadToolMenu, 0) ; load_tool_menu (ToolIniFileName) ; break ; case CM_HELPCONTENTS : WinHelp (main_window, engineHelpPath, HELP_INDEX, 0L) ; return (TRUE) ; case CM_HELPCOMPUSERVE : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 8L) ; return (TRUE) ; case CM_GOPOVRAY : execute_tool ("gocserve povray") ; return (TRUE) ; case CM_GOPOVRAYORG : ShellExecute (NULL, NULL, "http://www.povray.org/", NULL, NULL, SW_SHOWNORMAL) ; return (TRUE) ; case CM_GOIRTC : ShellExecute (NULL, NULL, "http://www.irtc.org/", NULL, NULL, SW_SHOWNORMAL) ; return (TRUE) ; case CM_HELPBUGS : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 5L) ; return (TRUE) ; case CM_HELPPOVCD : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 7L) ; return (TRUE) ; case CM_HELPIRTCCD : WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 6L) ; return (TRUE) ; case CM_POVLEGAL : if (stat (engineHelpPath, &st) == 0) WinHelp (main_window, engineHelpPath, HELP_CONTEXT, 0L) ; else DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_VIEW), main_window, (DLGPROC) PovLegalDialogProc, (LPARAM) main_window) ; return (TRUE) ; case CM_HELPPOVRAY : WinHelp (main_window, rendererHelpPath, HELP_INDEX, 0L) ; return (TRUE) ; case CM_HELPUSING_HELP : WinHelp (main_window, engineHelpPath, HELP_HELPONHELP, 0L) ; return (TRUE) ; case CM_HELPLOOKUP : if ((EditGetFlags () & EDIT_MSG_SELECTED) == 0) EditContextHelp () ; return (TRUE) ; } return (FALSE) ; } LRESULT CALLBACK PovRenderWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int dest_width ; int dest_height ; int dest_xoffset ; int dest_yoffset ; int oldMode ; int x1 ; int y1 ; int x2 ; int y2 ; HDC hdc ; HDC hdcMemory ; RECT rect ; HPEN hpen ; char str [512] ; char *s ; POINT pt ; POINT pts [5] ; HBITMAP oldBmp ; MINMAXINFO *pInfo ; PAINTSTRUCT ps ; static HBITMAP errorBitmap = NULL ; static int RBand = 0 ; static POINT RB1 ; static POINT RB2 ; switch (message) { case WM_USER : DestroyWindow (hwnd) ; return (0) ; case WM_CREATE : PVEnableMenuItem (CM_RENDERSHOW, MF_GRAYED) ; PVEnableMenuItem (CM_RENDERCLOSE, MF_ENABLED) ; RBand = 0 ; break ; case WM_COMMAND : if (handle_main_command (wParam, lParam)) return (0) ; break ; case WM_LBUTTONDOWN : if (rendering) { MessageBeep (-1) ; return (0) ; } RBand = 1 ; if ((wParam & MK_SHIFT) != 0) RBand++ ; RB1.x = LOWORD (lParam) ; RB1.y = HIWORD (lParam) ; RB2 = RB1 ; SetCapture (hwnd) ; return (0) ; case WM_LBUTTONUP : case WM_MOUSEMOVE : if (RBand) { hdc = GetDC (hwnd) ; pts [0] = RB1 ; pts [1] = RB1 ; pts [1].x = RB2.x ; pts [2] = RB2 ; pts [3] = RB2 ; pts [3].x = RB1.x ; pts [4] = RB1 ; hpen = CreatePen (PS_DASHDOT, 1, RGB (128, 128, 128)) ; hpen = SelectObject (hdc, hpen) ; oldMode = SetROP2 (hdc, R2_XORPEN) ; Polyline (hdc, pts, 5) ; x2 = RB2.x = LOWORD (lParam) ; y2 = RB2.y = HIWORD (lParam) ; x2 += renderwin_xoffset ; y2 += renderwin_xoffset ; x1 = RB1.x + renderwin_xoffset ; y1 = RB1.y + renderwin_yoffset ; if (x1 > x2) x1 ^= x2 ^= x1 ^= x2 ; if (y1 > y2) y1 ^= y2 ^= y1 ^= y2 ; GetClientRect (hwnd, &rect) ; if (rect.right > render_width || rect.bottom > render_height) { x1 = MulDiv (x1, render_width, rect.right) ; x2 = MulDiv (x2, render_width, rect.right) ; y1 = MulDiv (y1, render_height, rect.bottom) ; y2 = MulDiv (y2, render_height, rect.bottom) ; } if (message != WM_LBUTTONUP) { sprintf (str, "%d,%d - %d,%d", x1, y1, x2, y2) ; SetWindowText (hwnd, str) ; pts [1].x = RB2.x ; pts [2] = RB2 ; pts [3] = RB2 ; pts [3].x = RB1.x ; Polyline (hdc, pts, 5) ; SetROP2 (hdc, oldMode) ; SelectObject (hdc, hpen) ; ReleaseDC (hwnd, hdc) ; } else { ReleaseCapture () ; SetROP2 (hdc, oldMode) ; SelectObject (hdc, hpen) ; ReleaseDC (hwnd, hdc) ; SetWindowText (hwnd, "Render Window") ; if ((x2 - x1 > 2) && (y2 - y1 > 2)) { sprintf (str, "Selection is %d,%d to %d,%d\n\n", x1, y1, x2, y2) ; if (RBand == 1) { RBand = 0 ; strcat (str, "Press OK to render this region now.\n") ; strcat (str, "(You may shift-drag to set a permanent region next time).") ; if (MessageBox (main_window, str, "Render region", MB_OKCANCEL) == IDOK) { if (RegionStr [0]) { if ((s = strstr (command_line, RegionStr)) != NULL) strcpy (s, s + strlen (RegionStr)) ; else if ((s = strstr (command_line, RegionStr + 1)) != NULL) strcpy (s, s + strlen (RegionStr) - 1) ; } // sprintf (RegionStr, " +sc%d +sr%d +ec%d +er%d", RB1.x, RB1.y, RB2.x, RB2.y) ; sprintf (RegionStr, " +sc%f +sr%f +ec%f +er%f", (float) x1 / render_width, (float) y1 / render_height, (float) x2 / render_width, (float) y2 / render_height) ; start_rendering (FALSE, FALSE) ; } } else { RBand = 0 ; strcat (str, "Press OK to append this region to the command-line.\n") ; if (MessageBox (main_window, str, "Render region", MB_OKCANCEL) == IDOK) { if (RegionStr [0]) { if ((s = strstr (command_line, RegionStr)) != NULL) strcpy (s, s + strlen (RegionStr)) ; else if ((s = strstr (command_line, RegionStr + 1)) != NULL) strcpy (s, s + strlen (RegionStr) - 1) ; } // sprintf (TempRegionStr, " +sc%d +sr%d +ec%d +er%d", RB1.x, RB1.y, RB2.x, RB2.y) ; sprintf (TempRegionStr, " +sc%f +sr%f +ec%f +er%f", (float) x1 / render_width, (float) y1 / render_height, (float) x2 / render_width, (float) y2 / render_height) ; PostMessage (main_window, WM_COMMAND, CM_COMMANDLINE, 0) ; } } } else RBand = 0 ; } } else { if (!rendering) { x2 = LOWORD (lParam) + renderwin_xoffset ; y2 = HIWORD (lParam) + renderwin_xoffset ; GetClientRect (hwnd, &rect) ; if (rect.right > render_width || rect.bottom > render_height) { x2 = MulDiv (x2, render_width, rect.right) ; y2 = MulDiv (y2, render_height, rect.bottom) ; } sprintf (str, "%d,%d", x2, y2) ; SetWindowText (hwnd, str) ; } } return (0) ; case WM_RBUTTONDOWN : if (hPopupMenus != NULL) { pt.x = LOWORD (lParam) ; pt.y = HIWORD (lParam) ; ClientToScreen (render_window, &pt) ; TrackPopupMenu (GetSubMenu (hPopupMenus, 1), TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, main_window, NULL) ; } return (0) ; case WM_GETMINMAXINFO : if (IsZoomed (hwnd)) break ; pInfo = (MINMAXINFO *) lParam ; pInfo->ptMaxTrackSize.x = renderwin_max_width ; pInfo->ptMaxTrackSize.y = renderwin_max_height ; break ; case WM_MOVE : if (render_window == NULL) break ; if (!IsIconic (render_window) && !IsZoomed (render_window)) { GetWindowRect (render_window, &rect) ; renderwin_left = rect.left ; renderwin_top = rect.top ; } return (0) ; case WM_SIZE : if (render_window == NULL) break ; switch (wParam) { case SIZE_MINIMIZED : renderwin_flags = WS_MINIMIZE ; return (0) ; case SIZE_MAXIMIZED : renderwin_flags = WS_MAXIMIZE ; SetScrollRange (render_window, SB_HORZ, 0, 0, TRUE) ; SetScrollRange (render_window, SB_VERT, 0, 0, TRUE) ; PovInvalidateRect (render_window, NULL, FALSE) ; UpdateWindow (render_window) ; return (0) ; case SIZE_RESTORED : renderwin_flags = 0 ; PovInvalidateRect (render_window, NULL, FALSE) ; UpdateWindow (render_window) ; break ; default : return (0) ; } // to get here we must be handling SIZE_RESTORED. // one problem we have here is that if we create one scroll bar, it takes away some of the client // area of the other direction (i.e. if we create a scroll bar for the X direction, it takes away // some of the Y client area). therefore we should create a scroll bar for that direction also. // but we don't do this for now. GetWindowRect (render_window, &rect) ; if (rect.right - rect.left < renderwin_max_width) { if (renderwin_xoffset >= render_width - LOWORD (lParam)) renderwin_xoffset = render_width - LOWORD (lParam) ; SetScrollRange (render_window, SB_HORZ, 0, render_width - LOWORD (lParam), FALSE) ; SetScrollPos (render_window, SB_HORZ, renderwin_xoffset, TRUE) ; } else { renderwin_xoffset = 0 ; SetScrollRange (render_window, SB_HORZ, 0, 0, TRUE) ; } if (rect.bottom - rect.top < renderwin_max_height) { if (renderwin_yoffset >= render_height - HIWORD (lParam)) renderwin_yoffset = render_height - HIWORD (lParam) ; SetScrollRange (render_window, SB_VERT, 0, render_height - HIWORD (lParam), FALSE) ; SetScrollPos (render_window, SB_VERT, renderwin_yoffset, TRUE) ; } else { renderwin_yoffset = 0 ; SetScrollRange (render_window, SB_VERT, 0, 0, TRUE) ; } return (0) ; case WM_VSCROLL : GetClientRect (render_window, &rect) ; switch (LOWORD (wParam)) { case SB_LINEDOWN : if (renderwin_yoffset >= render_height - rect.bottom) break ; SetScrollRange (render_window, SB_VERT, 0, render_height - rect.bottom, FALSE) ; SetScrollPos (render_window, SB_VERT, ++renderwin_yoffset, TRUE) ; ScrollWindow (render_window, 0, -1, NULL, NULL) ; break ; case SB_LINEUP : if (renderwin_yoffset == 0) break ; SetScrollRange (render_window, SB_VERT, 0, render_height - rect.bottom, FALSE) ; SetScrollPos (render_window, SB_VERT, --renderwin_yoffset, TRUE) ; ScrollWindow (render_window, 0, 1, NULL, NULL) ; break ; case SB_PAGEDOWN : renderwin_yoffset += rect.bottom ; if (renderwin_yoffset > render_height - rect.bottom) renderwin_yoffset = render_height - rect.bottom ; SetScrollPos (render_window, SB_VERT, renderwin_yoffset, TRUE) ; PovInvalidateRect (hwnd, NULL, FALSE) ; break ; case SB_PAGEUP : renderwin_yoffset -= rect.bottom ; if (renderwin_yoffset < 0) renderwin_yoffset = 0 ; SetScrollPos (render_window, SB_VERT, renderwin_yoffset, TRUE) ; PovInvalidateRect (hwnd, NULL, FALSE) ; break ; case SB_THUMBPOSITION : case SB_THUMBTRACK : renderwin_yoffset = HIWORD (wParam) ; SetScrollPos (render_window, SB_VERT, renderwin_yoffset, TRUE) ; PovInvalidateRect (hwnd, NULL, FALSE) ; break ; } return (0) ; case WM_HSCROLL : GetClientRect (render_window, &rect) ; switch (LOWORD (wParam)) { case SB_LINERIGHT : if (renderwin_xoffset >= render_width - rect.right) break ; SetScrollRange (render_window, SB_HORZ, 0, render_width - rect.right, FALSE) ; SetScrollPos (render_window, SB_HORZ, ++renderwin_xoffset, TRUE) ; ScrollWindow (render_window, -1, 0, NULL, NULL) ; break ; case SB_LINELEFT : if (renderwin_xoffset == 0) break ; SetScrollRange (render_window, SB_HORZ, 0, render_width - rect.right, FALSE) ; SetScrollPos (render_window, SB_HORZ, --renderwin_xoffset, TRUE) ; ScrollWindow (render_window, 1, 0, NULL, NULL) ; break ; case SB_PAGERIGHT : renderwin_xoffset += rect.right ; if (renderwin_xoffset > render_width - rect.right) renderwin_xoffset = render_width - rect.right ; SetScrollPos (render_window, SB_HORZ, renderwin_xoffset, TRUE) ; PovInvalidateRect (hwnd, NULL, FALSE) ; break ; case SB_PAGELEFT : renderwin_xoffset -= rect.right ; if (renderwin_xoffset < 0) renderwin_xoffset = 0 ; SetScrollPos (render_window, SB_HORZ, renderwin_xoffset, TRUE) ; PovInvalidateRect (hwnd, NULL, FALSE) ; break ; case SB_THUMBPOSITION : case SB_THUMBTRACK : renderwin_xoffset = HIWORD (wParam) ; SetScrollPos (render_window, SB_HORZ, renderwin_xoffset, TRUE) ; PovInvalidateRect (hwnd, NULL, FALSE) ; break ; } return (0) ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; oldMode = SetStretchBltMode (hdc, STRETCH_DELETESCANS) ; if (hPalApp) { SelectPalette (hdc, hPalApp, FALSE) ; RealizePalette (hdc) ; } if (IsIconic (render_window)) { SelectClipRgn (hdc, NULL) ; dest_xoffset = 0 ; dest_yoffset = 0 ; dest_width = 36 ; dest_height = 36 ; } else { if (IsZoomed (render_window)) { GetClientRect (render_window, &rect) ; dest_xoffset = 0 ; dest_yoffset = 0 ; dest_width = rect.right ; dest_height = rect.bottom ; } else { dest_xoffset = -renderwin_xoffset ; dest_yoffset = -renderwin_yoffset ; dest_width = render_width ; dest_height = render_height ; GetClientRect (render_window, &rect) ; if (rect.right > dest_width) BitBlt (hdc, dest_width, 0, rect.right - dest_width, rect.bottom, NULL, 0, 0, BLACKNESS) ; if (rect.bottom > dest_height) BitBlt (hdc, 0, dest_height, rect.right, rect.bottom - dest_height, NULL, 0, 0, BLACKNESS) ; } } if (StretchDIBits (hdc, dest_xoffset, dest_yoffset, dest_width, dest_height, 0, 0, render_bitmap.header.biWidth, render_bitmap.header.biHeight, render_bitmap_surface, (LPBITMAPINFO) &render_bitmap, DIB_RGB_COLORS, SRCCOPY) <= 0) { // hmmmm ... it seems we've run into a Windows bug of some form. When rendering a // large scene file (it used some 200mb of swap plus 80+mb of real memory on a 128mb // box) at a resolution of 1280x1024 (same as screen resolution) on Windows NT 4.0, // StretchDIBits () was observed to return zero (which is not failure, but not success // either :). GetClientRect (render_window, &rect) ; BitBlt (hdc, 0, 0, dest_width, dest_height, NULL, 0, 0, WHITENESS) ; if (errorBitmap == NULL) errorBitmap = LoadBitmap (hInstance, MAKEINTRESOURCE (BMP_STRETCHDIBITS)) ; hdcMemory = CreateCompatibleDC (hdc) ; oldBmp = SelectObject (hdcMemory, errorBitmap) ; BitBlt (hdc, rect.right / 2 - 157, rect.bottom / 2 - 10, 315, 21, hdcMemory, 0, 0, SRCCOPY) ; SelectObject (hdcMemory, oldBmp) ; DeleteDC (hdcMemory) ; } SetStretchBltMode (hdc, oldMode) ; EndPaint (hwnd, &ps) ; return (0) ; case WM_DESTROY : // it is possible for an old render window to be in the process of being destroyed // when a new one has already been created. check for this here. if (render_window == hwnd) { render_window = NULL ; renderwin_destroyed = TRUE ; PVEnableMenuItem (CM_RENDERSHOW, MF_ENABLED) ; PVEnableMenuItem (CM_RENDERCLOSE, MF_GRAYED) ; } return (0) ; } return (DefWindowProc (hwnd, message, wParam, lParam)) ; } LRESULT CALLBACK PovMainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int i ; char *s ; HDC hdc ; BOOL f ; RECT rect ; POINT pt ; NMHDR *nmh ; DWORD result = 0 ; HPALETTE oldPalette ; TOOLTIPTEXT *t ; switch (message) { case TASKBAR_NOTIFY_MESSAGE : if (lParam == WM_LBUTTONDBLCLK) { ShowWindow (main_window, SW_SHOW) ; if (render_window) ShowWindow (render_window, SW_SHOW) ; PVModifyMenu (CM_SHOWMAINWINDOW, MF_STRING, CM_SHOWMAINWINDOW, "Minimize to System &Tray\tAlt+W") ; main_window_hidden = 0 ; TaskBarDeleteIcon (main_window, 0) ; return (0) ; } if (lParam == WM_RBUTTONDOWN) { if (hPopupMenus != NULL) { GetCursorPos (&pt) ; SetForegroundWindow (main_window) ; TrackPopupMenu (GetSubMenu (hPopupMenus, 0), TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, main_window, NULL) ; return (0) ; } } return (0) ; case WM_ENTERSIZEMOVE : if (!IsW95UserInterface) break ; resizing = TRUE ; break ; case WM_EXITSIZEMOVE : if (!IsW95UserInterface) break ; resizing = FALSE ; InvalidateRect (message_window, NULL, TRUE) ; break ; case WM_SETFOCUS : // After a dialog has been displayed, Windows will give the focus // back to our main window. We need to farm the focus off to whatever // window should have it. EditSetFocus () will handle this for us. EditSetFocus () ; break ; case EDITOR_RENDER_MESSAGE : if (rendering || hRenderThread) { stop_rendering++ ; return (0) ; } strcpy (source_file_name, (char *) lParam) ; splitpath (source_file_name, lastRenderPath, lastRenderName) ; if (!ExternalDragFunction (source_file_name, dfRenderEditor)) start_rendering (FALSE, FALSE) ; return (0) ; case CREATE_RENDERWIN_MESSAGE : return (renderwin_init ()) ; case WM_NOTIFY : nmh = (NMHDR *) lParam ; if (nmh->hwndFrom == rebar_window) { switch (nmh->code) { case RBN_HEIGHTCHANGE : if (!use_toolbar) break ; GetClientRect (rebar_window, &rect) ; toolheight = rect.bottom + 1 ; CalculateClientWindows (TRUE) ; // perhaps there's a bug in Windows 95 ? if (top_message_row) { ShowScrollBar (message_window, SB_VERT, FALSE) ; ShowScrollBar (message_window, SB_VERT, TRUE) ; } if (need_hscroll ()) { ShowScrollBar (message_window, SB_HORZ, FALSE) ; ShowScrollBar (message_window, SB_HORZ, TRUE) ; } break ; } break ; } switch (nmh->code) { case TTN_NEEDTEXT : t = (TOOLTIPTEXT *) lParam ; if (use_tooltips == 0) { t->lpszText = NULL ; t->hinst = 0 ; break ; } t->hinst = hInstance ; t->lpszText = MAKEINTRESOURCE (t->hdr.idFrom) ; return (0) ; } break ; case RENDER_MESSAGE : s = getCommandLine () ; if ((rendering || hRenderThread) && (strlen (s) || wParam)) { PovMessageBox ("Cannot accept new command - already rendering", "Warning") ; return (0) ; } if (main_window_hidden) { ShowWindow (main_window, SW_SHOW) ; if (render_window != NULL) ShowWindow (render_window, SW_SHOW) ; PVModifyMenu (CM_SHOWMAINWINDOW, MF_STRING, CM_SHOWMAINWINDOW, "Minimize to System &Tray\tAlt+W") ; main_window_hidden = 0 ; TaskBarDeleteIcon (main_window, 0) ; return (0) ; } if (wParam == 0) { if (strlen (s) == 0) return (0) ; if (!restore_command_line) strcpy (old_command_line, command_line) ; restore_command_line = TRUE ; strcpy (command_line, s) ; start_rendering (FALSE, TRUE) ; strcpy (command_line, old_command_line) ; restore_command_line = FALSE ; } else handle_main_command (CM_DEMO, 0) ; return (0) ; case WM_CREATE : main_window = hwnd ; hMainMenu = CreateMenu () ; build_main_menu (hMainMenu, FALSE) ; SetMenu (main_window, hMainMenu) ; break ; case WM_QUERYENDSESSION : if (!EditCanClose (TRUE)) return (FALSE) ; return (TRUE) ; case WM_ENDSESSION : if ((BOOL) wParam) { setRunOnce () ; if (save_settings) { SendMessage (toolbar_combobox, CB_GETLBTEXT, SendMessage (toolbar_combobox, CB_GETCURSEL, 0, 0), (LPARAM) SecondaryRenderIniFileSection) ; if (restore_command_line) strcpy (command_line, old_command_line) ; write_INI_settings (EngineIniFileName) ; EditSaveState () ; } } break ; case WM_COMMAND : if (LOWORD (wParam) < CM_FIRST) { EditDispatchMenuId (LOWORD (wParam)) ; return (0) ; } if (ExtensionsEnabled) if (LOWORD (wParam) >= CM_FIRSTGUIEXT && LOWORD (wParam) <= CM_LASTGUIEXT) return (ExternalMenuSelect (LOWORD (wParam))) ; if (handle_main_command (wParam, lParam)) return (0) ; break ; case WM_INITMENU : case WM_INITMENUPOPUP : EditUpdateMenus ((HMENU) wParam) ; EditPassOnMessage (hwnd, message, wParam, lParam, &result) ; break ; case WM_ACTIVATEAPP : EditPassOnMessage (hwnd, message, wParam, lParam, &result) ; break ; case WM_TIMER : seconds++ ; ExternalEvent (EventTimer, seconds) ; if (MenuBarDraw) { DrawMenuBar (main_window) ; MenuBarDraw = FALSE ; } if (!rendering && !hRenderThread) { if (auto_render) { if (queued_file_count) { queued_file_count-- ; update_queue_status (TRUE) ; strcpy (source_file_name, queued_files [0]) ; memcpy (queued_files [0], queued_files [1], sizeof (queued_files) - sizeof (queued_files [0])) ; splitpath (source_file_name, dir, NULL) ; SetCurrentDirectory (dir) ; if (!ExternalDragFunction (source_file_name, dfRenderFileQueue)) start_rendering (TRUE, FALSE) ; } } } else { render_finish_time = time (NULL) ; if (render_finish_time != render_start_time) status_printf (StatusPPS, "%u PPS", pixels / (render_finish_time - render_start_time)) ; say_status_message (StatusRendertime, get_elapsed_time (render_start_time, render_finish_time)) ; if ((IsIconic (main_window) && !IsW95UserInterface) && render_bitmap_surface != NULL) SendMessage (main_window, WM_NCPAINT, 0, 0L) ; if (rendersleep) FlashWindow (main_window, seconds & 0x01) ; } return (0) ; case WM_PALETTECHANGED : // make sure it wasn't us who changed the palette, otherwise we can get into an infinite loop. if ((HWND) wParam == main_window) return (0) ; // FALL THROUGH to WM_QUERYNEWPALETTE case WM_QUERYNEWPALETTE : if (hPalApp) { hdc = GetDC (main_window) ; oldPalette = SelectPalette (hdc, hPalApp, FALSE) ; f = RealizePalette (hdc) ; SelectPalette (hdc, oldPalette, FALSE) ; ReleaseDC (main_window, hdc) ; if (f) { PovInvalidateRect (hwnd, NULL, TRUE) ; if ((EditGetFlags () & EDIT_MSG_SELECTED) == 0) PovInvalidateRect (message_window, NULL, TRUE) ; PovInvalidateRect (render_window, NULL, TRUE) ; } } return (0) ; case WM_SIZE : mainwin_placement.length = sizeof (WINDOWPLACEMENT) ; GetWindowPlacement (main_window, &mainwin_placement) ; SendMessage (rebar_window, WM_SIZE, wParam, lParam) ; SendMessage (StatusWindow, WM_SIZE, wParam, lParam) ; ResizeStatusBar (StatusWindow) ; switch (wParam) { case SIZE_MINIMIZED : SetWindowText (main_window, rendersleep ? "POV-Ray for Windows (paused)" : "POV-Ray for Windows") ; if ((render_above_main || hide_render_window) && render_window != NULL) { ShowWindow (render_window, SW_HIDE) ; render_main_icon = TRUE ; } ExternalEvent (EventSize, wParam) ; return (0) ; case SIZE_MAXIMIZED : case SIZE_RESTORED : if (render_main_icon && render_window != NULL) ShowWindow (render_window, renderwin_active ? SW_SHOW : SW_SHOWNA) ; render_main_icon = FALSE ; SendMessage (toolbar_window, TB_AUTOSIZE, 0, 0) ; if (use_toolbar && toolheight == 0 && rebar_window != NULL) { GetClientRect (rebar_window, &rect) ; toolheight = rect.bottom + 1 ; } CalculateClientWindows (TRUE) ; // perhaps there's a bug in Windows 95 ? if (top_message_row) { ShowScrollBar (message_window, SB_VERT, FALSE) ; ShowScrollBar (message_window, SB_VERT, TRUE) ; } if (need_hscroll ()) { ShowScrollBar (message_window, SB_HORZ, FALSE) ; ShowScrollBar (message_window, SB_HORZ, TRUE) ; } ExternalEvent (EventSize, wParam) ; break ; case SIZE_MAXHIDE : case SIZE_MAXSHOW : default : ExternalEvent (EventSize, wParam) ; return (0) ; } return (0) ; case WM_MOVE : mainwin_placement.length = sizeof (WINDOWPLACEMENT) ; GetWindowPlacement (main_window, &mainwin_placement) ; ExternalEvent (EventMove, lParam) ; return (0) ; case WM_ERASEBKGND : if (IsIconic (main_window)) { BitBlt ((HDC) wParam, 0, 0, 36, 36, NULL, 0, 0, BLACKNESS) ; return (1) ; } break ; case WM_DROPFILES : DragFunction ((HANDLE) wParam) ; return (0) ; case WM_CHAR : switch ((char) wParam) { case 0x0f : // ctrl-o EditBrowseFile (TRUE) ; return (0) ; case 0x0e : // ctrl-n (close enough to shift-ctrl-n ;) EditOpenFile (NULL) ; return (0) ; } if (EditPassOnMessage (hwnd, message, wParam, lParam, &result)) return (0) ; break ; case WM_KEYDOWN : for (i = 0 ; key2scroll [i].wVirtkey != -1 ; i++) { if (wParam == key2scroll [i].wVirtkey) { SendMessage (message_window, key2scroll [i].iMessage, key2scroll [i].wRequest, 0L) ; return (0) ; } } break ; case WM_MENUSELECT : if (EditPassOnMessage (hwnd, message, wParam, lParam, &result)) return (result) ; handle_menu_select (wParam, lParam) ; return (0) ; case WM_CLOSE : if (debugging) message_printf ("DEBUG : Close requested, rendering is %d, quit is %d\n", rendering, quit) ; if ((rendering || hRenderThread) && !quit) { if (MessageBox (main_window, "POV-Ray is currently rendering - do you want to stop ?", "Stop rendering", MB_ICONQUESTION | MB_YESNO) == IDNO) { return (0) ; } } if (!EditCanClose (TRUE)) return (0) ; ExternalEvent (EventClose, 0) ; if (timer_id != 0) KillTimer (main_window, timer_id) ; DragAcceptFiles (main_window, FALSE) ; if (!rendering || quit) { WinHelp (main_window, "pvengine.hlp", HELP_QUIT, NULL) ; WinHelp (main_window, "povray31.hlp", HELP_QUIT, NULL) ; DestroyWindow (main_window) ; } else quit = TRUE ; return (0) ; case WM_DESTROY : ExternalEvent (EventDestroy, 0) ; if (save_settings) { SendMessage (toolbar_combobox, CB_GETLBTEXT, SendMessage (toolbar_combobox, CB_GETCURSEL, 0, 0), (LPARAM) SecondaryRenderIniFileSection) ; if (restore_command_line) strcpy (command_line, old_command_line) ; write_INI_settings (EngineIniFileName) ; EditSaveState () ; } PostQuitMessage (0) ; return (0) ; } return (DefWindowProc (hwnd, message, wParam, lParam)) ; } LRESULT CALLBACK PovMessageWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int nhs ; HDC hdc ; RECT rect ; POINT pt ; PAINTSTRUCT ps ; switch (message) { case WM_KEYDOWN : PostMessage (main_window, message, wParam, lParam) ; return (0) ; case WM_RBUTTONDOWN : if (hPopupMenus != NULL) { pt.x = LOWORD (lParam) ; pt.y = HIWORD (lParam) ; ClientToScreen (hwnd, &pt) ; TrackPopupMenu (GetSubMenu (hPopupMenus, 0), TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, main_window, NULL) ; } return (0) ; case WM_ERASEBKGND : return (1) ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; if (hPalApp) { SelectPalette (hdc, hPalApp, FALSE) ; RealizePalette (hdc) ; } paint_display_window (hdc) ; EndPaint (hwnd, &ps) ; return (0) ; case WM_SIZE : if (message_count) { GetClientRect (hwnd, &rect) ; message_scroll_pos_x = 0 ; message_scroll_pos_y = message_count - rect.bottom / message_ychar ; if (message_scroll_pos_y < 0) message_scroll_pos_y = 0 ; } update_message_display (None) ; PovInvalidateRect (hwnd, NULL, TRUE) ; return (0) ; case WM_VSCROLL : switch (LOWORD (wParam)) { case SB_LINEDOWN : if (message_scroll_pos_y < message_count - message_rows) { message_scroll_pos_y++ ; ScrollWindow (hwnd, 0, -message_ychar, NULL, NULL) ; update_message_display (None) ; UpdateWindow (hwnd) ; } break ; case SB_LINEUP : if (message_scroll_pos_y > 0) { message_scroll_pos_y-- ; ScrollWindow (hwnd, 0, message_ychar, NULL, NULL) ; update_message_display (None) ; UpdateWindow (hwnd) ; } break ; case SB_PAGEDOWN : if (message_scroll_pos_y < message_count - message_rows) { message_scroll_pos_y += message_rows ; if (message_scroll_pos_y > message_count - message_rows) message_scroll_pos_y = message_count - message_rows ; PovInvalidateRect (hwnd, NULL, TRUE) ; update_message_display (None) ; } break ; case SB_PAGEUP : if (message_scroll_pos_y > 0) { message_scroll_pos_y -= message_rows ; if (message_scroll_pos_y < 0) message_scroll_pos_y = 0 ; PovInvalidateRect (hwnd, NULL, TRUE) ; update_message_display (None) ; } break ; case SB_THUMBPOSITION : case SB_THUMBTRACK : message_scroll_pos_y = HIWORD (wParam) ; PovInvalidateRect (hwnd, NULL, TRUE) ; update_message_display (None) ; break ; } return (0) ; case WM_HSCROLL : nhs = need_hscroll () ; switch (LOWORD (wParam)) { case SB_LINERIGHT : if (message_scroll_pos_x < nhs) { message_scroll_pos_x++ ; ScrollWindow (hwnd, -message_xchar, 0, NULL, NULL) ; update_message_display (None) ; UpdateWindow (hwnd) ; } break ; case SB_LINELEFT : if (message_scroll_pos_x > 0) { message_scroll_pos_x-- ; ScrollWindow (hwnd, message_xchar, 0, NULL, NULL) ; update_message_display (None) ; UpdateWindow (hwnd) ; } break ; case SB_PAGERIGHT : if (message_scroll_pos_x < nhs) { message_scroll_pos_x += message_cols ; if (message_scroll_pos_x > nhs) message_scroll_pos_x = nhs ; PovInvalidateRect (hwnd, NULL, TRUE) ; update_message_display (None) ; } break ; case SB_PAGELEFT : if (message_scroll_pos_x > 0) { message_scroll_pos_x -= message_cols ; if (message_scroll_pos_x < 0) message_scroll_pos_x = 0 ; PovInvalidateRect (hwnd, NULL, TRUE) ; update_message_display (None) ; } break ; case SB_THUMBPOSITION : case SB_THUMBTRACK : message_scroll_pos_x = HIWORD (wParam) ; PovInvalidateRect (hwnd, NULL, TRUE) ; update_message_display (None) ; break ; } return (0) ; } return (DefWindowProc (hwnd, message, wParam, lParam)) ; } // You must recreate the bitmaps splash5-8bpp.cmp and splash5-pal.bmp that are // in the bitmaps\ dir if you want to distribute your compile. When you do you // must include our copyright statement and clearly indicate that you have made // a derived version. You MAY NOT remove the splash screen code that shows this // bitmap at startup ! LRESULT CALLBACK PovSplashWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; HDC hdcMemory ; BOOL f ; HBITMAP oldBmp ; HPALETTE oldPalette ; PAINTSTRUCT ps ; switch (message) { case WM_DESTROY : if (screen_depth <= 8) { hdc = GetDC (hwnd) ; BitBlt (hdc, 0, 0, splash_width, splash_height, NULL, 0, 0, BLACKNESS) ; ReleaseDC (hwnd, hdc) ; } DeleteObject (hBmpSplash) ; if (hPalBitmap) DeleteObject (hPalBitmap) ; hPalBitmap = hBmpSplash = NULL ; break ; case WM_KEYDOWN : case WM_LBUTTONDOWN : DestroyWindow (hwnd) ; if (splash_show_about) DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_ABOUT), main_window, (DLGPROC) PovAboutDialogProc, (LPARAM) main_window) ; return (0) ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; if (hPalBitmap) { SelectPalette (hdc, hPalBitmap, FALSE) ; RealizePalette (hdc) ; } hdcMemory = CreateCompatibleDC (hdc) ; oldBmp = SelectObject (hdcMemory, hBmpSplash) ; BitBlt (hdc, 0, 0, splash_width, splash_height, hdcMemory, 0, 0, SRCCOPY) ; SelectObject (hdcMemory, oldBmp) ; DeleteDC (hdcMemory) ; EndPaint (hwnd, &ps) ; return (0) ; case WM_PALETTECHANGED : // make sure it wasn't us who changed the palette, otherwise we can get into an infinite loop. if ((HWND) wParam == hwnd) return (0) ; // FALL THROUGH to WM_QUERYNEWPALETTE case WM_QUERYNEWPALETTE : if (hPalBitmap) { hdc = GetDC (hwnd) ; oldPalette = SelectPalette (hdc, hPalBitmap, FALSE) ; f = RealizePalette (hdc) ; SelectPalette (hdc, oldPalette, FALSE) ; ReleaseDC (hwnd, hdc) ; if (f) PovInvalidateRect (hwnd, NULL, TRUE) ; } return (0) ; } return (DefWindowProc (hwnd, message, wParam, lParam)) ; } LRESULT CALLBACK PovRenderAnimWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int line ; int page ; int lastpage ; HDC hdc ; HDC hdcMemory ; HBITMAP oldBmp ; MINMAXINFO *mm ; PAINTSTRUCT ps ; static int pages ; static BITMAP bm ; static HBITMAP hBmp ; switch (message) { case WM_SIZE : if (LOWORD (lParam) > 120) SetWindowPos (hwnd, NULL, 0, 0, 120, 42, SWP_NOMOVE | SWP_NOREDRAW) ; return (0) ; case WM_GETMINMAXINFO : mm = (MINMAXINFO *) lParam ; mm->ptMaxSize.x = 120 ; mm->ptMaxSize.y = 42 ; return (0) ; case WM_CREATE : hBmp = LoadImage (hInstance, MAKEINTRESOURCE (screen_depth <= 8 ? BMP_RENDERANIM_4BPP : BMP_RENDERANIM), IMAGE_BITMAP, 0, 0, 0) ; // hBmp = DIBToBitmap (LoadDIB ("renderanim.bmp"), NULL) ; GetObject (hBmp, sizeof (BITMAP), (LPSTR) &bm) ; pages = bm.bmHeight / 42 ; break ; case WM_TIMER : if (use_renderanim && rendering) { if (hBmp == NULL || rendersleep) return (0) ; line = render_anim_count % 42 ; page = (render_anim_count / 42) % pages + 1 ; if (page >= pages) page = 0 ; hdc = GetDC (hwnd) ; hdcMemory = CreateCompatibleDC (hdc) ; oldBmp = SelectObject (hdcMemory, hBmp) ; BitBlt (hdc, 0, line, 120, 1, hdcMemory, 0, page * 42 + line, SRCCOPY) ; SelectObject (hdcMemory, oldBmp) ; DeleteDC (hdcMemory) ; ReleaseDC (hwnd, hdc) ; if (render_anim_count++ == 0) InvalidateRect (hwnd, NULL, FALSE) ; } return (0) ; case WM_PAINT : if (hBmp == NULL) break ; hdc = BeginPaint (hwnd, &ps) ; hdcMemory = CreateCompatibleDC (hdc) ; oldBmp = SelectObject (hdcMemory, hBmp) ; if (use_renderanim && rendering) { line = render_anim_count % 42 ; page = (render_anim_count / 42) % pages + 1 ; if (page >= pages) page = 0 ; lastpage = render_anim_count / 42 % pages ; BitBlt (hdc, 0, line, 120, 42 - line, hdcMemory, 0, lastpage * 42 + line, SRCCOPY) ; BitBlt (hdc, 0, 0, 120, line, hdcMemory, 0, page * 42, SRCCOPY) ; } else BitBlt (hdc, 0, 0, 120, 42, hdcMemory, 0, (pages - 1) * 42, SRCCOPY) ; SelectObject (hdcMemory, oldBmp) ; DeleteDC (hdcMemory) ; EndPaint (hwnd, &ps) ; return (0) ; } return (DefWindowProc (hwnd, message, wParam, lParam)) ; } int register_classes (void) { WNDCLASS wc ; // Register the main window class. wc.style = 0 ; wc.lpfnWndProc = PovMainWndProc ; wc.cbClsExtra = 0 ; wc.cbWndExtra = 0 ; wc.hInstance = hInstance ; wc.hIcon = ourIcon ; wc.hCursor = LoadCursor (NULL, IDC_ARROW) ; wc.hbrBackground = NULL ; wc.lpszMenuName = NULL ; wc.lpszClassName = PovMainWinClass ; if (RegisterClass (&wc) == FALSE) return (FALSE) ; // Register the message window class. wc.style = 0 ; wc.lpfnWndProc = PovMessageWndProc ; wc.cbClsExtra = 0 ; wc.cbWndExtra = 0 ; wc.hInstance = hInstance ; wc.hIcon = NULL ; wc.hCursor = LoadCursor (NULL, IDC_ARROW) ; wc.hbrBackground = NULL ; wc.lpszMenuName = NULL ; wc.lpszClassName = PovMessageWinClass ; if (RegisterClass (&wc) == FALSE) return (FALSE) ; // Register the render window class. wc.style = CS_BYTEALIGNCLIENT ; wc.lpfnWndProc = PovRenderWndProc ; wc.cbClsExtra = 0 ; wc.cbWndExtra = 0 ; wc.hInstance = hInstance ; wc.hIcon = NULL ; wc.hCursor = LoadCursor (NULL, IDC_CROSS) ; wc.hbrBackground = NULL ; wc.lpszMenuName = NULL ; wc.lpszClassName = PovRenderWinClass ; if (RegisterClass (&wc) == FALSE) return (FALSE) ; // Register the splash window class. wc.style = CS_BYTEALIGNCLIENT ; wc.lpfnWndProc = PovSplashWndProc ; wc.cbClsExtra = 0 ; wc.cbWndExtra = 0 ; wc.hInstance = hInstance ; wc.hIcon = NULL ; wc.hCursor = LoadCursor (NULL, IDC_ARROW) ; wc.hbrBackground = NULL ; wc.lpszMenuName = NULL ; wc.lpszClassName = PovSplashWinClass ; if (RegisterClass (&wc) == FALSE) return (FALSE) ; // Register the render animation window class. wc.style = CS_BYTEALIGNCLIENT ; wc.lpfnWndProc = PovRenderAnimWndProc ; wc.cbClsExtra = 0 ; wc.cbWndExtra = 0 ; wc.hInstance = hInstance ; wc.hIcon = NULL ; wc.hCursor = LoadCursor (NULL, IDC_ARROW) ; wc.hbrBackground = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)) ; wc.lpszMenuName = NULL ; wc.lpszClassName = PovRenderAnimWinClass ; if (RegisterClass (&wc) == FALSE) return (FALSE) ; return (TRUE) ; } void cleanup_all (void) { ExternalCleanupAll () ; EditUnload () ; if (use_taskbar) TaskBarDeleteIcon (main_window, 0) ; WinHelp (main_window, "pvengine.hlp", HELP_QUIT, NULL) ; WinHelp (main_window, "povray31.hlp", HELP_QUIT, NULL) ; DeleteCriticalSection (&critical_section) ; if (hLibCtl3d != NULL) FreeLibrary (hLibCtl3d) ; display_cleanup () ; if (hBmpBackground != NULL) DeleteObject (hBmpBackground) ; if (hBmpRendering != NULL) DeleteObject (hBmpRendering) ; if (hBmpIcon != NULL) DeleteObject (hBmpIcon) ; if (hBmpSplash != NULL) DeleteObject (hBmpSplash) ; if (hMenuBar) DestroyMenu (hMenuBar) ; if (hMainMenu) DestroyMenu (hMainMenu) ; if (hPopupMenus) DestroyMenu (hPopupMenus) ; if (hPalApp) DeleteObject (hPalApp) ; if (message_font) DeleteObject (message_font) ; if (tab_font) DeleteObject (tab_font) ; if (ourIcon) DestroyIcon (ourIcon) ; UnregisterClass (PovRenderWinClass, hInstance) ; UnregisterClass (PovMessageWinClass, hInstance) ; UnregisterClass (PovMainWinClass, hInstance) ; UnregisterClass (PovSplashWinClass, hInstance) ; UnregisterClass (PovRenderAnimWinClass, hInstance) ; } #ifdef CBUILDER int PASCAL PVEWinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) #else int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) #endif { int show_state ; int i ; int id = 0 ; int w, h ; char str [_MAX_PATH] ; char *s ; unsigned n ; unsigned splash_time = 1 ; MSG msg ; HDC hDC ; HDIB hDIB ; RECT rect ; HWND hwnd ; BITMAP bm ; HBITMAP hBMP ; struct stat statbuf ; BOOL (WINAPI *Ctl3dAutoSubclass) (HINSTANCE); BOOL (WINAPI *Ctl3dRegister) (HINSTANCE); BOOL (WINAPI *Ctl3dUnregister) (HINSTANCE); WINDOWPLACEMENT placement ; struct stat st ; //SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) PovUnhandledExceptionFilter) ; #ifdef TIMED_BETA if (time (NULL) > EXPIRE_AT) { MessageBox (NULL, "This beta version of POV-Ray for Windows has expired", "Beta expired", MB_OK | MB_ICONSTOP) ; exit (1) ; } #endif hInstance = hInst ; ourIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_NEW_PVENGINE)) ; if (hPrev == NULL) if (register_classes () == FALSE) MessageBox (NULL, "ERROR : Could not register classes", "Error", MB_ICONSTOP) ; detect_graphics_config () ; // You must recreate the bitmaps splash5-8bpp.cmp and splash5-pal.bmp that are // in the bitmaps\ dir if you want to distribute your compile. When you do you // must include our copyright statement and clearly indicate that you have made // a derived version. // You MAY NOT remove or disable the splash screen code. SplashScreen (NULL) ; strcpy (str, szCmdLine) ; strupr (str) ; if ((s = strstr (str, "PVENGINE.EXE")) != NULL) { szCmdLine += (int) (s - str) + 12 ; if (*szCmdLine == '"') szCmdLine++ ; } if (strnicmp (szCmdLine, "/DEBUG", 6) == 0) { debugging++ ; debugFile = fopen ("c:\\povray.dbg", "wt") ; } version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO) ; GetVersionEx (&version_info) ; hMainThread = GetCurrentThread () ; use_editors = TRUE ; IsWin32 = HaveWin95OrLater () || HaveWinNT () ; IsW98 = HaveWin98OrLater () ; if (HaveWin95OrLater ()) { using_ctl3d = FALSE ; IsW95UserInterface = TRUE ; } init_menus () ; getHome () ; if (HomePath [0] == '\0') { MessageBox (NULL, "ERROR : Cannot find Home entry in registry.\n\n" "This entry should have been set by the installation program.\n\n" "If you did not install using the correct installation procedure, please " "do this before running POV-Ray for Windows. Otherwise, consult the README.DOC " "file that should have accompanied this executable file.", "Critical Error", MB_ICONSTOP) ; return (1) ; } if (HomePath [strlen (HomePath) - 1] != '\\') strcat (HomePath, "\\") ; strupr (HomePath) ; sprintf (EngineIniFileName, "%sINI", HomePath) ; if (debugFile) fprintf (debugFile, "INI path is '%s'\n", EngineIniFileName) ; if (stat (EngineIniFileName, &statbuf) != 0 || (statbuf.st_mode & S_IFREG) != 0) { if (debugFile) fprintf (debugFile, "INI directory not found\n") ; MessageBox (NULL, "ERROR : Cannot find INI directory in expected location\n\n" "This directory should have been created by the installation program.\n\n" "If you did not install using the correct installation procedure, please " "do this before running POV-Ray for Windows. Otherwise, consult the README.DOC " "file that should have accompanied this executable file.", "Critical Error", MB_ICONSTOP) ; return (1) ; } strcat (EngineIniFileName, "\\"INIFILENAME) ; sprintf (DefaultRenderIniFileName, "%sRENDERER\\POVRAY.INI", HomePath) ; sprintf (RerunIniPath, "%sRENDERER\\RERUN\\", HomePath) ; sprintf (CurrentRerunFileName, "%sRENDERER\\RERUN\\CURRENT.INI", HomePath) ; sprintf (ToolIniFileName, "%sINI\\"TOOLFILENAME, HomePath) ; GetModuleFileName (hInst, str, sizeof (str) - 1) ; splitpath (str, ourPath, NULL) ; sprintf (engineHelpPath, "%shelp\\PVENGINE.HLP", HomePath) ; sprintf (rendererHelpPath, "%shelp\\POVRAY31.HLP", HomePath) ; IsW95UserInterface = GetPrivateProfileInt ("General", "UseW95UserInterface", 1, EngineIniFileName) ; read_INI_settings (EngineIniFileName) ; if (!IsWin32) IsW95UserInterface = FALSE ; if (IsW95UserInterface) using_ctl3d = FALSE ; if (!IsW95UserInterface) { PVEnableMenuItem (CM_SHOWMAINWINDOW, MF_GRAYED) ; use_taskbar = FALSE ; } InitializeCriticalSection (&critical_section) ; if (GetPrivateProfileInt ("General", "BigSplash", 0, EngineIniFileName) + 86400 < time (NULL)) splash_time = 4 ; GetPrivateProfileString ("General", "CommandLine", "", old_command_line, sizeof (old_command_line), EngineIniFileName) ; if ((szCmdLine = preparse_commandline (szCmdLine)) != NULL) { parse_commandline (szCmdLine) ; if (!demo_mode) { restore_command_line = TRUE ; strncpy (command_line, szCmdLine, sizeof (command_line) - 1) ; } } if (one_instance && (hwnd = FindWindow (PovMainWinClass, NULL)) != NULL) { setCommandLine (command_line) ; if (IsIconic (hwnd)) ShowWindow (hwnd, SW_RESTORE) ; SetForegroundWindow (hwnd) ; PostMessage (hwnd, RENDER_MESSAGE, demo_mode, 0) ; return (0) ; } if (hPrev == NULL) { #ifdef __USECTL3D__ if (using_ctl3d) { if ((hLibCtl3d = LoadLibrary ("CTL3D32.DLL")) != NULL) { Ctl3dRegister = GetProcAddress (hLibCtl3d, "Ctl3dRegister") ; Ctl3dAutoSubclass = GetProcAddress (hLibCtl3d, "Ctl3dAutoSubclass") ; Ctl3dUnregister = GetProcAddress (hLibCtl3d, "Ctl3dUnregister") ; if (Ctl3dRegister != NULL && Ctl3dAutoSubclass != NULL && Ctl3dUnregister != NULL) { if (Ctl3dRegister (hInst)) Ctl3dAutoSubclass (hInst) ; else PovMessageBox ("CTL3D initialisation failed - check version of CTL3D32.DLL\n\n[Execution will continue normally]", "CTL3D Error") ; } else PovMessageBox ("CTL3D initialisation failed [GetProcAddress for CTL3D32.DLL failed.]", "CTL3D Error") ; } else PovMessageBox ("CTL3D initialisation failed [LoadLibrary for CTL3D32.DLL failed.]", "CTL3D Error") ; } #endif } sprintf (str, "%sbin\\cmedit.dll", HomePath) ; if (!LoadEditorDLL (str)) use_editors = FALSE ; GetPrivateProfileString ("General", "Version", "", str, strlen (str), EngineIniFileName) ; if (debugFile) fprintf (debugFile, "INI version is %s, and we are %s\n", str, PVENGINE_VER) ; newVersion = strcmp (str, PVENGINE_VER) ; if ((run_count = GetPrivateProfileInt ("General", "RunCount", 0, EngineIniFileName)) == 0 || newVersion) { if (screen_depth < 8) { MessageBox (NULL, "NOTE : POV-Ray for Windows was not designed to run in 16-color mode. " "While the program will operate, it is recommended that you use a minimum " "graphics mode of 800x600x256.", "Warning - running in 16-color mode", MB_ICONEXCLAMATION) ; tile_background = FALSE ; } if (screen_width < 800) { MessageBox (NULL, "NOTE : POV-Ray for Windows was not designed to run at less than 800x600.\n\n" "While the program will operate, it is recommended that you use a minimum " "graphics mode of 800x600x256.", "Warning - running at less than 800x600", MB_ICONEXCLAMATION) ; } } PutPrivateProfileInt ("General", "RunCount", ++run_count, EngineIniFileName) ; if (screen_depth < 8) tile_background = FALSE ; hPopupMenus = LoadMenu (hInstance, MAKEINTRESOURCE (IsWin32 ? POPUP_MENUS32 : POPUP_MENUS)) ; hAccelerators = LoadAccelerators (hInstance, MAKEINTRESOURCE (PVENGINE_MENU)) ; /* Create the main window */ placement = mainwin_placement ; placement.length = sizeof (WINDOWPLACEMENT) ; w = mainwin_placement.rcNormalPosition.right - mainwin_placement.rcNormalPosition.left ; h = mainwin_placement.rcNormalPosition.bottom - mainwin_placement.rcNormalPosition.top ; if (w <= 0) w = 512 ; if (h <= 0) h = 512 ; main_window = CreateWindowEx (0, PovMainWinClass, "POV-Ray for Windows", WS_OVERLAPPEDWINDOW, mainwin_placement.rcNormalPosition.left, mainwin_placement.rcNormalPosition.top, w, h, NULL, NULL, hInst, NULL) ; if (main_window == NULL) { MessageBox (NULL, "ERROR : Could not create main window.", "Critical Error", MB_ICONSTOP) ; cleanup_all () ; return (1) ; } EditSetNotifyBase (main_window, CM_FIRSTEDITNOTIFY) ; if ((StatusWindow = CreateStatusbar (main_window)) == NULL) { MessageBox (main_window, "ERROR : Could not create statusbar", "Critical Error", MB_ICONSTOP) ; cleanup_all () ; return (1) ; } if (use_template == 2) { use_template = TRUE ; PVCheckMenuItem (CM_USETEMPLATE, use_template ? MF_CHECKED : MF_UNCHECKED) ; } if ((timer_id = SetTimer (main_window, 1, 1000, NULL)) != 0) DragAcceptFiles (main_window, TRUE) ; if (splash_window != NULL) { if (timer_id != 0) { while (seconds < splash_time && GetMessage (&msg, NULL, 0, 0) == TRUE) { if (!TranslateAccelerator (main_window, hAccelerators, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } } DestroyWindow (splash_window) ; if (splash_time == 4) PutPrivateProfileInt ("General", "BigSplash", time (NULL), EngineIniFileName) ; } clear_system_palette () ; hPalApp = create_palette (NULL, 0) ; if (tile_background && background_file [1]) { if ((hDIB = LoadDIB (background_file)) != NULL) { hBmpBackground = DIBToBitmap (hDIB, hPalApp) ; DeleteObject (hDIB) ; GetObject (hBmpBackground, sizeof (BITMAP), (LPSTR) &bm) ; background_width = bm.bmWidth ; background_height = bm.bmHeight ; } else { PovMessageBox ("Failed to load bitmap file", "Error") ; strcpy (background_file, "0") ; } } if (tile_background && hBmpBackground == NULL && screen_depth >= 8) { if (isdigit (background_file [0]) && background_file [1] == '\0') id = background_file [0] - '0' ; SendMessage (main_window, WM_COMMAND, CM_BACKGROUNDSTD + id, 1L) ; } if ((hBMP = LoadBitmap (hInstance, MAKEINTRESOURCE (BMP_ICON))) != NULL) hBmpIcon = hBMP ; if (lastBitmapPath [0] == '\0') sprintf (lastBitmapPath, "%sTILES", HomePath) ; if (lastRenderPath [0] == '\0') { sprintf (lastRenderPath, "%sSCENES\\OBJECTS", HomePath) ; strcpy (lastRenderName, "TORUS1.POV") ; } if (lastQueuePath [0] == '\0') sprintf (lastQueuePath, "%sSCENES", HomePath) ; GetPrivateProfileString ("Editor", "LastPath", "", str, sizeof (str), EngineIniFileName) ; validatePath (lastRenderPath) ; if (str [0] == '\0') WritePrivateProfileString ("Editor", "LastPath", lastRenderPath, EngineIniFileName) ; if (lastRenderName [0] != '\0' && !demo_mode) joinPath (source_file_name, lastRenderPath, lastRenderName) ; add_rerun_to_menu () ; if (use_editors) if ((hwnd = InitialiseEditor (main_window, StatusWindow, HomePath)) == NULL) use_editors = 0 ; message_window = CreateWindow (PovMessageWinClass, "", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, use_editors ? hwnd : main_window, NULL, hInst, NULL) ; if (message_window == NULL) { MessageBox (NULL, "ERROR : Could not create message window.", "Critical Error", MB_ICONSTOP) ; cleanup_all () ; return (1) ; } if (initialise_message_display ()) { cleanup_all () ; return (1) ; } EditSetMessageWindow (message_window) ; if ((rebar_window = create_rebar (main_window)) == NULL) { MessageBox (main_window, "ERROR : Could not create internal window #1", "Critical Error", MB_ICONSTOP) ; cleanup_all () ; return (1) ; } if ((toolbar_window = create_toolbar (rebar_window)) == NULL) { MessageBox (main_window, "ERROR : Could not create internal window #2", "Critical Error", MB_ICONSTOP) ; cleanup_all () ; return (1) ; } if (!use_toolbar) { ShowWindow (rebar_window, SW_HIDE) ; toolheight = 0 ; } SetTimer (renderanim_window, 2, 100, NULL) ; extract_ini_sections_ex (SecondaryRenderIniFileName, toolbar_combobox) ; select_combo_item_ex (toolbar_combobox, SecondaryRenderIniFileSection) ; setup_menus (use_editors) ; build_main_menu (hMainMenu, use_editors) ; set_toggles () ; if (!use_editors) { SendMessage (toolbar_window, TB_ENABLEBUTTON, CM_FILENEW, 0L) ; SendMessage (toolbar_window, TB_ENABLEBUTTON, CM_FILEOPEN, 0L) ; SendMessage (toolbar_window, TB_ENABLEBUTTON, CM_FILESAVE, 0L) ; } else EditRestoreState (!NoRestore) ; if (use_editors) PVCheckMenuItem (CM_USEEDITOR, MF_CHECKED) ; PVEnableMenuItem (CM_RENDERHIDE, render_above_main ? MF_GRAYED : MF_ENABLED) ; PVCheckMenuItem (on_completion, MF_CHECKED) ; PVEnableMenuItem (CM_RENDERSHOW, MF_GRAYED) ; PVEnableMenuItem (CM_RENDERSLEEP, MF_GRAYED) ; PVCheckMenuItem (render_priority, MF_CHECKED) ; PVCheckMenuItem (GUI_priority, MF_CHECKED) ; PVCheckMenuItem (drop_to_editor ? CM_DROPEDITOR : CM_DROPRENDERER, MF_CHECKED) ; PVEnableMenuItem (CM_RENDERSHOW, MF_GRAYED) ; PVEnableMenuItem (CM_RENDERCLOSE, MF_GRAYED) ; PVModifyMenu (CM_TILEDBACKGROUND, MF_STRING, CM_TILEDBACKGROUND, tile_background ? "&Select Plain Background" : "&Select Tiled Background") ; if (screen_depth < 8) { PVEnableMenuItem (CM_TILEDBACKGROUND, MF_GRAYED) ; PVEnableMenuItem (CM_BACKGROUNDBITMAP, MF_GRAYED) ; for (i = 0 ; i < 16 ; i++) PVEnableMenuItem (CM_BACKGROUNDSTD + i, MF_GRAYED) ; } GetWindowsDirectory (str, sizeof (str)) ; strcat (str, "\\gocserve.exe") ; if (stat (str, &statbuf) != 0) PVDeleteMenuItem (CM_GOPOVRAY) ; switch (placement.showCmd) { case SW_SHOWNORMAL : show_state = SW_SHOW ; break ; case SW_SHOWMINIMIZED : show_state = SW_SHOWMINNOACTIVE ; break ; case SW_SHOWMAXIMIZED : show_state = SW_SHOWMAXIMIZED ; break ; default : show_state = SW_SHOW ; break ; } placement.showCmd = show_state ; placement.flags = (placement.ptMinPosition.x == -1 && placement.ptMinPosition.y == -1) ? 0 : WPF_SETMINPOSITION ; if (placement.rcNormalPosition.right <= 0 || placement.rcNormalPosition.bottom <= 0) { placement.rcNormalPosition.right = placement.rcNormalPosition.left + message_xchar * 115 ; placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + message_ychar * 49 ; } placement.length = sizeof (WINDOWPLACEMENT) ; SetWindowPlacement (main_window, &placement) ; if (show_state != SW_SHOWMAXIMIZED) FitWindowInWindow (NULL, main_window) ; if (use_toolbar) { hDC = GetDC (toolbar_window) ; GetClientRect (toolbar_window, &rect) ; FillRect (hDC, &rect, GetStockObject (LTGRAY_BRUSH)) ; ReleaseDC (toolbar_window, hDC) ; } if (run_count > 1 || !demo_mode) { n = GetPrivateProfileInt ("General", "ItsAboutTime", 0, EngineIniFileName) ; if (time (NULL) > n || newVersion) { DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_ABOUT), main_window, (DLGPROC) PovAboutDialogProc, (LPARAM) main_window) ; PutPrivateProfileInt ("General", "ItsAboutTime", n ? time (NULL) + 14L * 86400L : time (NULL) + 86400L, EngineIniFileName) ; } } if (ExtensionsEnabled) LoadGUIExtensions () ; buffer_message (mIDE, "Persistence of Vision Ray Tracer(tm) for Windows.\n") ; buffer_message (mIDE, "POV-Ray for Windows is part of the POV-Ray(tm) suite of programs.\n") ; buffer_message (mIDE, " This is version " POV_RAY_VERSION COMPILER_VER "." PVENGINE_VER " [" OPTIMISATION " optimized].\n") ; buffer_message (mIDE, "The POV-Ray software is Copyright 1991-1998 POV-Team(tm).\n") ; buffer_message (mIDE, "This is an UNSUPPORTED UNOFFICIAL COMPILE by " UNOFFICIALCOMPILE "\n") ; buffer_message (mIDE, " It is distributable only under the conditions in POVLEGAL.DOC.\n") ; buffer_message (mIDE, " Select Help|About (or press Alt+B) for more information and a copy of POVLEGAL.DOC.\n") ; buffer_message (mIDE, "\n") ; buffer_message (mIDE, "The terms POV-Ray, POV-Team, and Persistence of Vision Raytracer are trademarks of the\n") ; buffer_message (mIDE, " Persistence of Vision Development Team (POV-Team)\n") ; if (render_bitmap_depth != 24) { buffer_message (mIDE, "\n") ; buffer_message (mIDE, renderwin_8bits ? "Using 8-bit dithered internal bitmap (menu setting)\n" : "Using 8-bit dithered internal bitmap (4 or 8-bit video mode)\n") ; } pre_init_povray () ; Usage (-1, FALSE) ; if (IsWin32) { buffer_message (mIDE, "\n") ; strcpy (tool_commands [0], "notepad.exe \"%ipovray.ini\"") ; } else strcpy (tool_commands [0], "notepad.exe %ipovray.ini") ; buffer_message (mIDE, "This is an UNSUPPORTED UNOFFICIAL COMPILE by " UNOFFICIALCOMPILE "\n") ; buffer_message (mDivider, "\n") ; load_tool_menu (ToolIniFileName) ; if (GetPrivateProfileInt ("FileQueue", "ReloadOnStartup", 0, EngineIniFileName)) { queued_file_count = GetPrivateProfileInt ("FileQueue", "QueueCount", 0, EngineIniFileName) ; if (queued_file_count > MAX_QUEUE) queued_file_count = MAX_QUEUE ; for (i = 0 ; i < queued_file_count ; i++) { sprintf (str, "QueuedFile%d", i) ; GetPrivateProfileString ("FileQueue", str, "", queued_files [i], sizeof (queued_files [0]), EngineIniFileName) ; } if (queued_file_count != 0) message_printf ("Loaded %d entr%s into file queue\n", queued_file_count, queued_file_count == 1 ? "y" : "ies") ; update_queue_status (FALSE) ; } buffer_message (mDivider, "\n") ; if (GetPrivateProfileInt ("General", "CheckColorsInc", 1, EngineIniFileName) == 1) { sprintf (str, "%sinclude\\colors.inc", HomePath) ; if (stat (str, &statbuf) != 0) { if (MessageBox (NULL, "WARNING : Cannot find COLORS.INC in expected location.\n\n" "This file is important for the normal operation of POV-Ray. It is included " "with the POV-Ray for Windows distribution. If you did not install using the " "correct installation procedure please attend to this before running POV-Ray " "for Windows.\n\nIf, however, you have chosen to change the location of this file " "or do not need it, you may ignore this warning as long as you have updated " "POVRAY.INI to the new path, or do not use any standard scenes that require it.\n\n" "Do you want to see this warning again ?", "Warning - COLORS.INC is missing", MB_ICONEXCLAMATION | MB_YESNO) == IDNO) PutPrivateProfileInt ("General", "CheckColorsInc", 0, EngineIniFileName) ; } } if (demo_mode) { message_printf ("Running demonstration\n") ; argc = 0 ; handle_main_command (CM_DEMO, 0) ; PovMessageBox ("Demonstration completed. POV-Ray will now exit.", "Finished test run") ; WinHelp (main_window, "pvengine.hlp", HELP_QUIT, NULL) ; WinHelp (main_window, "povray31.hlp", HELP_QUIT, NULL) ; DestroyWindow (main_window) ; cleanup_all () ; return (0) ; } // automatically call the rendering engine if there were any parameters on the command line if (argc > 1 || render_requested) { if (render_requested) { message_printf ("Requested render file is '%s'\n", requested_render_file) ; strcpy (source_file_name, requested_render_file) ; } if (argc > 1) message_printf ("Calling rendering engine with parameters '%s'\n", command_line) ; start_rendering (TRUE, !render_requested) ; if (exit_after_render) { WinHelp (main_window, "pvengine.hlp", HELP_QUIT, NULL) ; WinHelp (main_window, "povray31.hlp", HELP_QUIT, NULL) ; DestroyWindow (main_window) ; cleanup_all () ; return (0) ; } } GetPrivateProfileString ("General", "CommandLine", "", command_line, sizeof (command_line), EngineIniFileName) ; restore_command_line = FALSE ; if (tips_enabled && argc <= 1) { n = GetPrivateProfileInt ("TipOfTheDay", "LastTipTime", 0, EngineIniFileName) ; if (time (NULL) >= n + 86400L) { PutPrivateProfileInt ("TipOfTheDay", "LastTipTime", time (NULL), EngineIniFileName) ; DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_TIP), main_window, (DLGPROC) PovTipDialogProc, (LPARAM) main_window) ; } } if (debugging) { message_printf ("My window handle is %08lx\n", main_window) ; if (HaveWin95OrLater ()) message_printf ("Win95 or later detected\n") ; if (HaveWin98OrLater ()) message_printf ("Win98 or later detected\n") ; if (HaveWinNT ()) message_printf ("WinNT detected\n") ; if (HaveWin32s ()) message_printf ("Win32s detected\n") ; if (IsW95UserInterface) message_printf ("Windows 95 user interface flag is set\n") ; } for (i = 0 ; i < EditFileCount ; i++) { if (EditGetFlags () & EDIT_CAN_OPEN) EditOpenFile (EditFiles [i]) ; free (EditFiles [i]) ; EditFiles [i] = NULL ; } EditFileCount = 0 ; if (debugFile) fprintf (debugFile, "Entering GetMessage () loop\n") ; while (GetMessage (&msg, NULL, 0, 0) == TRUE) { if (!TranslateAccelerator (main_window, hAccelerators, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } #ifdef __USECTL3D__ if (using_ctl3d) { if (hPrev == NULL) if (Ctl3dUnregister != NULL) Ctl3dUnregister (hInst) ; } #endif cleanup_all () ; fcloseall () ; return (msg.wParam) ; }