#define DEBUG//                                      (VER.REV.1)
#define ADD_DEBUG_CODE//                             (VER.REV.1)
#include <debug.h>//                                 (VER.REV.1)
//                                                   (VER.REV.1)
#include "MP.h"//                                    (VER.REV.1)
#include <extras/macros/exec.h>
struct SignalSemaphore LockPubSem;

extern struct Process  *MPTask;
extern BYTE   PublicSignal;


extern struct MPSem *MPSem;
extern UBYTE   ModePro[];

131extern struct Screen * __asm (*OldLockPubScreen)(register __a0 UBYTE *Name,
                                               register __a6 struct Library *);
extern void __asm (*OldUnlockPubScreen)(register __a0 UBYTE *Name,
                                        register __a1 struct Screen *,
                                        register __a6 struct Library *);


struct Screen * __saveds __asm NewLockPubScreen(register __a0 UBYTE *Name,
                                                register __a6 struct IntuitionBase *IBase)
{
  struct OpenNode *on;
  struct Screen *scr, *ps;
  struct DefaultNode *dnode;
  LONG button;
  char tnamebuffer[52];
  char *tname;
  ULONG stackid=0xc0de0020;
  
  tname=SetupTaskName(tnamebuffer,", LPS",50);

#ifdef ADD_DEBUG_CODE
  if(MPSem->Debug)
  {
    DKP("LockPubScreen(%s)\n",Name);
  }
#endif

  ps=0;

  // 4.53 @11 Should keep duplicate pubscreens from being created in a race condition
  ObtainSemaphoreShared(&MPSem->ListSem); 
  ObtainSemaphore(&MPSem->NodeSem);

  if(scr=OldLockPubScreen(Name,(struct Library *)IntuitionBase))
  {
    DEBUG_CODE(DKP("  RV=0x%08lx\n",ps););

    SetTaskName(tname);
    
    ReleaseSemaphore(&MPSem->NodeSem);    
    ReleaseSemaphore(&MPSem->ListSem);

    return(scr);
  }
  else
  {
    ObtainSemaphore(&LockPubSem);
    if(scr=OldLockPubScreen(Name,(struct Library *)IntuitionBase))
    {
      DEBUG_CODE(DKP("  RV=0x%08lx\n",ps););

      SetTaskName(tname);

      ReleaseSemaphore(&LockPubSem);      
      ReleaseSemaphore(&MPSem->NodeSem);    
      ReleaseSemaphore(&MPSem->ListSem);
  
      return(scr);
    }
    else    
    {
      if(strcmp("Workench",Name)) // Can't f with Workbench!
      {
        // 4.53 moved above
//      ObtainSemaphoreShared(&MPSem->ListSem); 
//      ObtainSemaphore(&MPSem->NodeSem);
        
        if(dnode=FindDNode(&MPSem->PromotionList[PL_PUBLICSCREENS],Name))
        {
          if(dnode->Flags & DNF_NEVER_PROMOTE)
            dnode=0;
          else
            dnode=DupDNode(dnode);
  
          ReleaseSemaphore(&MPSem->NodeSem);    
        }
        else
        {
          ReleaseSemaphore(&MPSem->NodeSem);    
          if(MPSem->CatchPubScreens)
          {
            if(button=EZReq(0,0,ModePro,GetString(MSG_NEW_PUBSCREEN),GetString(MSG_NEW_PUBSCREEN_BUTTONS),(ULONG)Name))
            {
              if(dnode=AllocDefaultNode(Name))
              {
                dnode->Type=PL_PUBLICSCREENS;
                dnode->ModeSelect=2;
                CloneWB(dnode);
                dnode=ForceEdit(dnode);
              }   
            }
          }
        }
        
        ReleaseSemaphore(&MPSem->ListSem);
        
        ps=0;
        
        if(dnode)
        {
          FreeVec(dnode->PubName);
          dnode->PubName=Name;
          dnode->PubOptions=1;
      
          if(scr=OpenScreenTags(0, SA_Title                 ,Name,
                                   SA_ModeProNode           ,dnode,
                                   TAG_DONE))
          {
            if(ps=OldLockPubScreen(Name,(struct Library *)IntuitionBase))
            {
              //4.53 @8 now clears ON_OPEN flag
              ObtainSemaphore(&MPSem->OpenListSem);
              if(on=FindOpenNode(ps))
              {
                // clear the open flag so MP can close the screen
                on->Flags&=(~ON_OPEN);
              }
              ReleaseSemaphore(&MPSem->OpenListSem);
//          CloseScreen(scr);
            }
          }
          
          dnode->PubName=0;
          dnode->PubOptions=0;
          
          FreeDNode(dnode);
        }      
      }
      ReleaseSemaphore(&LockPubSem);
    }
  }

  DEBUG_CODE(DKP("  RV=0x%08lx\n",ps););

  SetTaskName(tname);
  
  return(ps);
}                          



// 4.53 @9 New patch
void __saveds __asm NewUnlockPubScreen(register __a0 UBYTE *Name, 
                                       register __a1 struct Screen *Scr,
                                       register __a6 struct Library *IBase)
{
  BOOL signal=0;
  struct List *plist;
  struct PubScreenNode *psn;
  struct OpenNode *on;
  char tnamebuffer[52];
  char *tname;
  ULONG stack2=0xc0de0021;
  
  tname=SetupTaskName(tnamebuffer,", ULPS",50);

#ifdef ADD_DEBUG_CODE
  if(MPSem->Debug)
  {
    DKP("UnLockPubScreen(%s,0x%08lx)\n",Name,Scr);
  }
#endif

  OldUnlockPubScreen(Name,Scr,IBase);

  // signal MP, birdie kludge
  Signal((struct Task *)MPTask,1<<PublicSignal);
  
  SetTaskName(tname);
}

/*
struct Screen * __saveds __asm ModeProPubScreen(register __a0 UBYTE *Name)
{
  struct Screen *ps;
  struct DefaultNode *dnode;
  LONG button;
  char tnamebuffer[52];
  char *tname;
  ULONG stack2=0xc0de0022;
  
  tname=SetupTaskName(tnamebuffer,", MPPS",50);

  if(strcmp("Workench",Name)) // Can't f with Workbench!
  {
    ObtainSemaphoreShared(&MPSem->ListSem); 
    ObtainSemaphore(&MPSem->NodeSem);
    
    if(dnode=FindDNode(&MPSem->PromotionList[PL_PUBLICSCREENS],Name))
    {
      if(dnode->Flags & DNF_NEVER_PROMOTE)
        dnode=0;
      else
        dnode=DupDNode(dnode);
       ReleaseSemaphore(&MPSem->NodeSem);    
    }
    else
    {
      ReleaseSemaphore(&MPSem->NodeSem);    
      if(MPSem->CatchPubScreens)
      {
        if(button=EZReq(0,0,ModePro,GetString(MSG_NEW_PUBSCREEN),GetString(MSG_NEW_PUBSCREEN_BUTTONS),(ULONG)Name))
        {
          if(dnode=AllocDefaultNode(Name))
          {
            dnode->Type=PL_PUBLICSCREENS;
            dnode->ModeSelect=2;
            CloneWB(dnode);
            dnode=ForceEdit(dnode);
          }   
        }
      }
    }
    
    ReleaseSemaphore(&MPSem->ListSem);
    
    ps=0;
    
    if(dnode)
    {
      FreeVec(dnode->PubName);
      dnode->PubName=Name;
      dnode->PubOptions=1;
  
      if(scr=OpenScreenTags(0, SA_Title                 ,Name,
                               SA_ModeProNode           ,dnode,
                               TAG_DONE))
      {
        ps=OldLockPubScreen(Name,(struct Library *)IntuitionBase);
      
        CloseScreen(scr);
      }
      
      dnode->PubName=0;
      dnode->PubOptions=0;
      
      FreeDNode(dnode);
    }      
  }
 }
  
  SetTaskName(tname);
  
  return(ps);
}  
*/




/*
 
*/

/*
struct Screen * __saveds __asm NewLockPubScreen(register __a0 UBYTE *Name,
                                                register __a6 struct IntuitionBase *IBase)
{
  struct Screen *ps;
  struct DefaultNode *dnode;
  LONG button;
  char tnamebuffer[52];
  char *tname;
  ULONG stack2=0xc0de0020;
  
  tname=SetupTaskName(tnamebuffer,", LPS",50);



#ifdef ADD_DEBUG_CODE
  if(MPSem->Debug)
  {
    DKP("LockPubScreen(%s)\n",Name);
  }
#endif

  ps=0;
  
  if(0==(ps=OldLockPubScreen(Name,(struct Library *)IntuitionBase))) 
  { // if it fails
    if(strcmp("Workench",Name)) // Can't f with Workbench!
    {
      // 4.53 rewritten so that ModePro opens the pubscreen not the calling task
      struct MsgPort *mport;
      struct MPMessage mpm;
      
      if(mport=CreateMsgPort())
      {
        mpm.mp_Message.mn_ReplyPort=mport;
        mpm.mp_Message.mn_Length=sizeof(mpm);
        mpm.Command = MP_PUBSCREEN;
        mpm.Code    = 0; // Open/Lock
        mpm.Data    = Name;

        PutMsg(MPSem->DaemonPort,(struct Message *)&mpm);
        WaitForReply((struct Message *)&mpm);
        
        ps=OldLockPubScreen(Name);

        mpm.Code    = 1; // Unlock

        PutMsg(MPSem->DaemonPort,(struct Message *)&mpm);
        WaitForReply((struct Message *)&mpm);
        
        DeleteMsgPort(mport);
      }
    }
  }
  
  SetTaskName(tname);
  
  return(ps);
}  

*/