
/*
 *@@sourcefile xwplink.c:
 *      This file contains SOM code for the following XWorkplace classes:
 *
 *      --  XWPLink (file-system links implementation)
 *
 *      Installation of this class is optional.
 *
 *      If this feature is enabled, XWPLink will be used by
 *      XWorkplace instead of WPShadow for linking to file-system
 *      objects. The point is that WPShadow is a pretty nice idea,
 *      but has a few problems:
 *
 *      --  It clutters up OS2.INI badly, and there's also that limit
 *          of how many abstracts can exist in the system in the
 *          first place.
 *
 *      --  Shadows work only on the local OS/2 installation. You
 *          can't see them over the network.
 *
 *      --  You can't easily recreate shadows after a reinstallation
 *          since they are so highly dependent on those darn
 *          file-system handles in OS2SYS.INI.
 *
 *      XWPLink solves these problems by doing the following:
 *
 *      1)  An XWPLink is really a simple data file with the
 *          .XLK extension, but the extension is hidden in
 *          folders. To the user, an XWPLink object looks and
 *          behaves exactly like a shadow. For this to work,
 *          we must override those parts of the WPS that
 *          create shadows and create XWPLink's instead if
 *          the target objects are file-system objects.
 *
 *      2)  The contents of the .XLK data file is a simple
 *          line containing the relative path of the target
 *          object. This way we can avoid having to maintain
 *          a file-system handles database, and the links
 *          work over the network too. We only need to update
 *          the link if the relative path changes.
 *
 *          The only precondition for this to work is that
 *          the drive letters are the same over the network
 *          if XWPLink objects link across drives.
 *
 *      For updates to work, the link needs to be notified
 *      whenever the target changes and vice versa.
 *      As a result, all file-system objects now need to store
 *      all links pointing to them, using relative paths also.
 *
 *      So the following operations must be intercepted:
 *
 *      1)  When a target object is woken up, it needs to
 *          wake up all links that point to it.
 *
 *      2)  When a target object is moved or renamed, all
 *          links pointing to it must be refreshed.
 *
 *      3)  If a link object is moved or copied, it needs
 *          to update the contained path to the target object
 *          since that path is relative and is now invalid.
 *          It also needs to notify the target object so
 *          it can refresh its list of links pointing to
 *          it.
 *
 *      4)  If the link object is renamed, it needs to rename
 *          the target object and update its contained path.
 *          Again, it needs to notify the target.
 *
 *      The list of links pointing to a target is stored
 *      in the .CLASSDATA of the target and can be updated
 *      asynchronously in _wpSaveState.
 *
 *      Todo: How should this work if a parent folder is
 *      moved or renamed? How does the parent folder know
 *      that there's target objects in it that need updating?
 *
 *@@somclass XWPLink xlk_
 *@@somclass M_XWPLink xlkM_
 */

/*
 *      Copyright (C) 2003 Ulrich M”ller.
 *
 *      This file is part of the XWorkplace source package.
 *      XWorkplace 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 XWorkplace 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.41
 */

#ifndef SOM_Module_xwplink_Source
#define SOM_Module_xwplink_Source
#endif
#define XWPLink_Class_Source
#define M_XWPLink_Class_Source

#pragma strings(readonly)

/*
 *  Suggested #include order:
 *  1)  os2.h
 *  2)  C library headers
 *  3)  setup.h (code generation and debugging options)
 *  4)  headers in helpers\
 *  5)  at least one SOM implementation header (*.ih)
 *  6)  dlgids.h, headers in shared\ (as needed)
 *  7)  headers in implementation dirs (e.g. filesys\, as needed)
 *  8)  #pragma hdrstop and then more SOM headers which crash with precompiled headers
 */

#define INCL_DOSPROCESS
#define INCL_DOSEXCEPTIONS
#define INCL_DOSSEMAPHORES
#define INCL_DOSERRORS

#include <os2.h>

// C library headers
#include <stdio.h>
#include <setjmp.h>             // needed for except.h
#include <assert.h>             // needed for except.h

// generic headers
#include "setup.h"                      // code generation and debugging options

// headers in /helpers

// SOM headers which don't crash with prec. header files
#include "xwplink.ih"

// XWorkplace implementation headers
#include "shared\common.h"              // the majestic XWorkplace include file
#include "shared\kernel.h"              // XWorkplace Kernel

#pragma hdrstop                         // VAC++ keeps crashing otherwise

/* ******************************************************************
 *
 *   Global variables
 *
 ********************************************************************/

static PCSZ G_pcszLinkFilter = "*.XLN";

/* ******************************************************************
 *
 *   XWPLink instance methods
 *
 ********************************************************************/

SOM_Scope WPFileSystem*  SOMLINK xlk_xwpQueryTarget(XWPLink *somSelf)
{
    XWPLinkData *somThis = XWPLinkGetData(somSelf);
    XWPLinkMethodDebug("XWPLink","xlk_xwpQueryTarget");

    return NULL;
}

/*
 *@@ wpInitData:
 *      this WPObject instance method gets called when the
 *      object is being initialized (on wake-up or creation).
 *      We initialize our additional instance data here.
 *      Always call the parent method first.
 */

SOM_Scope void  SOMLINK xlk_wpInitData(XWPLink *somSelf)
{
    /* XWPLinkData *somThis = XWPLinkGetData(somSelf); */
    XWPLinkMethodDebug("XWPLink","xlk_wpInitData");

    XWPLink_parent_XFldDataFile_wpInitData(somSelf);
}

/*
 *@@ wpUnInitData:
 *      this WPObject instance method is called when the object
 *      is destroyed as a SOM object, either because it's being
 *      made dormant (via wpMakeDormant) or being deleted for
 *      good (via wpFree). All allocated in-memory resources
 *      should be freed here, but to destroy the physical
 *      representation of the object, override wpDestroyObject
 *      instead.
 *
 *      The parent method must always be called last.
 */

SOM_Scope void  SOMLINK xlk_wpUnInitData(XWPLink *somSelf)
{
    /* XWPLinkData *somThis = XWPLinkGetData(somSelf); */
    XWPLinkMethodDebug("XWPLink","xlk_wpUnInitData");

    XWPLink_parent_XFldDataFile_wpUnInitData(somSelf);
}


/*
 *@@ xwpResolveIfLink:
 *      this new XFldObject method returns the object that
 *      somSelf points to.
 *
 *      We override this to return the object that this
 *      link points to.
 */

SOM_Scope WPObject*  SOMLINK xlk_xwpResolveIfLink(XWPLink *somSelf)
{
    /* XWPLinkData *somThis = XWPLinkGetData(somSelf); */
    XWPLinkMethodDebug("XWPLink","xlk_xwpResolveIfLink");

    return NULL;
}


/* ******************************************************************
 *
 *   XWPLink class methods
 *
 ********************************************************************/

/*
 *@@ wpclsInitData:
 *      this M_WPObject class method gets called when a class
 *      is loaded by the WPS (probably from within a
 *      somFindClass call) and allows the class to initialize
 *      itself.
 *
 */

SOM_Scope void  SOMLINK xlkM_wpclsInitData(M_XWPLink *somSelf)
{
    /* M_XWPLinkData *somThis = M_XWPLinkGetData(somSelf); */
    M_XWPLinkMethodDebug("M_XWPLink","xlkM_wpclsInitData");

    M_XWPLink_parent_M_XFldDataFile_wpclsInitData(somSelf);

    krnClassInitialized(G_pcszXWPLink);
}

/*
 *@@ wpclsCreateDefaultTemplates:
 *
 */

SOM_Scope BOOL  SOMLINK xlkM_wpclsCreateDefaultTemplates(M_XWPLink *somSelf,
                                                         WPObject* Folder)
{
    /* M_XWPLinkData *somThis = M_XWPLinkGetData(somSelf); */
    M_XWPLinkMethodDebug("M_XWPLink","xlkM_wpclsCreateDefaultTemplates");

    // pretend we've created the template
    return TRUE;
}

/*
 *@@ wpclsQueryTitle:
 *
 */

SOM_Scope PSZ  SOMLINK xlkM_wpclsQueryTitle(M_XWPLink *somSelf)
{
    /* M_XWPLinkData *somThis = M_XWPLinkGetData(somSelf); */
    M_XWPLinkMethodDebug("M_XWPLink","xlkM_wpclsQueryTitle");

    return "File Link";     // @@todo localize
}

/*
 *@@ wpclsQueryIconData:
 *      this M_WPObject class method must return information
 *      about how to build the default icon for objects
 *      of a class. This gets called from various other
 *      methods whenever a class default icon is needed;
 *      most importantly, M_WPObject::wpclsQueryIcon
 *      calls this to build a class default icon, which
 *      is then cached in the class's instance data.
 *      If a subclass wants to change a class default icon,
 *      it should always override _this_ method instead of
 *      wpclsQueryIcon.
 *
 *      Note that the default WPS implementation does not
 *      allow for specifying the ICON_FILE format here,
 *      which is why we have overridden
 *      M_XFldObject::wpclsQueryIcon too. This allows us
 *      to return icon _files_ for theming too. For details
 *      about the WPS's crappy icon management, refer to
 *      src\filesys\icons.c.
 *
 *      Per default, we return the same "broken shadow"
 *      icon as the WPShadow class.
 */

SOM_Scope ULONG  SOMLINK xlkM_wpclsQueryIconData(M_XWPLink *somSelf,
                                                 PICONINFO pIconInfo)
{
    ULONG cb = 0;

    /* M_XWPLinkData *somThis = M_XWPLinkGetData(somSelf); */
    M_XWPLinkMethodDebug("M_XWPLink","xlkM_wpclsQueryIconData");

    if (!cmnGetStandardIcon(STDICON_SHADOWBROKEN,
                            NULL,            // no hpointer
                            &cb,
                            pIconInfo))      // can be NULL
        return cb;

    return 0;
}

/*
 *@@ wpclsQueryInstanceFilter:
 *      this M_WPFileSystem class method determines which file-system
 *      objects will be instances of a certain class according
 *      to a file filter.
 *
 */

SOM_Scope PSZ  SOMLINK xlkM_wpclsQueryInstanceFilter(M_XWPLink *somSelf)
{
    /* M_XWPLinkData *somThis = M_XWPLinkGetData(somSelf); */
    M_XWPLinkMethodDebug("M_XWPLink","xlkM_wpclsQueryInstanceFilter");

    return (PSZ)G_pcszLinkFilter;
}

/*
 *@@ wpclsQueryInstanceType:
 *
 */

SOM_Scope PSZ  SOMLINK xlkM_wpclsQueryInstanceType(M_XWPLink *somSelf)
{
    /* M_XWPLinkData *somThis = M_XWPLinkGetData(somSelf); */
    M_XWPLinkMethodDebug("M_XWPLink","xlkM_wpclsQueryInstanceType");

    return "File Link";     // @@todo localize
}

