povray/windows/pvguiext.cpp
2013-11-06 13:07:19 -05:00

710 lines
27 KiB
C++

/*******************************************************************************
* pvguiext.cpp
*
* This file contains POV-Ray for Windows GUI Extension support code.
*
* Author: Christopher J. Cason.
*
* ---------------------------------------------------------------------------
* Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
* Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
*
* POV-Ray is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* POV-Ray is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------------
* POV-Ray 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.
* ---------------------------------------------------------------------------
* $File: //depot/public/povray/3.x/windows/pvguiext.cpp $
* $Revision: #1 $
* $Change: 6069 $
* $DateTime: 2013/11/06 11:59:40 $
* $Author: chrisc $
*******************************************************************************/
#define POVWIN_FILE
#define _WIN32_IE COMMONCTRL_VERSION
#include <setjmp.h>
#include <string.h>
#include <windows.h>
#include <commctrl.h>
#include "pvengine.h"
#include "pvedit.h"
#include "resource.h"
#include "pvdialog.h"
#include "pvguiext.h"
// this must be the last file included
#include "syspovdebug.h"
namespace povwin
{
typedef struct _RGPB0X0100
{
DWORD Signature ;
DWORD InstanceID ;
BOOL (WINAPI *Init) (DWORD InstanceID, int RecSize, GuiExtInitStruct *InitStruct) ;
void (WINAPI *Destroy) (IDataStruct *InstanceData) ;
DWORD (WINAPI *MenuSelect) (IDataStruct *InstanceData, WPARAM Code) ;
LPSTR (WINAPI *MenuTip) (IDataStruct *InstanceData, WPARAM Code) ;
DWORD (WINAPI *Event) (IDataStruct *InstanceData, ExternalEvents Event, DWORD EventVal) ;
void (WINAPI *DisplayPlot) (IDataStruct *InstanceData, int x, int y, int Red, int Green, int Blue, int Alpha) ;
void (WINAPI *DisplayPlotRect) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha) ;
void (WINAPI *WinPrePixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
void (WINAPI *WinPostPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
BOOL (WINAPI *WinSystem) (IDataStruct *InstanceData, LPSTR command, int *returnval) ;
void (WINAPI *CleanupAll) (IDataStruct *InstanceData) ;
void (WINAPI *BufferMessage) (IDataStruct *InstanceData, msgtype message_type, LPSTR message) ;
LPSTR (WINAPI *ParseToolCommand) (IDataStruct *InstanceData, char command [512]) ;
BOOL (WINAPI *DragFunction) (IDataStruct *InstanceData, LPSTR szFile, ExternalDropType DropType) ;
struct _RGPB0X0100 *Next ;
int IniID ;
IDataStruct InstanceData ;
char Name [256] ;
char Author [256] ;
char AuthorEmail [256] ;
char FileName [_MAX_PATH] ;
} RealGuiPointerBlock_Version_100 ;
typedef struct _RGPB0X0101
{
DWORD Signature ;
DWORD InstanceID ;
BOOL (WINAPI *Init) (DWORD InstanceID, int RecSize, GuiExtInitStruct *InitStruct) ;
void (WINAPI *Destroy) (IDataStruct *InstanceData) ;
DWORD (WINAPI *MenuSelect) (IDataStruct *InstanceData, WPARAM Code) ;
LPSTR (WINAPI *MenuTip) (IDataStruct *InstanceData, WPARAM Code) ;
DWORD (WINAPI *Event) (IDataStruct *InstanceData, ExternalEvents Event, DWORD EventVal) ;
void (WINAPI *DisplayPlot) (IDataStruct *InstanceData, int x, int y, int Red, int Green, int Blue, int Alpha) ;
void (WINAPI *DisplayPlotRect) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha) ;
void (WINAPI *WinPrePixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
void (WINAPI *WinPostPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
BOOL (WINAPI *WinSystem) (IDataStruct *InstanceData, LPSTR command, int *returnval) ;
void (WINAPI *CleanupAll) (IDataStruct *InstanceData) ;
void (WINAPI *BufferMessage) (IDataStruct *InstanceData, msgtype message_type, LPSTR message) ;
LPSTR (WINAPI *ParseToolCommand) (IDataStruct *InstanceData, char command [512]) ;
BOOL (WINAPI *DragFunction) (IDataStruct *InstanceData, LPSTR szFile, ExternalDropType DropType) ;
void (WINAPI *AssignPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
struct _RGPB0X0101 *Next ;
int IniID ;
IDataStruct InstanceData ;
char Name [256] ;
char Author [256] ;
char AuthorEmail [256] ;
char FileName [_MAX_PATH] ;
} RealGuiPointerBlock_Version_101 ;
typedef struct _RGPB
{
DWORD Signature ;
DWORD InstanceID ;
BOOL (WINAPI *Init) (DWORD InstanceID, int RecSize, GuiExtInitStruct *InitStruct) ;
void (WINAPI *Destroy) (IDataStruct *InstanceData) ;
DWORD (WINAPI *MenuSelect) (IDataStruct *InstanceData, WPARAM Code) ;
LPSTR (WINAPI *MenuTip) (IDataStruct *InstanceData, WPARAM Code) ;
DWORD (WINAPI *Event) (IDataStruct *InstanceData, ExternalEvents Event, DWORD EventVal) ;
void (WINAPI *DisplayPlot) (IDataStruct *InstanceData, int x, int y, int Red, int Green, int Blue, int Alpha) ;
void (WINAPI *DisplayPlotRect) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha) ;
void (WINAPI *WinPrePixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
void (WINAPI *WinPostPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
BOOL (WINAPI *WinSystem) (IDataStruct *InstanceData, LPSTR command, int *returnval) ;
void (WINAPI *CleanupAll) (IDataStruct *InstanceData) ;
void (WINAPI *BufferMessage) (IDataStruct *InstanceData, msgtype message_type, LPSTR message) ;
LPSTR (WINAPI *ParseToolCommand) (IDataStruct *InstanceData, char command [512]) ;
BOOL (WINAPI *DragFunction) (IDataStruct *InstanceData, LPSTR szFile, ExternalDropType DropType) ;
void (WINAPI *AssignPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
void (WINAPI *DisplayPlotBlock) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, const GuiRGBA8* colour) ;
struct _RGPB *Next ;
int IniID ;
IDataStruct InstanceData ;
char Name [256] ;
char Author [256] ;
char AuthorEmail [256] ;
char FileName [_MAX_PATH] ;
} RealGuiPointerBlock ;
DWORD CooperateLevel = 9 ; // this should really be per-GUIEXT rather than global
GuiExtInitStruct InitStruct ;
RealGuiPointerBlock *GuiPointerBlocks = NULL ;
DWORD (WINAPI *GuiExtGetPointers) (int RecSize, GuiPointerBlock *PointerBlock) ;
extern char source_file_name [_MAX_PATH] ;
extern bool ExtensionsEnabled ;
extern bool rendering ;
extern bool stop_rendering ;
extern bool hide_newuser_help ;
extern bool debugging;
extern HWND main_window ;
extern HMENU hPluginsMenu ;
void getvars (ExternalVarStruct *v) ;
void setvars (ExternalVarStruct *v) ;
DWORD ExternalEvent (ExternalEvents Event, DWORD EventVal)
{
DWORD rval = 0 ;
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return (0) ;
if (Event == EventWinCooperate)
if (EventVal >= CooperateLevel)
return (0) ;
p = GuiPointerBlocks ;
while (p)
{
if (p->Event != NULL)
rval |= (*p->Event ) (&p->InstanceData, Event, EventVal) ;
p = p->Next ;
}
return (rval) ;
}
void ExternalDisplayPlot (int x, int y, int Red, int Green, int Blue, int Alpha)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
p = GuiPointerBlocks ;
while (p)
{
if (p->DisplayPlot != NULL)
(*p->DisplayPlot) (&p->InstanceData, x, y, Red, Green, Blue, Alpha) ;
p = p->Next ;
}
}
void ExternalDisplayPlotBlock (int x1, int y1, int x2, int y2, const GuiRGBA8* colour)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
int pixelsCount = ( x2 - x1 + 1 ) * ( y2 - y1 + 1 );
GuiRGBA8* localColourCopy = NULL;
p = GuiPointerBlocks ;
while (p)
{
if (p->DisplayPlotBlock != NULL)
{
if (localColourCopy == NULL)
localColourCopy = new GuiRGBA8[ pixelsCount ];
memcpy( localColourCopy, colour, pixelsCount * sizeof( GuiRGBA8 ) );
(*p->DisplayPlotBlock) (&p->InstanceData, x1, y1, x2, y2, localColourCopy ) ;
}
p = p->Next ;
}
delete[] localColourCopy;
}
void ExternalDisplayPlotRect (int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
p = GuiPointerBlocks ;
while (p)
{
if (p->DisplayPlotRect != NULL)
(*p->DisplayPlotRect) (&p->InstanceData, x1, y1, x2, y2, Red, Green, Blue, Alpha) ;
p = p->Next ;
}
}
void ExternalWinPrePixel (int x, int y, COLOUR colour)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
p = GuiPointerBlocks ;
while (p)
{
if (p->WinPrePixel != NULL)
(*p->WinPrePixel) (&p->InstanceData, x, y, colour) ;
p = p->Next ;
}
}
void ExternalWinPostPixel (int x, int y, COLOUR colour)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
p = GuiPointerBlocks ;
while (p)
{
if (p->WinPostPixel != NULL)
(*p->WinPostPixel) (&p->InstanceData, x, y, colour) ;
p = p->Next ;
}
}
void ExternalAssignPixel (int x, int y, COLOUR colour)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
p = GuiPointerBlocks ;
while (p)
{
if (p->AssignPixel != NULL)
(*p->AssignPixel) (&p->InstanceData, x, y, colour) ;
p = p->Next ;
}
}
BOOL ExternalWinSystem (LPSTR command, int *returnval)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return (false) ;
p = GuiPointerBlocks ;
while (p)
{
if (p->WinSystem != NULL)
if ((*p->WinSystem) (&p->InstanceData, command, returnval))
return (true) ;
p = p->Next ;
}
return (false) ;
}
void ExternalCleanupAll (void)
{
// always enabled
while (GuiPointerBlocks)
{
if (GuiPointerBlocks->Destroy != NULL)
(*GuiPointerBlocks->Destroy) (&GuiPointerBlocks->InstanceData) ;
GuiPointerBlocks = GuiPointerBlocks->Next ;
}
}
void ExternalBufferMessage (msgtype message_type, LPSTR message)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
p = GuiPointerBlocks ;
while (p)
{
if (p->BufferMessage != NULL)
(*p->BufferMessage) (&p->InstanceData, message_type, message) ;
p = p->Next ;
}
}
void ExternalParseToolCommand (char command [512])
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ;
p = GuiPointerBlocks ;
while (p)
{
if (p->ParseToolCommand != NULL)
(*p->ParseToolCommand) (&p->InstanceData, command) ;
p = p->Next ;
}
}
BOOL ExternalDragFunction (LPSTR szFile, ExternalDropType DropType)
{
int n ;
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return (false) ;
n = get_file_type (szFile) ;
if (n == filePOV || n == fileINI)
return (false) ;
p = GuiPointerBlocks ;
while (p)
{
if (p->DragFunction != NULL)
if ((*p->DragFunction) (&p->InstanceData, szFile, DropType))
return (true) ;
p = p->Next ;
}
return (false) ;
}
ExternalRequestResult WINAPI ExternalRequest (ExternalRequests Request, void *RequestBlock)
{
if (!ExtensionsEnabled)
return (ExRequestDisabled) ;
switch (Request)
{
case RequestGetVars :
if (((ExternalVarStruct *) RequestBlock)->RecSize != sizeof (ExternalVarStruct))
return (ExRequestBadRecSize) ;
getvars ((ExternalVarStruct *) RequestBlock) ;
return (ExRequestOK) ;
case RequestSetVars :
if (((ExternalVarStruct *) RequestBlock)->RecSize != sizeof (ExternalVarStruct))
return (ExRequestBadRecSize) ;
setvars ((ExternalVarStruct *) RequestBlock) ;
return (ExRequestOK) ;
case RequestSetCooperateLevel :
CooperateLevel = *(DWORD *) RequestBlock ;
return (ExRequestOK) ;
case RequestStartRendering :
if (rendering)
return (ExRequestFailedRendering) ;
message_printf ("Rendering started by GUI extension\n") ;
start_rendering (false) ;
return (ExRequestOK) ;
case RequestStopRendering :
if (!rendering)
return (ExRequestFailedNotRendering) ;
stop_rendering = true ;
message_printf ("Rendering stopped by GUI extension\n") ;
SendMessage (main_window, WM_COMMAND, CM_STOPRENDER, 0) ;
return (ExRequestOK) ;
case RequestExit :
if (rendering)
return (ExRequestFailedRendering) ;
message_printf ("Exit requested by GUI extension\n") ;
Sleep (1000) ;
SendMessage (main_window, WM_CLOSE, 0, 0) ;
return (ExRequestOK) ;
}
return (ExRequestUnknown) ;
}
DWORD ExternalMenuSelect (WPARAM Code)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return (1) ;
p = GuiPointerBlocks ;
while (p)
{
if (Code >= p->InstanceData.FirstMenuItem && Code <= p->InstanceData.FirstMenuItem + 59)
return ((*p->MenuSelect) (&p->InstanceData, Code - p->InstanceData.FirstMenuItem)) ;
p = p->Next ;
}
return (1) ;
}
char *ExternalMenuTip (WPARAM wParam)
{
RealGuiPointerBlock *p ;
if (!ExtensionsEnabled)
return ("Extensions Disabled") ;
p = GuiPointerBlocks ;
while (p)
{
if (wParam >= p->InstanceData.FirstMenuItem && wParam <= p->InstanceData.FirstMenuItem + 59)
return ((*p->MenuTip) (&p->InstanceData, wParam - p->InstanceData.FirstMenuItem)) ;
p = p->Next ;
}
return ("") ;
}
bool ValidateMenu (HMENU hMenu, int first, int last)
{
int count ;
int i ;
int id ;
HMENU hSubMenu ;
count = GetMenuItemCount (hMenu) ;
for (i = 0 ; i < count ; i++)
{
if ((id = GetMenuItemID (hMenu, i)) == 0xffffffff)
{
// could be a popup menu
if ((hSubMenu = GetSubMenu (hMenu, i)) == NULL)
continue ;
if (!ValidateMenu (hSubMenu, first, last))
return (false) ;
continue ;
}
if (id == 0 || id == 0xffff)
continue ;
if (id < first || id > last)
return (false) ;
}
return (true) ;
}
void LoadGUIExtensions (void)
{
int i ;
int FirstMenuItem = CM_FIRSTGUIEXT ;
char str [64] ;
char filename [_MAX_PATH] ;
char name [_MAX_PATH] ;
bool first = true ;
bool loaded = false ;
HINSTANCE hLib ;
GuiPointerBlock PointerBlock ;
RealGuiPointerBlock *RealPointerBlock ;
RealGuiPointerBlock *LastPointerBlock = NULL ;
if (!ExtensionsEnabled)
return ;
for (i = 0 ; i < MAX_GUI_EXT ; i++)
{
sprintf (str, "ExtDll%02d", i) ;
GetHKCU("GuiExtensions", str, "", filename, sizeof (filename));
if (filename [0] != '\0')
{
if (first)
{
first = false ;
buffer_message (mDivider, "\n") ;
message_printf ("DISCLAIMER : The POV-Team takes no responsibility for the operation of third-party GUI Extensions.\n") ;
message_printf (" Please do not send us bug reports if they cause things to go haywire.\n\n") ;
}
splitpath (filename, NULL, name) ;
if ((hLib = LoadLibrary (filename)) == NULL)
{
if (debugging)
debug_output ("Could not load GUI Extension DLL '%s', error code is %08lx\n", filename, GetLastError ()) ;
message_printf ("Could not load GUI Extension DLL '%s'\n", name) ;
continue ;
}
GuiExtGetPointers = (unsigned long(WINAPI *)(int, GuiPointerBlock *))GetProcAddress (hLib, "PovGuiExtensionGetPointers") ;
if (GuiExtGetPointers == NULL)
{
if (debugging)
debug_output ("Could not get Init process address for GUI extension '%s', error code is %08lx\n", filename, GetLastError ()) ;
message_printf ("Could not get Init address for GUI Extension DLL '%s'\n", name) ;
message_printf (" Contact author of '%s'\n", name) ;
FreeLibrary (hLib) ;
continue ;
}
memset (&PointerBlock, 0, sizeof (PointerBlock)) ;
if (GuiExtGetPointers (sizeof (PointerBlock), &PointerBlock) == 0)
{
if (debugging)
debug_output ("Could not get pointers for GUI extension '%s'\n", filename) ;
message_printf ("Could not get pointers for GUI extension '%s'\n", name) ;
message_printf (" Contact author of '%s'\n", name) ;
FreeLibrary (hLib) ;
continue ;
}
if (PointerBlock.Init == NULL ||
PointerBlock.MenuSelect == NULL ||
PointerBlock.MenuTip == NULL ||
(PointerBlock.Signature != 'CJC!' && PointerBlock.Signature != '!CJC'))
{
if (debugging)
debug_output ("PointerBlock not correctly initialized by GUI extension '%s'\n", filename) ;
message_printf ("PointerBlock not correctly initialized by GUI extension '%s'\n", name) ;
message_printf (" Contact author of '%s'\n", name) ;
FreeLibrary (hLib) ;
continue ;
}
memset (&InitStruct, 0, sizeof (InitStruct)) ;
InitStruct.PovVersion = "" ;
InitStruct.GuiVersion = "" ;
InitStruct.GuiInterfaceVersion = GUI_INTERFACE_VERSION ;
InitStruct.hInst = hInstance ;
InitStruct.MainWindow = main_window ;
InitStruct.ExternalRequest = ExternalRequest ;
InitStruct.FirstMenuItem = FirstMenuItem ;
if ((*PointerBlock.Init) (PointerBlock.InstanceID, sizeof (InitStruct), &InitStruct) == 0)
{
if (debugging)
debug_output ("Init () failed (return code == 0) for GUI extension '%s'\n", filename) ;
message_printf ("Init () failed (return code == 0) for GUI extension '%s'\n", name) ;
message_printf (" Contact %s <%s>\n", InitStruct.Author, InitStruct.AuthorEmail) ;
FreeLibrary (hLib) ;
continue ;
}
if (InitStruct.Name == NULL || strlen (InitStruct.Name) < 8 ||
InitStruct.Author == NULL || strlen (InitStruct.Author) < 8 ||
InitStruct.AuthorEmail == NULL || strlen (InitStruct.AuthorEmail) < 8 ||
strncmp (InitStruct.Author, "Place ", 6) == 0 ||
strncmp (InitStruct.AuthorEmail, "Place ", 6) == 0)
{
if (debugging)
debug_output ("GUI extension '%s' has invalid name/author/email\n", filename) ;
message_printf ("GUI extension '%s' has invalid name/author/email. Contact author of add-in.\n", name) ;
FreeLibrary (hLib) ;
continue ;
}
if (InitStruct.DLLInterfaceVersion / 100 != GUI_INTERFACE_VERSION / 100)
{
if (debugging)
debug_output ("GUI extension '%s' ('%s') is wrong version (%d)\n", filename, InitStruct.Name, InitStruct.DLLInterfaceVersion) ;
message_printf ("GUI extension '%s' ('%s') is wrong version (%d)\n", name, InitStruct.Name, InitStruct.DLLInterfaceVersion) ;
message_printf (" Contact %s <%s>\n", InitStruct.Author, InitStruct.AuthorEmail) ;
FreeLibrary (hLib) ;
continue ;
}
if (strcmp (InitStruct.Agreement, "The author of this POV-Ray(tm) GUI Extension DLL certifies that, at the time of "
"its production or distribution, it complied with the POV-Ray Team's then current "
"requirements for GUI Extensions to POV-Ray for Windows, and acknowledges that it "
"is a violation of copyright to fail to do so. This text is copyright (c) the "
"POV-Team 1996. Used by permission.") != 0)
{
if (debugging)
debug_output ("GUI extension '%s' ('%s') has invalid agreement\n '%s'", filename, InitStruct.Name, InitStruct.Agreement) ;
message_printf ("GUI extension '%s' ('%s') has invalid agreement\n", name, InitStruct.Name) ;
message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
FreeLibrary (hLib) ;
continue ;
}
if (InitStruct.hMenu == NULL || !IsMenu (InitStruct.hMenu))
{
if (debugging)
debug_output ("GUI extension '%s' ('%s') has no menu\n", filename, InitStruct.Name) ;
message_printf ("GUI extension '%s' ('%s') has no menu\n", name, InitStruct.Name) ;
message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
FreeLibrary (hLib) ;
continue ;
}
if (!ValidateMenu (InitStruct.hMenu, FirstMenuItem, FirstMenuItem + 59))
{
if (debugging)
debug_output ("GUI extension '%s' ('%s') has invalid menu ID's\n", filename, InitStruct.Name) ;
message_printf ("GUI extension '%s' ('%s') has invalid menu ID's\n", name, InitStruct.Name) ;
message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
FreeLibrary (hLib) ;
continue ;
}
if ((RealPointerBlock = (RealGuiPointerBlock *)calloc (sizeof (RealGuiPointerBlock), 1)) == NULL)
{
message_printf ("Memory allocation error\n") ;
FreeLibrary (hLib) ;
continue ;
}
switch (InitStruct.DLLInterfaceVersion)
{
case 100 :
PointerBlock.AssignPixel = NULL ;
PointerBlock.DisplayPlotBlock = NULL;
break ;
case 101 :
PointerBlock.DisplayPlotBlock = NULL;
break ;
case 102 :
break;
default :
if (debugging)
debug_output ("GUI extension '%s' ('%s') is for a later version of POV (DLLInterfaceVersion is %04x)\n",
filename, InitStruct.Name, InitStruct.DLLInterfaceVersion) ;
message_printf ("GUI extension '%s' ('%s') is for a later version of POV-Ray\n", name, InitStruct.Name) ;
message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
FreeLibrary (hLib) ;
continue ;
}
memcpy (RealPointerBlock, &PointerBlock, sizeof (PointerBlock) - sizeof (PointerBlock.Reserved)) ;
strncpy (RealPointerBlock->Name, InitStruct.Name, sizeof (RealPointerBlock->Name)) ;
strncpy (RealPointerBlock->Author, InitStruct.Author, sizeof (RealPointerBlock->Author)) ;
strncpy (RealPointerBlock->AuthorEmail, InitStruct.AuthorEmail, sizeof (RealPointerBlock->AuthorEmail)) ;
strncpy (RealPointerBlock->FileName, filename, sizeof (RealPointerBlock->FileName)) ;
RealPointerBlock->InstanceData.FirstMenuItem = FirstMenuItem ;
RealPointerBlock->InstanceData.InstanceID = PointerBlock.InstanceID ;
RealPointerBlock->InstanceData.hMenu = InitStruct.hMenu ;
RealPointerBlock->IniID = i ;
if (!loaded)
DeleteMenu (hPluginsMenu, hide_newuser_help ? 1 : 3, MF_BYPOSITION) ;
AppendMenu (hPluginsMenu, MF_POPUP, (UINT_PTR) InitStruct.hMenu, InitStruct.Name) ;
FirstMenuItem += 64 ;
message_printf ("GUI Extension '%s' loaded from '%s'\n", InitStruct.Name, name) ;
message_printf (" Report any problems to %s <%s>\n", InitStruct.Author, InitStruct.AuthorEmail) ;
if (LastPointerBlock != NULL)
{
LastPointerBlock->Next = RealPointerBlock ;
LastPointerBlock = RealPointerBlock ;
}
else
LastPointerBlock = GuiPointerBlocks = RealPointerBlock ;
loaded = true ;
}
}
if (!first)
buffer_message (mDivider, "\n") ;
if (debugging && loaded)
{
RealPointerBlock = GuiPointerBlocks ;
debug_output ("\nGUI extension summary:\n") ;
while (RealPointerBlock)
{
debug_output ("\nExtension DLL '%s'\n\n", RealPointerBlock->FileName) ;
debug_output (" Name : '%s'\n", RealPointerBlock->Name) ;
debug_output (" Author : '%s'\n", RealPointerBlock->Author) ;
debug_output (" AuthorEmail : '%s'\n", RealPointerBlock->AuthorEmail) ;
debug_output (" IniID : %d\n", RealPointerBlock->IniID) ;
debug_output (" Init : %p\n", RealPointerBlock->Init) ;
debug_output (" Destroy : %p\n", RealPointerBlock->Destroy) ;
debug_output (" MenuSelect : %p\n", RealPointerBlock->MenuSelect) ;
debug_output (" Event : %p\n", RealPointerBlock->Event) ;
debug_output (" DisplayPlot : %p\n", RealPointerBlock->DisplayPlot) ;
debug_output (" DisplayPlotRect : %p\n", RealPointerBlock->DisplayPlotRect) ;
debug_output (" WinPrePixel : %p\n", RealPointerBlock->WinPrePixel) ;
debug_output (" WinPostPixel : %p\n", RealPointerBlock->WinPostPixel) ;
debug_output (" WinSystem : %p\n", RealPointerBlock->WinSystem) ;
debug_output (" CleanupAll : %p\n", RealPointerBlock->CleanupAll) ;
debug_output (" BufferMessage : %p\n", RealPointerBlock->BufferMessage) ;
debug_output (" ParseToolCommand : %p\n", RealPointerBlock->ParseToolCommand) ;
debug_output (" DragFunction : %p\n", RealPointerBlock->DragFunction) ;
debug_output (" FirstMenuItem : %p\n", RealPointerBlock->InstanceData.FirstMenuItem) ;
#ifdef _WIN64
debug_output (" InstanceID : %016lX\n", RealPointerBlock->InstanceData.InstanceID) ;
#else
debug_output (" InstanceID : %08X\n", RealPointerBlock->InstanceData.InstanceID) ;
#endif
debug_output (" hMenu : %p\n", RealPointerBlock->InstanceData.hMenu) ;
debug_output (" AssignPixel : %p\n", RealPointerBlock->AssignPixel) ;
RealPointerBlock = RealPointerBlock->Next ;
}
debug_output ("\n") ;
}
}
BOOL CheckGUIExtLoaded (const char *Name)
{
RealGuiPointerBlock *pb = GuiPointerBlocks ;
while (pb)
{
if (_stricmp (pb->Name, Name) == 0)
return (true) ;
pb = pb->Next ;
}
return (false) ;
}
}