00001 // $Id: oilmods.cpp 1464 2006-07-18 12:32:26Z gerry $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 /* 00100 */ 00101 00102 // This handles the machine-specific areas regarding modules & tools and how they link 00103 // in to the kernel. The Kernel itself maintains a list of modules & tools, but we are 00104 // responsible for physically finding modules (in .DLLs) and declaring their presence 00105 // to everyone else. 00106 00107 // See winoil\killdlls.cpp for the _ADXDLL build vsn of Deinit() method of OILModule. 00108 00109 #include "camtypes.h" 00110 00111 #include "module.h" 00112 #include "oilmods.h" 00113 //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 #include "modlist.h" 00115 //#include "dll_lib.h" 00116 //#include "andy.h" 00117 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 #include "viewmod.h" 00119 //#include "zoomres.h" 00120 00121 DECLARE_SOURCE("$Revision: 1464 $"); 00122 00123 // Declare smart memory handling in Debug builds 00124 #define new CAM_DEBUG_NEW 00125 00126 // This list is always needed as RSN DLLs will hold resources even if the tool code 00127 // itself is in the .EXE 00128 00129 HINSTANCE DLLs[MAX_DLLS]; 00130 UINT32 DLLCount = 0; 00131 00132 // This list is for other DLLs that MUST be closed upon termination 00133 HINSTANCE ExtraDLLs[Extra_DLL_Count]; 00134 00135 #define TOOL_DLL_NAME "TOOLS.DLL" 00136 00137 00138 /******************************************************************************************** 00139 00140 > OILModule::Init() 00141 00142 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00143 Created: 21/6/93 00144 Inputs: None 00145 Outputs: None 00146 Returns: None 00147 Purpose: Called to supply all modules to the Kernel. For each module that is found, 00148 calls Modules::DeclareModule(). Note that at this point only the constructors 00149 on each module are called; their Init functions are not. This allows one 00150 module to detect the presence of another module and fail its Init call. 00151 Errors: None 00152 00153 ********************************************************************************************/ 00154 00155 // RALPH 00156 #ifdef RALPH 00157 #define NOMODULE 00158 #else 00159 #ifndef _AFXDLL 00160 #define NOMODULE 00161 #endif 00162 #endif 00163 00164 //#ifndef _AFXDLL 00165 00166 #ifdef NOMODULE 00167 /******************************************************************************************** 00168 00169 Kludged built in to .exe file Tool code: 00170 00171 ********************************************************************************************/ 00172 00173 BOOL OILModule::Init() 00174 { 00175 // The Viewer, and Mac version always read from the exe 00176 #ifdef STANDALONE 00177 // #define _READFROMEXE 00178 #endif 00179 00180 #ifndef _READFROMEXE 00181 #ifdef _MAC 00182 #define _READFROMEXE 00183 #endif 00184 #endif 00185 00186 HINSTANCE hLibrary = (HINSTANCE)HINSTANCE_ERROR; 00187 00188 PORTNOTE("other", "Removed SetErrorMode usage" ) 00189 #ifndef EXCLUDE_FROM_XARALX 00190 SetErrorMode( SEM_NOOPENFILEERRORBOX ); // don't cause errors 00191 #endif 00192 00193 // Still need the DLLs for the module/tool resources. 00194 00195 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00196 // Have a look to see if the tools resources are in the normal ones... 00197 HINSTANCE hResInst = AfxGetResourceHandle(); 00198 TCHAR Buf[200]; 00199 INT32 LoadStringResult = ::LoadString( hResInst, _R(IDS_ZOOMOP_STATUSHELP), Buf, 200); 00200 if(LoadStringResult) 00201 { 00202 // if(ExtraDLLs[Resources_DLL] != 0) 00203 // We don't want to load the tools.dll if we're using an external resource 00204 // dll anyway, since it should already have these resources in it... 00205 hLibrary = (HINSTANCE)HINSTANCE_ERROR; //AfxGetInstanceHandle(); 00206 } 00207 else 00208 { 00209 #ifndef _READFROMEXE 00210 LPTCHAR LibName = wxT(TOOL_DLL_NAME); 00211 hLibrary = LoadLibrary( LibName ); 00212 00213 // for now the tools DLL is compulsory 00214 if (hLibrary < (HINSTANCE)HINSTANCE_ERROR) 00215 { 00216 /* TCHAR loaded[256], buf[256]; 00217 00218 if (::LoadString( AfxGetResourceHandle(), _R(IDW_NOTOOLS), loaded, sizeof(loaded) ) ) 00219 { 00220 wsprintf(buf, loaded, LibName ); // assumes %s in message 00221 Error::SetError(0, buf, 0); // leave InformError for caller 00222 } 00223 return FALSE; 00224 */ 00225 // Rewrite the above to use MakeMsg, so the context-senstive help will work. 00226 String_256 buf; 00227 buf.MakeMsg(_R(IDW_NOTOOLS), (LPCTSTR) LibName); 00228 Error::SetError(0, buf, 0); // leave InformError to caller 00229 return FALSE; 00230 } 00231 #else 00232 // Mac version cannot open DLLs 00233 hLibrary = AfxGetInstanceHandle(); // read resource from us 00234 #endif 00235 } 00236 //#else 00237 // hLibrary = AfxGetInstanceHandle(); // read resource from us 00238 #endif 00239 00240 // Bodge the DLL table 00241 DLLs[0] = hLibrary; 00242 DLLCount++; 00243 00244 Module *NewModule = (Module *) new ViewModule; 00245 if (NewModule == NULL) 00246 goto AbnormalExit; 00247 00248 // Construct an OILModule and make it point to this DLL for the module's resources. 00249 OILModule *pOILModule; 00250 pOILModule = new OILModule; 00251 if (pOILModule == NULL) 00252 { 00253 delete NewModule; 00254 goto AbnormalExit; 00255 } 00256 pOILModule->hInstance = hLibrary; 00257 00258 // Declare this module. 00259 Module::Declare(NewModule, pOILModule); 00260 00261 // Here you add your own built-in tools for in .exe testing - when in a DLL, 00262 // you can't do this. 00263 00264 return TRUE; 00265 00266 AbnormalExit: 00267 // Out of memory - clean up and fail 00268 TRACEUSER( "Tim", _T("OILModule::Init(): memory exhausted") ); 00269 PORTNOTE("other", "Removed FreeLibrary usage" ) 00270 #ifndef EXCLUDE_FROM_XARALX 00271 // FreeLibrary(hLibrary); 00272 #endif 00273 DLLs[0] = (HINSTANCE)HINSTANCE_ERROR; 00274 DLLCount--; 00275 return FALSE; 00276 } 00277 00278 #else 00279 00280 00281 00282 /******************************************************************************************** 00283 00284 Proper DLL-reading code: 00285 00286 ********************************************************************************************/ 00287 00288 00289 /******************************************************************************************** 00290 00291 void OILModule::EnumerateToolsFromDLL(const char *Filename) 00292 00293 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00294 Created: 30/6/93 00295 Inputs: Filename - filename of DLL to load and interrogate. 00296 Outputs: - 00297 Returns: - 00298 Purpose: Loads a Windows DLL, finds out how many modules it contains, and tries 00299 to create (and declare) each one in turn. 00300 It detects debug vs non-debug build clashes and ignores modules that are 00301 not from the same build. 00302 Errors: - 00303 SeeAlso: - 00304 00305 ********************************************************************************************/ 00306 00307 typedef Module *(MODULE_FN *CreateProcType)(UINT32); 00308 typedef UINT32 ((MODULE_FN * CountProcType)()); // ptr to CountModules fn 00309 typedef void *((MODULE_FN *DebugProcType)()); // ptr to Debug marker fn 00310 00311 void OILModule::EnumerateModulesFromDLL(const char *Filename) 00312 { 00313 CreateProcType CreateProc; // ptr to CreateModule fn 00314 CountProcType CountProc; // ptr to CountModules fn 00315 DebugProcType DebugProc; // ptr to Debug marker fn 00316 00317 ModuleListItem *NewItem = NULL; // ptr to new Module list item 00318 HINSTANCE hLibrary; // handle of DLL 00319 00320 00321 if (DLLCount == MAX_DLLS) // stop when limit reached 00322 { 00323 TRACE( _T("Too many DLLs\n")); 00324 return; 00325 } 00326 00327 hLibrary = LoadLibrary(Filename); // load .DLL 00328 00329 00330 if (hLibrary <= (HINSTANCE)HINSTANCE_ERROR) 00331 { 00332 ERROR3_PF( ("Tools DLL %s failed to load - may be problems starting up", Filename) ); 00333 return; // ignore if not found 00334 } 00335 00336 // Read the function pointers from the DLL. (Lots of lovely casts required). 00337 00338 #if WIN32 00339 CountProc = (CountProcType) GetProcAddress(hLibrary, "GetNumberOfModules"); 00340 CreateProc= (CreateProcType) GetProcAddress(hLibrary, "CreateModule"); 00341 #else 00342 CountProc = (CountProcType) GetProcAddress(hLibrary, "_GetNumberOfModules"); 00343 CreateProc= (CreateProcType) GetProcAddress(hLibrary, "_CreateModule"); 00344 #endif 00345 DebugProc = (DebugProcType) GetProcAddress(hLibrary, "IAmADebugTool"); 00346 00347 // Construct an OILModule and make it point to this DLL for the module's resources. 00348 OILModule *pOILModule = new OILModule; 00349 if (pOILModule == NULL) 00350 // Out of memory 00351 TRACE( _T("OILModule::EnumerateModulesFromDLL(): memory exhausted")); 00352 else 00353 pOILModule->hInstance = hLibrary; 00354 00355 if (pOILModule) 00356 { 00357 if (CreateProc && CountProc) 00358 { 00359 // ensure that debug status of DLL matches the .exe file 00360 #ifdef _DEBUG 00361 if (DebugProc) 00362 #else 00363 if (!DebugProc) 00364 #endif 00365 { 00366 // Fill in the instance handle so the Tool (or, more accurately, the 00367 // OILTool) can use it when initialising. 00368 DLLs[DLLCount++] = hLibrary; 00369 00370 // Ask about Modules in this DLL 00371 00372 UINT32 i; 00373 const UINT32 ModuleCount = CountProc(); // ask DLL how many 00374 00375 for (i = 1; i <= ModuleCount; i++) // tool numbers start at 1 00376 { 00377 Module *NewModule = CreateProc(i); // ask about each Tool 00378 00379 if (NewModule) 00380 NewItem = Module::Declare(NewModule, 00381 pOILModule); // tell Kernel about it 00382 } 00383 } 00384 } 00385 else if (camStrcmp( Filename, TOOL_DLL_NAME )==0 ) 00386 { 00387 // loaded resources from the DLL, now declare the built-in Tools 00388 Module *NewModule = (Module*) new ViewModule; 00389 00390 if (NewModule) 00391 NewItem = Module::Declare(NewModule, pOILModule ); 00392 } 00393 } 00394 00395 // Did the DLL provide any modules? (or did we run out of memory?) 00396 if (NewItem == NULL) 00397 { 00398 // No - so forget about this DLL 00399 DLLs[DLLCount] = (HINSTANCE)HINSTANCE_ERROR; 00400 DLLCount--; 00401 FreeLibrary(hLibrary); 00402 ERROR3_PF( ("Tools DLL %s failed to init - may be problems starting up", Filename) ); 00403 } 00404 else 00405 { 00406 TRACEUSER( "Andy", _T("%08lx=%s\n"), hLibrary, Filename ); 00407 } 00408 } 00409 00410 /******************************************************************************************** 00411 00412 > BOOL OILModule::Init() 00413 00414 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00415 Created: 21/6/93 00416 Inputs: None 00417 Outputs: None 00418 Returns: TRUE if OK, FALSE if serious fatal error. 00419 Purpose: Under Windows, reads all Module DLLs and declares the modules found therein 00420 to the Kernel. 00421 Errors: None. 00422 SeeAlso: Tool::InitTools 00423 Scope: Private 00424 00425 ********************************************************************************************/ 00426 00427 00428 BOOL OILModule::Init() 00429 { 00430 // At some point we will have a smart routine for finding all .DLLs. For now, 00431 // we keep life a little simpler... 00432 00433 SetErrorMode( SEM_NOOPENFILEERRORBOX ); // don't cause errors 00434 00435 00436 // read built-in tools and their resources 00437 EnumerateModulesFromDLL( TOOL_DLL_NAME ); 00438 00439 // read from the external DLL(s) 00440 EnumerateModulesFromDLL( "Push.dll" ); 00441 EnumerateModulesFromDLL( "ZoomTool.dll" ); 00442 EnumerateModulesFromDLL( "FreeHand.dll" ); 00443 EnumerateModulesFromDLL( "BlndTool.dll" ); 00444 00445 00446 return TRUE; // always OK 00447 } 00448 00449 00450 00451 #endif 00452 00453 00454 00455 /******************************************************************************************** 00456 00457 > HINSTANCE OILModule::GetInstance(UINT32 ModuleID) 00458 00459 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00460 Created: 1/7/93 00461 Inputs: ModuleID - ID of the module to get the instance for. 00462 Outputs: - 00463 Returns: The HINSTANCE value for the required module, or HINSTANCE_ERROR if the ID 00464 was not found. 00465 Purpose: Given a module ID, return the Windows HINSTANCE handle for the Windows 00466 'module' containing this Camelot module. 00467 Errors: - 00468 00469 ********************************************************************************************/ 00470 00471 HINSTANCE OILModule::GetInstance(UINT32 ModuleID) 00472 { 00473 // Find the module in question 00474 ModuleListItem *Item = Module::Find(ModuleID); 00475 00476 // Extract the instance if the module was found 00477 if (Item == NULL) 00478 { 00479 TRACE( _T("OILModule::GetInstance() : ModuleID (%d) not found\n"), ModuleID); 00480 return (HINSTANCE)HINSTANCE_ERROR; 00481 } 00482 else 00483 return (Item->m_pOILModule->GetInstance()); 00484 } 00485 00486 /******************************************************************************************** 00487 00488 > OILModule::OILModule(UINT32 ModuleID) 00489 00490 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00491 Created: 14/7/93 00492 Inputs: - 00493 Outputs: - 00494 Returns: - 00495 Purpose: Provides access to the OIL specific features of a module. 00496 Errors: - 00497 SeeAlso: GetInstance 00498 00499 ********************************************************************************************/ 00500 00501 00502 OILModule::OILModule() 00503 { 00504 // Initialise to a value that can be easily recognised as invalid. 00505 hInstance = (HINSTANCE)HINSTANCE_ERROR; 00506 } 00507 00508 /******************************************************************************************** 00509 00510 > HINSTANCE OILModule::GetInstance() 00511 00512 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00513 Created: 14/7/93 00514 Inputs: - 00515 Outputs: - 00516 Returns: - 00517 Purpose: Returns the HINSTANCE of the DLL that this module's resources are in. 00518 Errors: - 00519 SeeAlso: - 00520 00521 ********************************************************************************************/ 00522 00523 00524 HINSTANCE OILModule::GetInstance() 00525 { 00526 return hInstance; 00527 }