From: Lee_Robert_Willis@cup.portal.com
Newsgroups: comp.sys.amiga.programmer
Subject: Re: idcmp port
Date: Sun, 23 Aug 92 11:16:51 PDT
Organization: The Portal System (TM)
Distribution: world

#ifndef INTUITION_UTILS_H
#define INTUITION_UTILS_H

#include <exec/types.h>
#include <intuition/intuition.h>



/*F:OpenWindowWithSharedUserPort*

------------------------------------------------------------

               OpenWindowWithSharedUserPort

------------------------------------------------------------

Name:          OpenWindowWithSharedUserPort - opens a window with a shared port.
Syntax:        | window = OpenWindowWithSharedPort( nw, port );
               | struct Window    *window;
               | struct NewWindow *nw;
               | struct MsgPort   *port;

Description:   To handle multiple windows within the one application, the
               best method (usually) is to have all the windows share the
               same UserPort.  This way, one can still do a 'WaitPort()'.
               (Otherwise one has to mess with signal bits.)

               In order to force a window to have a specific UserPort, one
               must first create the port (using 'CreatePort()'), and then
               there is a sequence of steps involved in opening the window.
               (This is described in the 1.3 RKM Libraries and Devices manual
               on page 167 "SETTING UP YOUR OWN IDCMP MONITOR TASK AND USER
               PORT")

               'OpenWindowWithSharedPort()' does all the steps after the
               creation of the MsgPort.   All you do is pass in the NewWindow
               structure and the message port, and
               'OpenWindowWithSharedUserPort' will open the window and do
               the UserPort setup.

Note:          Windows opened with this function must be closed using
               'CloseWindowWithSharedUserPort()', NOT 'CloseWindow()'!

See Also:      CloseWindowWithSharedUserPort
Author:        Lee R. Willis
*/

struct Window *OpenWindowWithSharedUserPort( struct NewWindow *nw,
                                             struct MsgPort   *shared );


/*F:CloseWindowWithSharedUserPort*

------------------------------------------------------------

               CloseWindowWithSharedUserPort

------------------------------------------------------------

Name:          CloseWindowWithSharedUserPort - closes a window with a shared port.
Syntax:        | CloseWindowWithSharedPort( w );
               | struct Window *w;
Description:   To handle multiple windows within the one application, the
               best method (usually) is to have all the windows share the
               same UserPort.  This way, one still to a 'WaitPort()' or
               'WaitForMessage()'.  (Otherwise one has to mess with signal
               bits.)

               Closing such a window requires some care, as Intuition normally
               deallocates the UserPort for such a window on closing, and
               since the port is shared, other windows are still using it!
               (This is described in the 1.3 RKM Libraries and Devices manual
               on page 167 "SETTING UP YOUR OWN IDCMP MONITOR TASK AND USER
               PORT")

               'CloseWindowWithSharedUserPort()' does all this for you.

See Also:      OpenWindowWithSharedUserPort
Author:        Lee R. Willis
*/

void CloseWindowWithSharedUserPort( struct Window *w );
   /* Taken from 1.3 RKM:L&D, page 171 'CloseWindowSafely' */

#endif

/*-=-=--=-=-=--=-=-=--=-=-=--=-=-=--=-=-=--=-=-=--=-=-=--=-=-=--=-=-=--=*/

#include "Intuition_utils.h"
#ifdef LATTICE
#include <proto/all.h>
#endif


struct Window *OpenWindowWithSharedUserPort( struct NewWindow *nw,
                                             struct MsgPort   *shared )
{
   ULONG IDCMPbuf;
   struct Window *w;

   IDCMPbuf       = nw->IDCMPFlags;
   nw->IDCMPFlags = 0;  /* no IDCMP flags. */

   if (w = OpenWindow( nw ))
   {
      w->UserPort = shared;         /* assign UserPort. */
      ModifyIDCMP( w, IDCMPbuf );   /* turn on IDCMP    */
   }
   nw->IDCMPFlags = IDCMPbuf; /* return 'nw' to its previous state. */
   return w;
}


void StripIntuiMessages( struct Window *w )
/*
   *ASSUMES* a Forbid() has been called!

   Taken from 1.3 RKM:L&D, page 171
*/
{
   struct MsgPort *mp;
   struct IntuiMessage *msg, *succ;

   mp = w->UserPort;

   /*
    * Loop through all messages waiting at this port, remove any
    * which are for Window 'w'.
    */

   msg = (struct IntuiMessage*) mp->mp_MsgList.lh_Head;
   while( succ = (struct IntuiMessage*) msg->ExecMessage.mn_Node.ln_Succ )
   {
      if (msg->IDCMPWindow == w)
      {
         Remove((struct Node *) msg);
         ReplyMsg((struct Message *) msg);
      }

      msg = succ;
   }
}

void CloseWindowWithSharedUserPort( struct Window *w )
   /* Taken from 1.3 RKM:L&D, page 171, 'CloseWindowSafely()' */
{
   Forbid();               /* Turn off multitasking */

   StripIntuiMessages( w );  /* remove all messages for this window. */

   w->UserPort = NULL;
   ModifyIDCMP( w, 0 ); /* prevents new messages from occuring. */
   Permit();

   CloseWindow( w );
}
Newsgroups: comp.sys.amiga.programmer