
/*
 *@@sourcefile xfdisk.c:
 *      This file contains the following major XFolder parts:
 *      --  XFldDisk SOM stuff
 *
 *      Check the other files starting with xf* for the
 *      other XFolder classes.
 *
 *      XFldDisk is needed mainly to modify the popup menus
 *      of Disk objects also. Since these are not instances
 *      of WPFolder, we need an extra subclass.
 *
 *      This class must always be installed.
 *
 *@@somclass XFldDisk xfdisk_
 *@@somclass M_XFldDisk xfdiskM_
 */

/*
 *      Copyright (C) 1997-99 Ulrich M”ller.
 *      This file is part of the XFolder source package.
 *      XFolder is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published
 *      by the Free Software Foundation, in version 2 as it comes in the
 *      "COPYING" file of the XFolder main distribution.
 *      This program 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 General Public License for more details.
 */

/*
 *  This file was generated by the SOM Compiler and Emitter Framework.
 *  Generated using:
 *      SOM Emitter emitctm: 2.42
 */

#ifndef SOM_Module_xfdisk_Source
#define SOM_Module_xfdisk_Source
#endif
#define XFldDisk_Class_Source
#define M_XFldDisk_Class_Source

/*
 *  Suggested #include order:
 *  1)  os2.h
 *  2)  C library headers
 *  3)  SOM headers which work with precompiled header files
 *  4)  headers in /helpers
 *  5)  headers in /main with dlgids.h and common.h first
 *  6)  #pragma hdrstop to prevent VAC++ crashes
 *  7)  other needed SOM headers
 *  8)  for non-SOM-class files: corresponding header (e.g. classlst.h)
 */

#define INCL_DOSPROCESS         // DosSleep, priorities, PIDs etc.
#define INCL_DOSSEMAPHORES      // needed for xthreads.h
#define INCL_DOSEXCEPTIONS
#define INCL_DOSERRORS
#define INCL_DOSMISC            // DosGetMessage etc.
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_WIN
#include  <os2.h>

// C library headers
#include <stdio.h>

// headers in /helpers
#include "undoc.h"              // some undocumented stuff

// SOM headers which don't crash with prec. header files
#include "xfdisk.ih"
#include "xfldr.h"

// headers in /main
#include "common.h"             // the majestic XFolder include file

#include "menus.h"              // common XFolder context menu logic
#include "statbars.h"           // status bar translation logic

// other SOM headers
#include "xwps.h"               // XFolder pseudo SOM functions


// global array of all awake Disk objects
XFldDisk* apDrives[27];

/* ******************************************************************
 *                                                                  *
 *   here come the XFldDsk instance methods                         *
 *                                                                  *
 ********************************************************************/

/*
 *@@ wpFilterPopupMenu:
 *           remove default entries for disks according to Global Settings
 */

SOM_Scope ULONG  SOMLINK xfdisk_wpFilterPopupMenu(XFldDisk *somSelf,
                                                ULONG ulFlags,
                                                HWND hwndCnr,
                                                BOOL fMultiSelect)
{
    PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
    // XFldDiskData *somThis = XFldDiskGetData(somSelf);
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpFilterPopupMenu");

    return (XFldDisk_parent_WPDisk_wpFilterPopupMenu(somSelf,
                                                     ulFlags,
                                                     hwndCnr,
                                                     fMultiSelect)
        & ~(pGlobalSettings->DefaultMenuItems)
        );
}

/*
 *@@ wpModifyPopupMenu:
 *           this method allows an object to modify a context
 *           menu. We add the various XFolder menu entries here
 *           by calling mnuModifyPopupMenu in menus.c,
 *           which is also used by the XFolder class.
 */

SOM_Scope BOOL  SOMLINK xfdisk_wpModifyPopupMenu(XFldDisk *somSelf,
                                               HWND hwndMenu,
                                               HWND hwndCnr,
                                               ULONG iPosition)
{
    PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
    BOOL            rc;

    // get the "root folder" of the WPDisk object; that is the
    // folder which is opened when the disk object is opened
    // (i.e. the folder of the root directory). This returns
    // NULL if the drive is not ready.
    XFolder         *pFolder = _wpQueryRootFolder(somSelf);

    // XFldDiskData *somThis = XFldDiskGetData(somSelf);
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpModifyPopupMenu");

    rc = XFldDisk_parent_WPDisk_wpModifyPopupMenu(somSelf,hwndMenu,hwndCnr,iPosition);

    if (pGlobalSettings->RemoveFormatDiskItem) {
        WinSendMsg(hwndMenu, MM_REMOVEITEM,
                MPFROM2SHORT(ID_WPMI_FORMATDISK, FALSE),
                0);
    }

    if (pGlobalSettings->RemoveCheckDiskItem) {
        WinSendMsg(hwndMenu, MM_REMOVEITEM,
                MPFROM2SHORT(ID_WPMI_CHECKDISK, FALSE),
                0);
    }

    if (pFolder) {
        // drive ready
        rc = mnuModifyPopupMenu(pFolder, hwndMenu, hwndCnr, iPosition);
    }

    return (rc);
}

/*
 *@@ wpMenuItemSelected:
 *           process input when any menu item was selected;
 *           we pass the input to mnuMenuItemSelected in menus.c.
 */

SOM_Scope BOOL  SOMLINK xfdisk_wpMenuItemSelected(XFldDisk *somSelf,
                                                HWND hwndFrame,
                                                ULONG ulMenuId)
{
    XFolder         *pFolder = _wpQueryRootFolder(somSelf);
    // XFldDiskData *somThis = XFldDiskGetData(somSelf);
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpMenuItemSelected");

    if (mnuMenuItemSelected(pFolder, hwndFrame, ulMenuId))
        return TRUE;
    else
        return (XFldDisk_parent_WPDisk_wpMenuItemSelected(somSelf, hwndFrame,
                                                   ulMenuId));
}

/*
 *@@ wpMenuItemHelpSelected:
 *           display help for a context menu item;
 *           we pass the input to mnuMenuItemHelpSelected in menus.c.
 */

SOM_Scope BOOL  SOMLINK xfdisk_wpMenuItemHelpSelected(XFldDisk *somSelf,
                                                    ULONG MenuId)
{
    XFolder         *pFolder = _wpQueryRootFolder(somSelf);
    // XFldDiskData *somThis = XFldDiskGetData(somSelf);
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpMenuItemHelpSelected");

    if (mnuMenuItemHelpSelected(pFolder, MenuId))
        return TRUE;
    else
        return (XFldDisk_parent_WPDisk_wpMenuItemHelpSelected(somSelf,
                                                           MenuId));
}

/*
 *@@ wpViewObject:
 *           this either opens a view of the given Disk object
 *           as a root folder (using wpOpen) or resurfaces an
 *           already open view.
 *           This gets called every time the user tries to open
 *           a disk object, e.g. by double-clicking on one in the
 *           "Drives" folder.
 *           The WPS seems to be doing no drive checking in here,
 *           which leads to the annoying "Drive not ready" popups.
 *           So we try to implement this here.
 */

SOM_Scope HWND  SOMLINK xfdisk_wpViewObject(XFldDisk *somSelf,
                                            HWND hwndCnr, ULONG ulView,
                                            ULONG param)
{
    HWND            hwndFrame = NULLHANDLE; // default: error occured
    APIRET          arc = NO_ERROR;
    XFolder*        pRootFolder;
    ULONG           mbrc = MBID_OK;

    /* XFldDiskData *somThis = XFldDiskGetData(somSelf); */
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpViewObject");

    // query root folder (WPRootFolder class, which is a descendant
    // of WPFolder/XFolder); each WPDisk is paired with one of those,
    // and the actual display is done by this class, so we will pass
    // pRootFolder instead of somSelf to most following method calls.
    // We use xwpsQueryRootFolder instead of wpQueryRootFolder to
    // avoid the "Drive not ready" popups which the WPS/OS/2 normally
    // displays in this method.
    do {
        HPOINTER hptrOld = WinQueryPointer(HWND_DESKTOP);
        WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
        pRootFolder = xwpsQueryRootFolder(somSelf, &arc);
        WinSetPointer(HWND_DESKTOP, hptrOld);

        mbrc = MBID_OK;

        if (pRootFolder == NULL) {
            // drive not ready:
            CHAR    szError[400],
                    szTitle[400];
            ULONG   ulLen = 0;
            DosGetMessage(NULL, 0,       // no string replacements
                    szError, sizeof(szError),
                    arc,
                    "OSO001.MSG",        // default OS/2 message file
                    &ulLen);

            cmnGetMessage(NULL, 0, szTitle, sizeof(szTitle), 104);
                            // "XFolder: Error"
            sprintf(szTitle + strlen(szTitle),
                    " (\"%s\")", _wpQueryTitle(somSelf));
                            // append drive name in brackets
            mbrc = cmnMessageBox(HWND_DESKTOP,
                    szTitle,
                    szError,
                    MB_RETRYCANCEL);
        }
    } while (mbrc == MBID_RETRY);

    if (pRootFolder)
        hwndFrame = XFldDisk_parent_WPDisk_wpViewObject(somSelf, hwndCnr,
                                                ulView, param);

    return (hwndFrame);
}

/*
 *@@ wpOpen:
 *           this method gets called when wpViewObject thinks a
 *           new view of the object needs to be opened.
 *           We call the parent first and then subclass the
 *           resulting frame window, similar to what we're doing
 *           with folder views (see XFolder::wpOpen).
 */

SOM_Scope HWND  SOMLINK xfdisk_wpOpen(XFldDisk *somSelf, HWND hwndCnr,
                                       ULONG ulView, ULONG param)
{
    HWND            hwndNewFrame = NULLHANDLE; // default: error occured
    APIRET          arc = NO_ERROR;
    XFolder*        pRootFolder;
    // XFldDiskData *somThis = XFldDiskGetData(somSelf);
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpOpen");

    // query root folder (WPRootFolder class, which is a descendant
    // of WPFolder/XFolder); each WPDisk is paired with one of those,
    // and the actual display is done by this class, so we will pass
    // pRootFolder instead of somSelf to most following method calls.
    // We use xwpsQueryRootFolder instead of wpQueryRootFolder to
    // avoid "Drive not ready" popups.
    pRootFolder = xwpsQueryRootFolder(somSelf, &arc);

    if (pRootFolder) {
        // drive ready: call parent to get frame handle
        hwndNewFrame = XFldDisk_parent_WPDisk_wpOpen(somSelf, hwndCnr, ulView,
                                              param);

        if (hwndNewFrame)
        {
            // open successful:
            if (   (ulView == OPEN_CONTENTS)
                || (ulView == OPEN_TREE)
                || (ulView == OPEN_DETAILS)
               )
            {
                PSUBCLASSEDLISTITEM psli;
                PGLOBALSETTINGS     pGlobalSettings = cmnQueryGlobalSettings();

                // subclass frame window; this is the same
                // proc which is used for normal folder frames,
                // we just use pRootFolder instead.
                // However, we pass somSelf as the "real" object
                // which will then be stored in *psli.
                psli = cmnSubclassFolderFrame(hwndNewFrame, pRootFolder, somSelf, ulView);

                // add status bar, if allowed: as opposed to
                // XFolder's, for XFldDisk's we only check the
                // global setting, because there's no instance
                // setting for this with XFldDisk's
                if (pGlobalSettings->StatusBar)
                    // assert that subclassed list item is valid
                    if (psli)
                        // add status bar only if allowed for the current view type
                        if (    (   (ulView == OPEN_CONTENTS)
                                 && (pGlobalSettings->SBForViews & SBV_ICON)
                                )
                             || (   (ulView == OPEN_TREE)
                                 && (pGlobalSettings->SBForViews & SBV_TREE)
                                )
                             || (   (ulView == OPEN_DETAILS)
                                 && (pGlobalSettings->SBForViews & SBV_DETAILS)
                                )
                            )
                            // this reformats the window with the status bar
                            _xfShowStatusBar(pRootFolder, psli, TRUE);

                // extended sort functions
                if (pGlobalSettings->ReplaceSort)
                {
                    hwndCnr = xwpsQueryCnrFromFrame(hwndNewFrame);
                    if (hwndCnr)
                        _xfSetCnrSort(pRootFolder, hwndCnr, FALSE);
                }
            }
        }
    }

    return (hwndNewFrame);
}

/*
 *@@ wpInitData:
 *           initialize XFldDisk instance data
 */

SOM_Scope void  SOMLINK xfdisk_wpInitData(XFldDisk *somSelf)
{
    // XFldDiskData *somThis = XFldDiskGetData(somSelf);
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpInitData");

    XFldDisk_parent_WPDisk_wpInitData(somSelf);

    // _szFSType[0] = '\0';
}

/*
 *@@ wpObjectReady:
 *           this instance method is called by the system when
 *           object awakening is complete and object data seems
 *           to be stable in memory.
 *           We will have this object's pointer stored in a
 *           global array to be able to find the Disk object for
 *           a given object (xfclsQueryDiskObject).
 */

SOM_Scope void  SOMLINK xfdisk_wpObjectReady(XFldDisk *somSelf,
                                             ULONG ulCode, WPObject* refObject)
{
    ULONG ulDisk;
    // XFldDiskData *somThis = XFldDiskGetData(somSelf);
    XFldDiskMethodDebug("XFldDisk","xfdisk_wpObjectReady");

    XFldDisk_parent_WPDisk_wpObjectReady(somSelf, ulCode, refObject);

    ulDisk = _wpQueryLogicalDrive(somSelf);
    apDrives[ulDisk] = somSelf;

    /* XFldDisk_parent_XFldObject_wpObjectReady(somSelf, ulCode,
                                             refObject); */
}

/* ******************************************************************
 *                                                                  *
 *   here come the xfdisk class methods                            *
 *                                                                  *
 ********************************************************************/

/*
 *@@ xfclsQueryDisk:
 *           since I have no idea what the default wpQueryDisk
 *           is for (why the hell does it return a WPFileSystem?),
 *           this is a proper method which returns the disk object
 *           which corresponds to the drive on which the object
 *           resides. This works for both abstract and file-system
 *           objects.
 *           Returns NULL upon errors.
 *           Note: this method only works after the Drives folder
 *           has been populated because it relies on our
 *           wpObjectReady override for XFldDisk. Otherwise you'll
 *           get NULL back.
 *           The WPS normally populates that folder a few seconds
 *           after the Desktop is up.
 */

SOM_Scope XFldDisk*  SOMLINK xfdiskM_xfclsQueryDiskObject(M_XFldDisk *somSelf,
                                                          WPObject* pObject)
{
    ULONG ulLogicalDrive = xwpsQueryLogicalDriveNumber(pObject);
    /* M_XFldDiskData *somThis = M_XFldDiskGetData(somSelf); */
    M_XFldDiskMethodDebug("M_XFldDisk","xfdiskM_xfclsQueryDiskObject");

    // _Pmpf(("xfclsQueryDiskObject: ulDrive = %d", ulLogicalDrive));
    return (apDrives[ulLogicalDrive]);
}

/*
 *@@ wpclsInitData:
 *           initialize class instance data
 */

SOM_Scope void  SOMLINK xfdiskM_wpclsInitData(M_XFldDisk *somSelf)
{
    // M_XFldDiskData *somThis = M_XFldDiskGetData(somSelf);
    M_XFldDiskMethodDebug("M_XFldDisk","xfdiskM_wpclsInitData");

    M_XFldDisk_parent_M_WPDisk_wpclsInitData(somSelf);
    // M_XFldDisk_parent_M_XFldObject_wpclsInitData(somSelf);

    // szWPDiskStatusBarMnemonics[0] = '\0';
    memset(&apDrives, 0, sizeof(apDrives));
}


