1 /*******************************************************************************
2 * pvguiext.cpp
3 *
4 * This file contains POV-Ray for Windows GUI Extension support code.
5 *
6 * Author: Christopher J. Cason.
7 *
8 * ---------------------------------------------------------------------------
9 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
10 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
11 *
12 * POV-Ray is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Affero General Public License as
14 * published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * POV-Ray is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * ---------------------------------------------------------------------------
25 * POV-Ray is based on the popular DKB raytracer version 2.12.
26 * DKBTrace was originally written by David K. Buck.
27 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
28 * ---------------------------------------------------------------------------
29 * $File: //depot/public/povray/3.x/windows/pvguiext.cpp $
30 * $Revision: #1 $
31 * $Change: 6069 $
32 * $DateTime: 2013/11/06 11:59:40 $
33 * $Author: chrisc $
34 *******************************************************************************/
35
36 #define POVWIN_FILE
37 #define _WIN32_IE COMMONCTRL_VERSION
38
39 #include <setjmp.h>
40 #include <string.h>
41
42 #include <windows.h>
43 #include <commctrl.h>
44
45 #include "pvengine.h"
46 #include "pvedit.h"
47 #include "resource.h"
48 #include "pvdialog.h"
49 #include "pvguiext.h"
50
51 // this must be the last file included
52 #include "syspovdebug.h"
53
54 namespace povwin
55 {
56
57 typedef struct _RGPB0X0100
58 {
59 DWORD Signature ;
60 DWORD InstanceID ;
61 BOOL (WINAPI *Init) (DWORD InstanceID, int RecSize, GuiExtInitStruct *InitStruct) ;
62 void (WINAPI *Destroy) (IDataStruct *InstanceData) ;
63 DWORD (WINAPI *MenuSelect) (IDataStruct *InstanceData, WPARAM Code) ;
64 LPSTR (WINAPI *MenuTip) (IDataStruct *InstanceData, WPARAM Code) ;
65 DWORD (WINAPI *Event) (IDataStruct *InstanceData, ExternalEvents Event, DWORD EventVal) ;
66 void (WINAPI *DisplayPlot) (IDataStruct *InstanceData, int x, int y, int Red, int Green, int Blue, int Alpha) ;
67 void (WINAPI *DisplayPlotRect) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha) ;
68 void (WINAPI *WinPrePixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
69 void (WINAPI *WinPostPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
70 BOOL (WINAPI *WinSystem) (IDataStruct *InstanceData, LPSTR command, int *returnval) ;
71 void (WINAPI *CleanupAll) (IDataStruct *InstanceData) ;
72 void (WINAPI *BufferMessage) (IDataStruct *InstanceData, msgtype message_type, LPSTR message) ;
73 LPSTR (WINAPI *ParseToolCommand) (IDataStruct *InstanceData, char command [512]) ;
74 BOOL (WINAPI *DragFunction) (IDataStruct *InstanceData, LPSTR szFile, ExternalDropType DropType) ;
75 struct _RGPB0X0100 *Next ;
76 int IniID ;
77 IDataStruct InstanceData ;
78 char Name [256] ;
79 char Author [256] ;
80 char AuthorEmail [256] ;
81 char FileName [_MAX_PATH] ;
82 } RealGuiPointerBlock_Version_100 ;
83
84 typedef struct _RGPB0X0101
85 {
86 DWORD Signature ;
87 DWORD InstanceID ;
88 BOOL (WINAPI *Init) (DWORD InstanceID, int RecSize, GuiExtInitStruct *InitStruct) ;
89 void (WINAPI *Destroy) (IDataStruct *InstanceData) ;
90 DWORD (WINAPI *MenuSelect) (IDataStruct *InstanceData, WPARAM Code) ;
91 LPSTR (WINAPI *MenuTip) (IDataStruct *InstanceData, WPARAM Code) ;
92 DWORD (WINAPI *Event) (IDataStruct *InstanceData, ExternalEvents Event, DWORD EventVal) ;
93 void (WINAPI *DisplayPlot) (IDataStruct *InstanceData, int x, int y, int Red, int Green, int Blue, int Alpha) ;
94 void (WINAPI *DisplayPlotRect) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha) ;
95 void (WINAPI *WinPrePixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
96 void (WINAPI *WinPostPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
97 BOOL (WINAPI *WinSystem) (IDataStruct *InstanceData, LPSTR command, int *returnval) ;
98 void (WINAPI *CleanupAll) (IDataStruct *InstanceData) ;
99 void (WINAPI *BufferMessage) (IDataStruct *InstanceData, msgtype message_type, LPSTR message) ;
100 LPSTR (WINAPI *ParseToolCommand) (IDataStruct *InstanceData, char command [512]) ;
101 BOOL (WINAPI *DragFunction) (IDataStruct *InstanceData, LPSTR szFile, ExternalDropType DropType) ;
102 void (WINAPI *AssignPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
103 struct _RGPB0X0101 *Next ;
104 int IniID ;
105 IDataStruct InstanceData ;
106 char Name [256] ;
107 char Author [256] ;
108 char AuthorEmail [256] ;
109 char FileName [_MAX_PATH] ;
110 } RealGuiPointerBlock_Version_101 ;
111
112 typedef struct _RGPB
113 {
114 DWORD Signature ;
115 DWORD InstanceID ;
116 BOOL (WINAPI *Init) (DWORD InstanceID, int RecSize, GuiExtInitStruct *InitStruct) ;
117 void (WINAPI *Destroy) (IDataStruct *InstanceData) ;
118 DWORD (WINAPI *MenuSelect) (IDataStruct *InstanceData, WPARAM Code) ;
119 LPSTR (WINAPI *MenuTip) (IDataStruct *InstanceData, WPARAM Code) ;
120 DWORD (WINAPI *Event) (IDataStruct *InstanceData, ExternalEvents Event, DWORD EventVal) ;
121 void (WINAPI *DisplayPlot) (IDataStruct *InstanceData, int x, int y, int Red, int Green, int Blue, int Alpha) ;
122 void (WINAPI *DisplayPlotRect) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha) ;
123 void (WINAPI *WinPrePixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
124 void (WINAPI *WinPostPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
125 BOOL (WINAPI *WinSystem) (IDataStruct *InstanceData, LPSTR command, int *returnval) ;
126 void (WINAPI *CleanupAll) (IDataStruct *InstanceData) ;
127 void (WINAPI *BufferMessage) (IDataStruct *InstanceData, msgtype message_type, LPSTR message) ;
128 LPSTR (WINAPI *ParseToolCommand) (IDataStruct *InstanceData, char command [512]) ;
129 BOOL (WINAPI *DragFunction) (IDataStruct *InstanceData, LPSTR szFile, ExternalDropType DropType) ;
130 void (WINAPI *AssignPixel) (IDataStruct *InstanceData, int x, int y, COLOUR colour) ;
131 void (WINAPI *DisplayPlotBlock) (IDataStruct *InstanceData, int x1, int y1, int x2, int y2, const GuiRGBA8* colour) ;
132 struct _RGPB *Next ;
133 int IniID ;
134 IDataStruct InstanceData ;
135 char Name [256] ;
136 char Author [256] ;
137 char AuthorEmail [256] ;
138 char FileName [_MAX_PATH] ;
139 } RealGuiPointerBlock ;
140
141 DWORD CooperateLevel = 9 ; // this should really be per-GUIEXT rather than global
142 GuiExtInitStruct InitStruct ;
143 RealGuiPointerBlock *GuiPointerBlocks = NULL ;
144
145 DWORD (WINAPI *GuiExtGetPointers) (int RecSize, GuiPointerBlock *PointerBlock) ;
146
147 extern char source_file_name [_MAX_PATH] ;
148 extern bool ExtensionsEnabled ;
149 extern bool rendering ;
150 extern bool stop_rendering ;
151 extern bool hide_newuser_help ;
152 extern bool debugging;
153 extern HWND main_window ;
154 extern HMENU hPluginsMenu ;
155
156 void getvars (ExternalVarStruct *v) ;
157 void setvars (ExternalVarStruct *v) ;
158
ExternalEvent(ExternalEvents Event,DWORD EventVal)159 DWORD ExternalEvent (ExternalEvents Event, DWORD EventVal)
160 {
161 DWORD rval = 0 ;
162 RealGuiPointerBlock *p ;
163
164 if (!ExtensionsEnabled)
165 return (0) ;
166 if (Event == EventWinCooperate)
167 if (EventVal >= CooperateLevel)
168 return (0) ;
169 p = GuiPointerBlocks ;
170 while (p)
171 {
172 if (p->Event != NULL)
173 rval |= (*p->Event ) (&p->InstanceData, Event, EventVal) ;
174 p = p->Next ;
175 }
176 return (rval) ;
177 }
178
ExternalDisplayPlot(int x,int y,int Red,int Green,int Blue,int Alpha)179 void ExternalDisplayPlot (int x, int y, int Red, int Green, int Blue, int Alpha)
180 {
181 RealGuiPointerBlock *p ;
182
183 if (!ExtensionsEnabled)
184 return ;
185 p = GuiPointerBlocks ;
186 while (p)
187 {
188 if (p->DisplayPlot != NULL)
189 (*p->DisplayPlot) (&p->InstanceData, x, y, Red, Green, Blue, Alpha) ;
190 p = p->Next ;
191 }
192 }
193
ExternalDisplayPlotBlock(int x1,int y1,int x2,int y2,const GuiRGBA8 * colour)194 void ExternalDisplayPlotBlock (int x1, int y1, int x2, int y2, const GuiRGBA8* colour)
195 {
196 RealGuiPointerBlock *p ;
197
198 if (!ExtensionsEnabled)
199 return ;
200
201 int pixelsCount = ( x2 - x1 + 1 ) * ( y2 - y1 + 1 );
202 GuiRGBA8* localColourCopy = NULL;
203
204 p = GuiPointerBlocks ;
205 while (p)
206 {
207 if (p->DisplayPlotBlock != NULL)
208 {
209 if (localColourCopy == NULL)
210 localColourCopy = new GuiRGBA8[ pixelsCount ];
211 memcpy( localColourCopy, colour, pixelsCount * sizeof( GuiRGBA8 ) );
212 (*p->DisplayPlotBlock) (&p->InstanceData, x1, y1, x2, y2, localColourCopy ) ;
213 }
214 p = p->Next ;
215 }
216 delete[] localColourCopy;
217 }
218
ExternalDisplayPlotRect(int x1,int y1,int x2,int y2,int Red,int Green,int Blue,int Alpha)219 void ExternalDisplayPlotRect (int x1, int y1, int x2, int y2, int Red, int Green, int Blue, int Alpha)
220 {
221 RealGuiPointerBlock *p ;
222
223 if (!ExtensionsEnabled)
224 return ;
225 p = GuiPointerBlocks ;
226 while (p)
227 {
228 if (p->DisplayPlotRect != NULL)
229 (*p->DisplayPlotRect) (&p->InstanceData, x1, y1, x2, y2, Red, Green, Blue, Alpha) ;
230 p = p->Next ;
231 }
232 }
233
ExternalWinPrePixel(int x,int y,COLOUR colour)234 void ExternalWinPrePixel (int x, int y, COLOUR colour)
235 {
236 RealGuiPointerBlock *p ;
237
238 if (!ExtensionsEnabled)
239 return ;
240 p = GuiPointerBlocks ;
241 while (p)
242 {
243 if (p->WinPrePixel != NULL)
244 (*p->WinPrePixel) (&p->InstanceData, x, y, colour) ;
245 p = p->Next ;
246 }
247 }
248
ExternalWinPostPixel(int x,int y,COLOUR colour)249 void ExternalWinPostPixel (int x, int y, COLOUR colour)
250 {
251 RealGuiPointerBlock *p ;
252
253 if (!ExtensionsEnabled)
254 return ;
255 p = GuiPointerBlocks ;
256 while (p)
257 {
258 if (p->WinPostPixel != NULL)
259 (*p->WinPostPixel) (&p->InstanceData, x, y, colour) ;
260 p = p->Next ;
261 }
262 }
263
ExternalAssignPixel(int x,int y,COLOUR colour)264 void ExternalAssignPixel (int x, int y, COLOUR colour)
265 {
266 RealGuiPointerBlock *p ;
267
268 if (!ExtensionsEnabled)
269 return ;
270 p = GuiPointerBlocks ;
271 while (p)
272 {
273 if (p->AssignPixel != NULL)
274 (*p->AssignPixel) (&p->InstanceData, x, y, colour) ;
275 p = p->Next ;
276 }
277 }
278
ExternalWinSystem(LPSTR command,int * returnval)279 BOOL ExternalWinSystem (LPSTR command, int *returnval)
280 {
281 RealGuiPointerBlock *p ;
282
283 if (!ExtensionsEnabled)
284 return (false) ;
285 p = GuiPointerBlocks ;
286 while (p)
287 {
288 if (p->WinSystem != NULL)
289 if ((*p->WinSystem) (&p->InstanceData, command, returnval))
290 return (true) ;
291 p = p->Next ;
292 }
293 return (false) ;
294 }
295
ExternalCleanupAll(void)296 void ExternalCleanupAll (void)
297 {
298 // always enabled
299 while (GuiPointerBlocks)
300 {
301 if (GuiPointerBlocks->Destroy != NULL)
302 (*GuiPointerBlocks->Destroy) (&GuiPointerBlocks->InstanceData) ;
303 GuiPointerBlocks = GuiPointerBlocks->Next ;
304 }
305 }
306
ExternalBufferMessage(msgtype message_type,LPSTR message)307 void ExternalBufferMessage (msgtype message_type, LPSTR message)
308 {
309 RealGuiPointerBlock *p ;
310
311 if (!ExtensionsEnabled)
312 return ;
313 p = GuiPointerBlocks ;
314 while (p)
315 {
316 if (p->BufferMessage != NULL)
317 (*p->BufferMessage) (&p->InstanceData, message_type, message) ;
318 p = p->Next ;
319 }
320 }
321
ExternalParseToolCommand(char command[512])322 void ExternalParseToolCommand (char command [512])
323 {
324 RealGuiPointerBlock *p ;
325
326 if (!ExtensionsEnabled)
327 return ;
328 p = GuiPointerBlocks ;
329 while (p)
330 {
331 if (p->ParseToolCommand != NULL)
332 (*p->ParseToolCommand) (&p->InstanceData, command) ;
333 p = p->Next ;
334 }
335 }
336
ExternalDragFunction(LPSTR szFile,ExternalDropType DropType)337 BOOL ExternalDragFunction (LPSTR szFile, ExternalDropType DropType)
338 {
339 int n ;
340 RealGuiPointerBlock *p ;
341
342 if (!ExtensionsEnabled)
343 return (false) ;
344 n = get_file_type (szFile) ;
345 if (n == filePOV || n == fileINI)
346 return (false) ;
347 p = GuiPointerBlocks ;
348 while (p)
349 {
350 if (p->DragFunction != NULL)
351 if ((*p->DragFunction) (&p->InstanceData, szFile, DropType))
352 return (true) ;
353 p = p->Next ;
354 }
355 return (false) ;
356 }
357
ExternalRequest(ExternalRequests Request,void * RequestBlock)358 ExternalRequestResult WINAPI ExternalRequest (ExternalRequests Request, void *RequestBlock)
359 {
360 if (!ExtensionsEnabled)
361 return (ExRequestDisabled) ;
362 switch (Request)
363 {
364 case RequestGetVars :
365 if (((ExternalVarStruct *) RequestBlock)->RecSize != sizeof (ExternalVarStruct))
366 return (ExRequestBadRecSize) ;
367 getvars ((ExternalVarStruct *) RequestBlock) ;
368 return (ExRequestOK) ;
369
370 case RequestSetVars :
371 if (((ExternalVarStruct *) RequestBlock)->RecSize != sizeof (ExternalVarStruct))
372 return (ExRequestBadRecSize) ;
373 setvars ((ExternalVarStruct *) RequestBlock) ;
374 return (ExRequestOK) ;
375
376 case RequestSetCooperateLevel :
377 CooperateLevel = *(DWORD *) RequestBlock ;
378 return (ExRequestOK) ;
379
380 case RequestStartRendering :
381 if (rendering)
382 return (ExRequestFailedRendering) ;
383 message_printf ("Rendering started by GUI extension\n") ;
384 start_rendering (false) ;
385 return (ExRequestOK) ;
386
387 case RequestStopRendering :
388 if (!rendering)
389 return (ExRequestFailedNotRendering) ;
390 stop_rendering = true ;
391 message_printf ("Rendering stopped by GUI extension\n") ;
392 SendMessage (main_window, WM_COMMAND, CM_STOPRENDER, 0) ;
393 return (ExRequestOK) ;
394
395 case RequestExit :
396 if (rendering)
397 return (ExRequestFailedRendering) ;
398 message_printf ("Exit requested by GUI extension\n") ;
399 Sleep (1000) ;
400 SendMessage (main_window, WM_CLOSE, 0, 0) ;
401 return (ExRequestOK) ;
402 }
403 return (ExRequestUnknown) ;
404 }
405
ExternalMenuSelect(WPARAM Code)406 DWORD ExternalMenuSelect (WPARAM Code)
407 {
408 RealGuiPointerBlock *p ;
409
410 if (!ExtensionsEnabled)
411 return (1) ;
412 p = GuiPointerBlocks ;
413 while (p)
414 {
415 if (Code >= p->InstanceData.FirstMenuItem && Code <= p->InstanceData.FirstMenuItem + 59)
416 return ((*p->MenuSelect) (&p->InstanceData, Code - p->InstanceData.FirstMenuItem)) ;
417 p = p->Next ;
418 }
419 return (1) ;
420 }
421
ExternalMenuTip(WPARAM wParam)422 char *ExternalMenuTip (WPARAM wParam)
423 {
424 RealGuiPointerBlock *p ;
425
426 if (!ExtensionsEnabled)
427 return ("Extensions Disabled") ;
428 p = GuiPointerBlocks ;
429 while (p)
430 {
431 if (wParam >= p->InstanceData.FirstMenuItem && wParam <= p->InstanceData.FirstMenuItem + 59)
432 return ((*p->MenuTip) (&p->InstanceData, wParam - p->InstanceData.FirstMenuItem)) ;
433 p = p->Next ;
434 }
435 return ("") ;
436 }
437
ValidateMenu(HMENU hMenu,int first,int last)438 bool ValidateMenu (HMENU hMenu, int first, int last)
439 {
440 int count ;
441 int i ;
442 int id ;
443 HMENU hSubMenu ;
444
445 count = GetMenuItemCount (hMenu) ;
446 for (i = 0 ; i < count ; i++)
447 {
448 if ((id = GetMenuItemID (hMenu, i)) == 0xffffffff)
449 {
450 // could be a popup menu
451 if ((hSubMenu = GetSubMenu (hMenu, i)) == NULL)
452 continue ;
453 if (!ValidateMenu (hSubMenu, first, last))
454 return (false) ;
455 continue ;
456 }
457 if (id == 0 || id == 0xffff)
458 continue ;
459 if (id < first || id > last)
460 return (false) ;
461 }
462 return (true) ;
463 }
464
LoadGUIExtensions(void)465 void LoadGUIExtensions (void)
466 {
467 int i ;
468 int FirstMenuItem = CM_FIRSTGUIEXT ;
469 char str [64] ;
470 char filename [_MAX_PATH] ;
471 char name [_MAX_PATH] ;
472 bool first = true ;
473 bool loaded = false ;
474 HINSTANCE hLib ;
475 GuiPointerBlock PointerBlock ;
476 RealGuiPointerBlock *RealPointerBlock ;
477 RealGuiPointerBlock *LastPointerBlock = NULL ;
478
479 if (!ExtensionsEnabled)
480 return ;
481 for (i = 0 ; i < MAX_GUI_EXT ; i++)
482 {
483 sprintf (str, "ExtDll%02d", i) ;
484 GetHKCU("GuiExtensions", str, "", filename, sizeof (filename));
485 if (filename [0] != '\0')
486 {
487 if (first)
488 {
489 first = false ;
490 buffer_message (mDivider, "\n") ;
491 message_printf ("DISCLAIMER : The POV-Team takes no responsibility for the operation of third-party GUI Extensions.\n") ;
492 message_printf (" Please do not send us bug reports if they cause things to go haywire.\n\n") ;
493 }
494
495 splitpath (filename, NULL, name) ;
496 if ((hLib = LoadLibrary (filename)) == NULL)
497 {
498 if (debugging)
499 debug_output ("Could not load GUI Extension DLL '%s', error code is %08lx\n", filename, GetLastError ()) ;
500 message_printf ("Could not load GUI Extension DLL '%s'\n", name) ;
501 continue ;
502 }
503 GuiExtGetPointers = (unsigned long(WINAPI *)(int, GuiPointerBlock *))GetProcAddress (hLib, "PovGuiExtensionGetPointers") ;
504 if (GuiExtGetPointers == NULL)
505 {
506 if (debugging)
507 debug_output ("Could not get Init process address for GUI extension '%s', error code is %08lx\n", filename, GetLastError ()) ;
508 message_printf ("Could not get Init address for GUI Extension DLL '%s'\n", name) ;
509 message_printf (" Contact author of '%s'\n", name) ;
510 FreeLibrary (hLib) ;
511 continue ;
512 }
513 memset (&PointerBlock, 0, sizeof (PointerBlock)) ;
514 if (GuiExtGetPointers (sizeof (PointerBlock), &PointerBlock) == 0)
515 {
516 if (debugging)
517 debug_output ("Could not get pointers for GUI extension '%s'\n", filename) ;
518 message_printf ("Could not get pointers for GUI extension '%s'\n", name) ;
519 message_printf (" Contact author of '%s'\n", name) ;
520 FreeLibrary (hLib) ;
521 continue ;
522 }
523 if (PointerBlock.Init == NULL ||
524 PointerBlock.MenuSelect == NULL ||
525 PointerBlock.MenuTip == NULL ||
526 (PointerBlock.Signature != 'CJC!' && PointerBlock.Signature != '!CJC'))
527 {
528 if (debugging)
529 debug_output ("PointerBlock not correctly initialized by GUI extension '%s'\n", filename) ;
530 message_printf ("PointerBlock not correctly initialized by GUI extension '%s'\n", name) ;
531 message_printf (" Contact author of '%s'\n", name) ;
532 FreeLibrary (hLib) ;
533 continue ;
534 }
535 memset (&InitStruct, 0, sizeof (InitStruct)) ;
536 InitStruct.PovVersion = "" ;
537 InitStruct.GuiVersion = "" ;
538 InitStruct.GuiInterfaceVersion = GUI_INTERFACE_VERSION ;
539 InitStruct.hInst = hInstance ;
540 InitStruct.MainWindow = main_window ;
541 InitStruct.ExternalRequest = ExternalRequest ;
542 InitStruct.FirstMenuItem = FirstMenuItem ;
543 if ((*PointerBlock.Init) (PointerBlock.InstanceID, sizeof (InitStruct), &InitStruct) == 0)
544 {
545 if (debugging)
546 debug_output ("Init () failed (return code == 0) for GUI extension '%s'\n", filename) ;
547 message_printf ("Init () failed (return code == 0) for GUI extension '%s'\n", name) ;
548 message_printf (" Contact %s <%s>\n", InitStruct.Author, InitStruct.AuthorEmail) ;
549 FreeLibrary (hLib) ;
550 continue ;
551 }
552 if (InitStruct.Name == NULL || strlen (InitStruct.Name) < 8 ||
553 InitStruct.Author == NULL || strlen (InitStruct.Author) < 8 ||
554 InitStruct.AuthorEmail == NULL || strlen (InitStruct.AuthorEmail) < 8 ||
555 strncmp (InitStruct.Author, "Place ", 6) == 0 ||
556 strncmp (InitStruct.AuthorEmail, "Place ", 6) == 0)
557 {
558 if (debugging)
559 debug_output ("GUI extension '%s' has invalid name/author/email\n", filename) ;
560 message_printf ("GUI extension '%s' has invalid name/author/email. Contact author of add-in.\n", name) ;
561 FreeLibrary (hLib) ;
562 continue ;
563 }
564 if (InitStruct.DLLInterfaceVersion / 100 != GUI_INTERFACE_VERSION / 100)
565 {
566 if (debugging)
567 debug_output ("GUI extension '%s' ('%s') is wrong version (%d)\n", filename, InitStruct.Name, InitStruct.DLLInterfaceVersion) ;
568 message_printf ("GUI extension '%s' ('%s') is wrong version (%d)\n", name, InitStruct.Name, InitStruct.DLLInterfaceVersion) ;
569 message_printf (" Contact %s <%s>\n", InitStruct.Author, InitStruct.AuthorEmail) ;
570 FreeLibrary (hLib) ;
571 continue ;
572 }
573 if (strcmp (InitStruct.Agreement, "The author of this POV-Ray(tm) GUI Extension DLL certifies that, at the time of "
574 "its production or distribution, it complied with the POV-Ray Team's then current "
575 "requirements for GUI Extensions to POV-Ray for Windows, and acknowledges that it "
576 "is a violation of copyright to fail to do so. This text is copyright (c) the "
577 "POV-Team 1996. Used by permission.") != 0)
578 {
579 if (debugging)
580 debug_output ("GUI extension '%s' ('%s') has invalid agreement\n '%s'", filename, InitStruct.Name, InitStruct.Agreement) ;
581 message_printf ("GUI extension '%s' ('%s') has invalid agreement\n", name, InitStruct.Name) ;
582 message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
583 FreeLibrary (hLib) ;
584 continue ;
585 }
586 if (InitStruct.hMenu == NULL || !IsMenu (InitStruct.hMenu))
587 {
588 if (debugging)
589 debug_output ("GUI extension '%s' ('%s') has no menu\n", filename, InitStruct.Name) ;
590 message_printf ("GUI extension '%s' ('%s') has no menu\n", name, InitStruct.Name) ;
591 message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
592 FreeLibrary (hLib) ;
593 continue ;
594 }
595 if (!ValidateMenu (InitStruct.hMenu, FirstMenuItem, FirstMenuItem + 59))
596 {
597 if (debugging)
598 debug_output ("GUI extension '%s' ('%s') has invalid menu ID's\n", filename, InitStruct.Name) ;
599 message_printf ("GUI extension '%s' ('%s') has invalid menu ID's\n", name, InitStruct.Name) ;
600 message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
601 FreeLibrary (hLib) ;
602 continue ;
603 }
604 if ((RealPointerBlock = (RealGuiPointerBlock *)calloc (sizeof (RealGuiPointerBlock), 1)) == NULL)
605 {
606 message_printf ("Memory allocation error\n") ;
607 FreeLibrary (hLib) ;
608 continue ;
609 }
610 switch (InitStruct.DLLInterfaceVersion)
611 {
612 case 100 :
613 PointerBlock.AssignPixel = NULL ;
614 PointerBlock.DisplayPlotBlock = NULL;
615 break ;
616
617 case 101 :
618 PointerBlock.DisplayPlotBlock = NULL;
619 break ;
620
621 case 102 :
622 break;
623
624 default :
625 if (debugging)
626 debug_output ("GUI extension '%s' ('%s') is for a later version of POV (DLLInterfaceVersion is %04x)\n",
627 filename, InitStruct.Name, InitStruct.DLLInterfaceVersion) ;
628 message_printf ("GUI extension '%s' ('%s') is for a later version of POV-Ray\n", name, InitStruct.Name) ;
629 message_printf (" Contact %s at %s\n", InitStruct.Author, InitStruct.AuthorEmail) ;
630 FreeLibrary (hLib) ;
631 continue ;
632 }
633 memcpy (RealPointerBlock, &PointerBlock, sizeof (PointerBlock) - sizeof (PointerBlock.Reserved)) ;
634 strncpy (RealPointerBlock->Name, InitStruct.Name, sizeof (RealPointerBlock->Name)) ;
635 strncpy (RealPointerBlock->Author, InitStruct.Author, sizeof (RealPointerBlock->Author)) ;
636 strncpy (RealPointerBlock->AuthorEmail, InitStruct.AuthorEmail, sizeof (RealPointerBlock->AuthorEmail)) ;
637 strncpy (RealPointerBlock->FileName, filename, sizeof (RealPointerBlock->FileName)) ;
638 RealPointerBlock->InstanceData.FirstMenuItem = FirstMenuItem ;
639 RealPointerBlock->InstanceData.InstanceID = PointerBlock.InstanceID ;
640 RealPointerBlock->InstanceData.hMenu = InitStruct.hMenu ;
641 RealPointerBlock->IniID = i ;
642 if (!loaded)
643 DeleteMenu (hPluginsMenu, hide_newuser_help ? 1 : 3, MF_BYPOSITION) ;
644 AppendMenu (hPluginsMenu, MF_POPUP, (UINT_PTR) InitStruct.hMenu, InitStruct.Name) ;
645 FirstMenuItem += 64 ;
646 message_printf ("GUI Extension '%s' loaded from '%s'\n", InitStruct.Name, name) ;
647 message_printf (" Report any problems to %s <%s>\n", InitStruct.Author, InitStruct.AuthorEmail) ;
648 if (LastPointerBlock != NULL)
649 {
650 LastPointerBlock->Next = RealPointerBlock ;
651 LastPointerBlock = RealPointerBlock ;
652 }
653 else
654 LastPointerBlock = GuiPointerBlocks = RealPointerBlock ;
655 loaded = true ;
656 }
657 }
658 if (!first)
659 buffer_message (mDivider, "\n") ;
660 if (debugging && loaded)
661 {
662 RealPointerBlock = GuiPointerBlocks ;
663 debug_output ("\nGUI extension summary:\n") ;
664 while (RealPointerBlock)
665 {
666 debug_output ("\nExtension DLL '%s'\n\n", RealPointerBlock->FileName) ;
667 debug_output (" Name : '%s'\n", RealPointerBlock->Name) ;
668 debug_output (" Author : '%s'\n", RealPointerBlock->Author) ;
669 debug_output (" AuthorEmail : '%s'\n", RealPointerBlock->AuthorEmail) ;
670 debug_output (" IniID : %d\n", RealPointerBlock->IniID) ;
671 debug_output (" Init : %p\n", RealPointerBlock->Init) ;
672 debug_output (" Destroy : %p\n", RealPointerBlock->Destroy) ;
673 debug_output (" MenuSelect : %p\n", RealPointerBlock->MenuSelect) ;
674 debug_output (" Event : %p\n", RealPointerBlock->Event) ;
675 debug_output (" DisplayPlot : %p\n", RealPointerBlock->DisplayPlot) ;
676 debug_output (" DisplayPlotRect : %p\n", RealPointerBlock->DisplayPlotRect) ;
677 debug_output (" WinPrePixel : %p\n", RealPointerBlock->WinPrePixel) ;
678 debug_output (" WinPostPixel : %p\n", RealPointerBlock->WinPostPixel) ;
679 debug_output (" WinSystem : %p\n", RealPointerBlock->WinSystem) ;
680 debug_output (" CleanupAll : %p\n", RealPointerBlock->CleanupAll) ;
681 debug_output (" BufferMessage : %p\n", RealPointerBlock->BufferMessage) ;
682 debug_output (" ParseToolCommand : %p\n", RealPointerBlock->ParseToolCommand) ;
683 debug_output (" DragFunction : %p\n", RealPointerBlock->DragFunction) ;
684 debug_output (" FirstMenuItem : %p\n", RealPointerBlock->InstanceData.FirstMenuItem) ;
685 #ifdef _WIN64
686 debug_output (" InstanceID : %016lX\n", RealPointerBlock->InstanceData.InstanceID) ;
687 #else
688 debug_output (" InstanceID : %08X\n", RealPointerBlock->InstanceData.InstanceID) ;
689 #endif
690 debug_output (" hMenu : %p\n", RealPointerBlock->InstanceData.hMenu) ;
691 debug_output (" AssignPixel : %p\n", RealPointerBlock->AssignPixel) ;
692 RealPointerBlock = RealPointerBlock->Next ;
693 }
694 debug_output ("\n") ;
695 }
696 }
697
CheckGUIExtLoaded(const char * Name)698 BOOL CheckGUIExtLoaded (const char *Name)
699 {
700 RealGuiPointerBlock *pb = GuiPointerBlocks ;
701 while (pb)
702 {
703 if (_stricmp (pb->Name, Name) == 0)
704 return (true) ;
705 pb = pb->Next ;
706 }
707 return (false) ;
708 }
709
710 }
711