home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / aplusplus-1.01-src.lha / GNU / src / amiga / APlusPlus-1.01 / libsource / WindowCV.cxx < prev    next >
C/C++ Source or Header  |  1994-05-05  |  10KB  |  294 lines

  1. /******************************************************************************
  2.  **
  3.  **    C++ Class Library for the Amiga© system software.
  4.  **
  5.  **    Copyright (C) 1994 by Armin Vogt  **  EMail: armin@uni-paderborn.de
  6.  **    All Rights Reserved.
  7.  **
  8.  **    $Source: apphome:APlusPlus/RCS/libsource/WindowCV.cxx,v $
  9.  **    $Revision: 1.4 $
  10.  **    $Date: 1994/05/05 22:11:19 $
  11.  **    $Author: Armin_Vogt $
  12.  **
  13.  ******************************************************************************/
  14.  
  15.  
  16. extern "C" {
  17. #ifdef __GNUG__
  18. #include <inline/intuition.h>
  19. #include <inline/gadtools.h>
  20. #endif
  21.  
  22. #ifdef __SASC
  23. #include <proto/intuition.h>
  24. #include <proto/gadtools.h>
  25. #endif
  26. }
  27.  
  28. #include <APlusPlus/intuition/WindowCV.h>
  29.  
  30.  
  31. volatile static char rcs_id[] = "$Id: WindowCV.cxx,v 1.4 1994/05/05 22:11:19 Armin_Vogt Exp Armin_Vogt $";
  32.  
  33.  
  34. /*************************************************************************************************
  35.       WindowCV methods
  36.  *************************************************************************************************/
  37.  
  38.  
  39. WindowCV::WindowCV(IntuiObject *owner,AttrList& attrs) : GraphicObject((GraphicObject*)owner,attrs)
  40. {
  41.    ULONG IDCMPflags = 0;
  42.  
  43.    // initialise for safety
  44.    window_rsp = (IntuitionResponder*)NULL;
  45.    AttrManipulator next(intuiAttrs());
  46.    
  47.    _dout("WindowCV::WindowCV("<<status()<<")\n");
  48.    if (next.findTagItem(WCV_SharePortWithWindow))
  49.    {
  50.       // share IDCMP port with another window.
  51.       WindowCV *shareWindow;
  52.  
  53.       if ( (shareWindow = (WindowCV*)(next.data()))->isKindOf(IOTYPE_WINDOWCV) )
  54.       {
  55.          // if the port sharing window has no port, create an own UserPort.
  56.          if (NULL == (window_rsp = shareWindow->getIntuiResponder()))
  57.          {
  58.             cerr << "window to share port with has no port.\n";
  59.          }
  60.          else
  61.          {
  62.             if (next.findTagItem(WA_IDCMP))
  63.             {
  64.                IDCMPflags = next.data();
  65.                next.writeData(0L);   // prevent Intuition from creating a userport for our window
  66.             }            
  67.          }
  68.       }
  69.       else cerr << "WindowCV: object to share port with is no WindowCV type.\n";
  70.    }
  71.    _dout("getting root screen..\n");
  72.  
  73.    ScreenC *screen = (ScreenC*)findRootOfType(IOTYPE_SCREEN);
  74.    if (screen==NULL){ cerr << "FATAL ERROR: no screen available!\n"; return; }
  75.    else
  76.    {
  77.    // make sure that these tags are present in the attribute tag list..
  78.    intuiAttrs().addAttrs(AttrList(WA_CustomScreen,0, WA_IDCMP,0, TAG_END));
  79.    // and initialise them..
  80.    intuiAttrs().updateAttrs(AttrList(WA_CustomScreen,screen->screenPtr(),
  81.             WA_IDCMP,IDCMPflags|=CLASS_CLOSEWINDOW,TAG_END));
  82.    _dout("Root screen found.\n");
  83.  
  84.    // open window
  85.    if (NULL != (wPtr() = OpenWindowTagList(NULL,intuiAttrs()) ) )
  86.    {
  87.       window()->UserData = (BYTE*)this;  // store the covering object in the window structure
  88.       {
  89.          if (window_rsp)   // window uses another intuition responder
  90.          {
  91.             // get the userport from the shared IntuitionResponder and tell him we are sharing
  92.             window()->UserPort = ((IntuitionResponder*)(window_rsp->participate()))->getMsgPort();
  93.             ModifyIDCMP(window(),IDCMPflags);     // now Intuition shall create a windowport
  94.          }
  95.          else if (window()->UserPort)  // create intui rsp only if the window has an IDCMP port.
  96.          {
  97.             /* create own IntuitionResponder for the window userport
  98.              * other windows may share this port but IntuitionResponder class handles this.
  99.              */
  100.             window_rsp = new IntuitionResponder(window()->UserPort);
  101.             if (!APPOK(window_rsp))
  102.                _ierror(OUT_OF_MEMORY);
  103.          }
  104.          else _dout("WindowCV without IDCMP created.\n");
  105.       }
  106.       newsize(NULL);
  107.  
  108.       _dout("WindowCV status = "<<IntuiObject::status()<<endl);
  109.       setIOType(IOTYPE_WINDOWCV);
  110.       _dout("\tWindowCV("<<IntuiObject::status()<<"): object at "<<window()<<" created.\n");
  111.    }
  112.    else _ierror(WINDOWCV_OPENWINDOW_FAILED);
  113.    }
  114. }
  115.  
  116. WindowCV::~WindowCV()
  117. {
  118.    _dout("WindowCV::~WindowCV()\n");
  119.  
  120.    if (window())
  121.    {
  122.       if (window_rsp)   // window may share user port
  123.       {
  124.          // release will reply all messages for our window still in the queue, so forbid sending more
  125.          Forbid();
  126.  
  127.          /* It is explicitly allowed to destruct a WindowCV within a message callback.
  128.          ** But the replying after message processing, done in actionCallback(), must then be inhibited.
  129.          */
  130.          if (window_rsp->msgInProcess)
  131.          {
  132.             GT_ReplyIMsg(window_rsp->msgInProcess);
  133.             window_rsp->msgInProcess = NULL;          //prevent from being replied twice.
  134.             _dout("  msg in process replied.\n");
  135.          }
  136.  
  137.          if (window_rsp->release(window())>0)  // our intuition responder has more participating windows
  138.          {
  139.             window()->UserPort = NULL;   // the shared IDCMP port is still used by other windows!
  140.             ModifyIDCMP(window(),NULL);  // let Intuition close its WindowPort
  141.          }
  142.          Permit();   // our UserPort is gone..
  143.       }
  144.       if ((WindowCV*)window()->UserData==this)
  145.       {
  146.          window()->UserData = NULL;
  147.          _dout("closing window "<<window()<<" ..\n");
  148.          CloseWindow(window());
  149.          _dout("..done\n");
  150.       }
  151.       else cerr << "WindowCV: invalid window pointer!\n";
  152.    }
  153.    _dout("WindowCV::~WindowCV done\n");
  154. }
  155.  
  156. ULONG WindowCV::setAttributes(AttrList& attrs)
  157. {
  158.    AttrIterator next(attrs);
  159.     
  160.     while (next())
  161.     {
  162.         switch (next.tag())
  163.         {
  164.             case WA_Title : 
  165.                 SetWindowTitles(window(),(UBYTE*)next.data(),(UBYTE*)-1);
  166.                 break;
  167.                 
  168.             case WA_ScreenTitle :
  169.                 SetWindowTitles(window(),(UBYTE*)-1,(UBYTE*)next.data());
  170.                 break;
  171.         }
  172.     }        
  173.    
  174.    return GraphicObject::setAttributes(attrs);
  175. }
  176.  
  177. ULONG WindowCV::getAttribute(Tag attr,ULONG& dataStore)
  178. {
  179.    switch (attr)
  180.     {
  181.         case WA_Title : return (dataStore=(ULONG)window()->Title);
  182.         case WA_ScreenTitle : return (dataStore=(ULONG)window()->ScreenTitle); 
  183.         default : return GraphicObject::getAttribute(attr,dataStore);
  184.     }
  185. }
  186.  
  187. void WindowCV::modifyIDCMP(ULONG flags)
  188. {
  189.    ModifyIDCMP(window(),(ULONG)window()->IDCMPFlags|flags);
  190. }
  191.  
  192. void WindowCV::handleIntuiMsg(const IntuiMessageC *msg)
  193.    /* Default IDCMP message handler used with all Window classes in this library.
  194.       Each derived class has to call the inherited WindowCV class ::handleIntuiMsg()
  195.       if it overloads handleIntuiMsg(). This assures that all handleIntuiMsg() methods
  196.       get called and can do their class specific work.
  197.    */
  198. {
  199.    /* This version no longer works with the IDCMPMapper!!! */
  200.    if (msg->getClass()==CLASS_NEWSIZE) newsize(msg);
  201. }
  202.  
  203. void WindowCV::newsize(const IntuiMessageC *dummy)
  204.    /* Has to be called from a derived class NEWSIZE callback.
  205.    */
  206. {
  207.    /* GraphicObject holds the position to the window origin and dimensions of the inner window area.
  208.    */
  209.    setRect( window()->BorderLeft,
  210.             window()->BorderTop,
  211.             window()->Width-1-window()->BorderRight,
  212.             window()->Height-1-window()->BorderBottom);
  213.  
  214. }
  215. /********************* friends of WindowCV *********************************/
  216.  
  217. ostream& operator << (ostream& OS,struct Window *w)
  218. {
  219.    OS << "{"<<w->LeftEdge<<","<<w->TopEdge<<","<<w->Width<<","<<w->Height<<", UserPort at "<<w->UserPort<<"}";
  220.    return OS;
  221. }
  222.  
  223. ostream& operator << (ostream& OS,WindowCV *win)
  224. {
  225.    OS << "WindowCV::window=" << win->window() << endl;
  226.    OS << "window_rsp at "<<win->window_rsp<<endl;
  227.    return OS;
  228. }
  229.  
  230.  
  231. /*************************************************************************************************
  232.       WindowCV::IntuitionResponder methods
  233.  *************************************************************************************************/
  234. IntuitionResponder::IntuitionResponder(struct MsgPort *IPort)
  235.       : SignalResponder(IPort->mp_SigBit,50)
  236. {
  237.    _dout("IntuitionResponder::\n");
  238.    userPort = IPort;
  239.    msgInProcess = NULL;
  240. }
  241.  
  242. IntuitionResponder::~IntuitionResponder()
  243. {
  244.    msgInProcess = NULL;    // indicate userport check.
  245.    userPort = NULL;        // indicate userport no longer available.
  246. }
  247.  
  248. WORD IntuitionResponder::release(Window *win)
  249.    /* unlink a window