/****************************************************************************
**
**  Name: ldrdlgs.cpp
**
**  Description:
**     Definitions of function to handle the Loader dialog boxes.
**
**  $Log:   S:/tbird/mt2_186/loader/ldrdlgs.cpv  $
** 
**    Rev 1.2   26 Feb 1997 11:49:38   Judy
** 
**    Rev 1.1   20 Dec 1996 16:39:44   matt
** 
**    Rev 1.5   12 Oct 1994 09:22:50   nghia
** Revised to support separate Load Options dialog for each load format.
** 
**    Rev 1.4   11 Oct 1994 10:31:08   nghia
** Temporary changes to support dynamically setup the load options dialog box
** according to the loadfile format.
** 
**    Rev 1.3   30 Aug 1994 17:21:20   nghia
** Revised LoadOption proc to handle new load option: CHECKBX_REGISTERS.
** 
**    Rev 1.2   25 Jul 1994 17:25:32   nghia
** Revised WM_INITDIALOG to post itself a message to change directory when
** the initial directory is set.
** 
**    Rev 1.1   20 Jul 1994 09:58:52   nghia
** Saved the selected load options and load space when the user selected OK.
** 
**    Rev 1.0   14 Jul 1994 10:51:20   nghia
** Initial revision.
**
**  $Header:   S:/tbird/mt2_186/loader/ldrdlgs.cpv   1.2   26 Feb 1997 11:49:38   Judy  $
**
**  Copyright (C) 1994 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include <dlgs.h>     // to process HookProc
#include <string.h>

#ifndef _BASEWIND_
#include "basewind.h"
#endif

#ifndef _PROC_
#include "proc.h"
#endif

#ifndef _ADDR_
#include "addr.h"
#endif

#ifndef _LOADER_
#include "loader.h"
#endif

#ifndef _HLPENTRY_
#include "hlpentry.h"   // Help entry declaration
#endif

#ifndef __LDROBJ__
#include "ldrobj.h"
#endif

#ifndef __CUSTDLG__
#include "custdlg.h"
#endif

#ifndef __LDRDLGS__
#include "ldrdlgs.h"
#endif

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
// Private data uses by Load Options Dialog Box
PRIVATE U32 dlgOptions;
PRIVATE ADDR_SPACE dlgAddrSpace;
PRIVATE U16 dlgRscId;
PRIVATE CHAR tmpFileName[MAX_FILE_NAME];

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
/* Global Loader Variables */
extern PROCESSOR_FAMILY procFamily;  // defined in LIBMAIN.CPP
extern HANDLE hLib;                    
extern PTLdrLauncher LoaderServer;   // defined in LDROBJ.CPP


                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
/*****************************************************************************
**
**  LdrOpenLoadFileDlg
**
*****************************************************************************/
RETCODE LdrOpenLoadFileDlg(HWND parent, LPSTR initDir, LPSTR loadFileName,
                           U32 *loadFlags, ADDR_SPACE *addrSpace) {
 
   // use stack based <LoadFileDlg> object to support multiple session
   LoadFileDlg newLoadFileDlg(parent,
                              (procFamily == FAMILY_X86 ?
                              IDS_INTEL_LOAD_FILTER : IDS_MOTO_LOAD_FILTER),
                              initDir, *loadFlags, *addrSpace);
   loadFileName[0] = '\0';
   if (newLoadFileDlg.status != GOOD)
      return newLoadFileDlg.status;
   // Get the file name and return it
   // NOTES: <LoadFileDlg> object is destroyed as the function exits.
   return newLoadFileDlg.GetLoadFileInfo(loadFileName, loadFlags, addrSpace);
}

/*****************************************************************************
**
**  LdrLoadFileDlgHookProc
**
*****************************************************************************/
#pragma argsused  // suppress compiler warning
UINT CALLBACK LdrLoadFileDlgHookProc(HWND hDlg, UINT msg, WPARAM wP,
                                      LPARAM lP) {   
   LoadFileDlg *self = LoadFileDlg::GetObject(hDlg);
   static U16 loadOptionsDlgRscId =  LOPTIONS_DEFAULT_DLG; // default
   RETCODE err;
   S16 dummy;

   switch(msg) {
      case WM_INITDIALOG:
         // register F1 help for the dialog
	 RegisterHelpEntry(HI_DLGR_LOAD_FILE, (LONG) hDlg, HE_DLGR_LOAD_FILE);
         // Disable the OPTIONS button until user selects a loadfile.
         EnableWindow(GetDlgItem(hDlg, ID_OPTIONS), FALSE);
         
         // Force Dialog to change directory to the initial directory
         // post myself a message.
         if (self && (lstrlen(self->ofn.lpstrFile) > 0)) 
            PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
         
         return TRUE;

      case WM_COMMAND:
         switch(wP) {
            case pshHelp:
            {
	       WORD hlpId;
	       char lpFilename[256];

               // retrieve the Help-Context Id of object running <hDlg>
               if ((err = CommFileDlg::GetHelpId(hDlg, &hlpId)) != GOOD) {
		  ErrDisplayFormattedError(err, FORCE_POPUP, NULL, NULL, NULL,
                                           MB_OK, &dummy);
                  return TRUE;
               }
	       // display help for dialog
	       /*Hera 12/17/96*/
	       if(GetModuleFileName(hLib, lpFilename, sizeof(lpFilename)) == 0)
	          return TRUE;
	       else
               {
		  *(strrchr(lpFilename,'\\')+1) = '\0';
                  strcat(lpFilename,"PWRVIEWS.HLP");
		  WinHelp(hDlg, lpFilename, HELP_CONTEXT, HE_DLGR_LOAD_FILE);
	       }
	       return (FALSE);
	       /*Hera*/
            }
            
            case ID_OPTIONS:
            {
               // get self object to get the load Options and address Space
               // after user make the selection, save the new information
               // back into self.
               if (!self) { 
                  ErrDisplayFormattedError(ER_CANNOT_OPEN_DIALOG,
                                        FORCE_POPUP, NULL, NULL, NULL,
                                        MB_OK, &dummy);
                  return TRUE;
               }
               // Open the Load Options Dialog 
               if ((err = LdrOpenLoadOptionsDlg(hDlg,
                                                &(self->loadOptions),
                                                &(self->loadAddrSpace),
                                                loadOptionsDlgRscId))
                   != GOOD) {
                  ErrDisplayFormattedError(err, FORCE_POPUP, NULL, NULL, NULL,
                                           MB_OK, &dummy);
               }
               return TRUE;            
            }
            
            case lst1:  // NOTES: lst1 defined in /INCLUDE/DLGS.H
            {
               // Validate load format to setup Load Options resource Id
               // retrieve the text changed in LB <lst1>.
               if (HIWORD(lP) == LBN_SELCHANGE) {
                  // enable the OPTIONS button
                  if ((err = LdrValidateSelFile(hDlg,
                                             &loadOptionsDlgRscId)) == GOOD) {
                     // enable the OPTIONS button
                     EnableWindow(GetDlgItem(hDlg, ID_OPTIONS), TRUE);
                  }
                  else {  
                     // enable the OPTIONS button
                     EnableWindow(GetDlgItem(hDlg, ID_OPTIONS), FALSE);
                     ErrDisplayFormattedError(err, FORCE_POPUP, NULL,
                                              NULL, NULL, MB_OK, &dummy);
                  }
               }
               return FALSE;   
            }
         } // switch(wP)
   } // switch(msg)

   // allow Windows standard processing.
   return FALSE; 
}   

/*****************************************************************************
**
**  LdrOpenLoadOptionsDlg
**
*****************************************************************************/
RETCODE EXPORT LdrOpenLoadOptionsDlg(HWND parentHwnd, U32 FAR *loadOptions,
                                     ADDR_SPACE FAR *addrSpace,
                                     U16 resourceId) {
   RETCODE err = GOOD;
   FARPROC lpLdrOptionsDlgProc;
   S16 dlgStatus;
   LPSTR dlgTemplateName;
   
   // hook LdrOptionsDlgProc and run it modal */
   if ((lpLdrOptionsDlgProc = (FARPROC) MakeProcInstance(
               (FARPROC)LdrOptionsDlgProc, hLib)) != NULL) {
      dlgOptions   = *loadOptions;
      dlgAddrSpace = *addrSpace;
      dlgRscId     = resourceId;
      // extract the Load Options dialog resource template
      dlgTemplateName = MAKEINTRESOURCE(resourceId);
      
      // run the Options dialog box
      if ((dlgStatus = DialogBox(hLib, dlgTemplateName, parentHwnd,
                    lpLdrOptionsDlgProc)) == -1) {
         err = ER_CANNOT_OPEN_DIALOG;
      }
      // release proc instance for Windows
      FreeProcInstance(lpLdrOptionsDlgProc);
   }
   else
      err = ER_CANNOT_OPEN_DIALOG;
   
   // retrieve the new selection only if user select OK
   if ((err == GOOD) && (dlgStatus)) {
      *loadOptions = dlgOptions;
      *addrSpace   = dlgAddrSpace;
      LoaderServer->LastLoadOptions(dlgOptions);
      LoaderServer->LastLoadSpace(dlgAddrSpace);
   }
   return err;
}

/******************************************************************************
**
** LdrOptionsDlgProc
**
** Description: Provide UI processing to allow the users operate the
**    Load Options dialog box.
**
** Parameters:
**    input:
**       hDlg          - The window handle for this message
**       iMsg          - The message number
**       wParam        - The WORD parmater for this message
**       lParam        - The LONG parmater for this message
**
**    output:
**       depend on message
**
******************************************************************************/
#pragma warn -par
BOOL EXPORT LdrOptionsDlgProc(HWND hDlg, WORD iMsg, WORD wParam,
                                  LONG lParam) {
   // NOTES: defined <dummy> to ensure that the compiler will generate
   // code to switch the DLL's DS when Windows call this routine.
#pragma warn -aus
   static U32 dummy;
   static WORD procOption = 0;
   
   switch(iMsg) {
      case WM_INITDIALOG:
         // register F1 help for the dialog
         RegisterHelpEntry(HI_DLGR_LOAD_OPTIONS, (LONG) hDlg,
                           HE_DLGR_LOAD_OPTIONS);
         // initialize address space for X86 Load Options
         if (procFamily == FAMILY_X86) 
            CheckRadioButton(hDlg, BUTTON_SPACE_USER, BUTTON_SPACE_SMM,
                             (dlgAddrSpace == SPACE_USER ?
                              BUTTON_SPACE_USER : BUTTON_SPACE_SMM));
         // set check box options
         CheckDlgButton(hDlg, CHECKBX_CODE, IsLoadCode(dlgOptions));
         CheckDlgButton(hDlg, CHECKBX_SYMBOL, IsLoadSymbol(dlgOptions));

         if (procFamily == FAMILY_X86) {
            if (dlgRscId == LOPTIONS_INTEL386_DLG) {
               procOption = CHECKBX_UPDATEBASE;
               CheckDlgButton(hDlg, CHECKBX_REGISTERS, IsLoadReg(dlgOptions));
            }
         }
         else {
            if (dlgRscId == LOPTIONS_MOTO_DLG)
               procOption = CHECKBX_ASMMODULE;
         }
         // disable sub-options of LoadSymbol
         if (!IsLoadSymbol(dlgOptions)) {
            EnableWindow(GetDlgItem(hDlg, CHECKBX_ONDEMAND), 0);
            EnableWindow(GetDlgItem(hDlg, CHECKBX_DEMANGLE), 0);
            EnableWindow(GetDlgItem(hDlg, CHECKBX_IGNORECASE), 0);
            if (procOption)
               EnableWindow(GetDlgItem(hDlg, procOption), 0);
         } else {
            CheckDlgButton(hDlg, CHECKBX_ONDEMAND, IsLoadOnDemand(dlgOptions));
            CheckDlgButton(hDlg, CHECKBX_DEMANGLE, IsDeMangle(dlgOptions));
            CheckDlgButton(hDlg, CHECKBX_IGNORECASE, IsIgnoreCase(dlgOptions));
            if (procOption)
               CheckDlgButton(hDlg, procOption,
                              (procFamily == FAMILY_68K ?
                               IsLoadAsm(dlgOptions) :
                               IsUpdateBase(dlgOptions)));
         }

         CheckDlgButton(hDlg, CHECKBX_STATUS, IsReportStatus(dlgOptions));
         CheckDlgButton(hDlg, CHECKBX_WARNING, IsReportWarning(dlgOptions));
         return(TRUE);

      case WM_COMMAND:
         switch(wParam) {
            case IDOK:
               // return TRUE to let caller known that user selected OK
               EndDialog(hDlg, TRUE);
               return(TRUE);

            case IDCANCEL:
               EndDialog(hDlg, FALSE);
               return(TRUE);

            case IDHELP:
               WinHelp(hDlg, "PWRVIEWS.HLP",
                       HELP_CONTEXT, HE_DLGR_LOAD_OPTIONS);
               return (FALSE);
               
            case BUTTON_SPACE_USER:
               dlgAddrSpace = SPACE_USER;
               break;
            case BUTTON_SPACE_SMM:
               dlgAddrSpace = SPACE_SMM;
               break;
               
            default:
               /* Process all button ID */
               if ((wParam >= CHECKBX_CODE) &&
                   (wParam <= CHECKBX_IGNORECASE)) {
                  if (IsDlgButtonChecked(hDlg, wParam) == 1)
                     dlgOptions |= LOADFLAG(wParam);
                  else
                     dlgOptions &= ~(LOADFLAG(wParam));

                  // disable Symbol related options
                  if (wParam == CHECKBX_SYMBOL) {
                     EnableWindow(GetDlgItem(hDlg, CHECKBX_ONDEMAND),
                                  IsLoadSymbol(dlgOptions));
                     EnableWindow(GetDlgItem(hDlg, CHECKBX_DEMANGLE),
                                  IsLoadSymbol(dlgOptions));
                     EnableWindow(GetDlgItem(hDlg, CHECKBX_IGNORECASE),
                                  IsLoadSymbol(dlgOptions));
                     if ((dlgRscId == LOPTIONS_MOTO_DLG) ||
                         (dlgRscId == LOPTIONS_INTEL386_DLG))  
                        EnableWindow(GetDlgItem(hDlg, procOption),
                                     IsLoadSymbol(dlgOptions));
                  }
                  return(TRUE);
               }
               return(FALSE);
         } /* end of switch(wParam) */

   }
   // allow standard window processing
   return(FALSE);
}

/*****************************************************************************
**
** LdrValidateSelFile
**
******************************************************************************/
RETCODE EXPORT LdrValidateSelFile(HWND hDlg, U16 FAR *lOptionsRscId) {
   DWORD itemIdx = 0;
   RETCODE err = GOOD;
   
   *lOptionsRscId = LOPTIONS_DEFAULT_DLG;  // default Load Option Dialog
   tmpFileName[0] = '\0';
   // retrieve the item selected to test
   if (((itemIdx = SendDlgItemMessage(hDlg, lst1, LB_GETCURSEL, 0, 0L))
        != (DWORD) LB_ERR) &&
       (SendDlgItemMessage(hDlg, lst1, LB_GETTEXT, (WORD)itemIdx,
                                 (DWORD) tmpFileName) != (DWORD)LB_ERR)) {
      if (!LoaderServer) return ER_LDR_INVALID_SERVER;
      // validate for the supported load format
      LOAD_FORMAT loadFormat;
      if ((err = LoaderServer->GetLoadFormat(tmpFileName, &loadFormat))
          == GOOD) {
         switch(loadFormat) {
            case OMF86:   *lOptionsRscId = LOPTIONS_INTEL86_DLG; break; 
            case OMF386:  *lOptionsRscId = LOPTIONS_INTEL386_DLG; break;
            case IEEE695: *lOptionsRscId = LOPTIONS_MOTO_DLG; break;
            case INHEX:   *lOptionsRscId = LOPTIONS_INTELHEX_DLG; break;
            default:      *lOptionsRscId = LOPTIONS_DEFAULT_DLG; break;
         }
      }
   }
   return err;
}
                                
/********************************** E O F ***********************************/
