home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 5
/
FreshFish_July-August1994.bin
/
bbs
/
gnu
/
aplusplus-1.01-src.lha
/
src
/
amiga
/
aplusplus-1.01
/
libsource
/
WindowCV.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-05
|
10KB
|
294 lines
/******************************************************************************
**
** C++ Class Library for the Amiga© system software.
**
** Copyright (C) 1994 by Armin Vogt ** EMail: armin@uni-paderborn.de
** All Rights Reserved.
**
** $Source: apphome:APlusPlus/RCS/libsource/WindowCV.cxx,v $
** $Revision: 1.4 $
** $Date: 1994/05/05 22:11:19 $
** $Author: Armin_Vogt $
**
******************************************************************************/
extern "C" {
#ifdef __GNUG__
#include <inline/intuition.h>
#include <inline/gadtools.h>
#endif
#ifdef __SASC
#include <proto/intuition.h>
#include <proto/gadtools.h>
#endif
}
#include <APlusPlus/intuition/WindowCV.h>
volatile static char rcs_id[] = "$Id: WindowCV.cxx,v 1.4 1994/05/05 22:11:19 Armin_Vogt Exp Armin_Vogt $";
/*************************************************************************************************
WindowCV methods
*************************************************************************************************/
WindowCV::WindowCV(IntuiObject *owner,AttrList& attrs) : GraphicObject((GraphicObject*)owner,attrs)
{
ULONG IDCMPflags = 0;
// initialise for safety
window_rsp = (IntuitionResponder*)NULL;
AttrManipulator next(intuiAttrs());
_dout("WindowCV::WindowCV("<<status()<<")\n");
if (next.findTagItem(WCV_SharePortWithWindow))
{
// share IDCMP port with another window.
WindowCV *shareWindow;
if ( (shareWindow = (WindowCV*)(next.data()))->isKindOf(IOTYPE_WINDOWCV) )
{
// if the port sharing window has no port, create an own UserPort.
if (NULL == (window_rsp = shareWindow->getIntuiResponder()))
{
cerr << "window to share port with has no port.\n";
}
else
{
if (next.findTagItem(WA_IDCMP))
{
IDCMPflags = next.data();
next.writeData(0L); // prevent Intuition from creating a userport for our window
}
}
}
else cerr << "WindowCV: object to share port with is no WindowCV type.\n";
}
_dout("getting root screen..\n");
ScreenC *screen = (ScreenC*)findRootOfType(IOTYPE_SCREEN);
if (screen==NULL){ cerr << "FATAL ERROR: no screen available!\n"; return; }
else
{
// make sure that these tags are present in the attribute tag list..
intuiAttrs().addAttrs(AttrList(WA_CustomScreen,0, WA_IDCMP,0, TAG_END));
// and initialise them..
intuiAttrs().updateAttrs(AttrList(WA_CustomScreen,screen->screenPtr(),
WA_IDCMP,IDCMPflags|=CLASS_CLOSEWINDOW,TAG_END));
_dout("Root screen found.\n");
// open window
if (NULL != (wPtr() = OpenWindowTagList(NULL,intuiAttrs()) ) )
{
window()->UserData = (BYTE*)this; // store the covering object in the window structure
{
if (window_rsp) // window uses another intuition responder
{
// get the userport from the shared IntuitionResponder and tell him we are sharing
window()->UserPort = ((IntuitionResponder*)(window_rsp->participate()))->getMsgPort();
ModifyIDCMP(window(),IDCMPflags); // now Intuition shall create a windowport
}
else if (window()->UserPort) // create intui rsp only if the window has an IDCMP port.
{
/* create own IntuitionResponder for the window userport
* other windows may share this port but IntuitionResponder class handles this.
*/
window_rsp = new IntuitionResponder(window()->UserPort);
if (!APPOK(window_rsp))
_ierror(OUT_OF_MEMORY);
}
else _dout("WindowCV without IDCMP created.\n");
}
newsize(NULL);
_dout("WindowCV status = "<<IntuiObject::status()<<endl);
setIOType(IOTYPE_WINDOWCV);
_dout("\tWindowCV("<<IntuiObject::status()<<"): object at "<<window()<<" created.\n");
}
else _ierror(WINDOWCV_OPENWINDOW_FAILED);
}
}
WindowCV::~WindowCV()
{
_dout("WindowCV::~WindowCV()\n");
if (window())
{
if (window_rsp) // window may share user port
{
// release will reply all messages for our window still in the queue, so forbid sending more
Forbid();
/* It is explicitly allowed to destruct a WindowCV within a message callback.
** But the replying after message processing, done in actionCallback(), must then be inhibited.
*/
if (window_rsp->msgInProcess)
{
GT_ReplyIMsg(window_rsp->msgInProcess);
window_rsp->msgInProcess = NULL; //prevent from being replied twice.
_dout(" msg in process replied.\n");
}
if (window_rsp->release(window())>0) // our intuition responder has more participating windows
{
window()->UserPort = NULL; // the shared IDCMP port is still used by other windows!
ModifyIDCMP(window(),NULL); // let Intuition close its WindowPort
}
Permit(); // our UserPort is gone..
}
if ((WindowCV*)window()->UserData==this)
{
window()->UserData = NULL;
_dout("closing window "<<window()<<" ..\n");
CloseWindow(window());
_dout("..done\n");
}
else cerr << "WindowCV: invalid window pointer!\n";
}
_dout("WindowCV::~WindowCV done\n");
}
ULONG WindowCV::setAttributes(AttrList& attrs)
{
AttrIterator next(attrs);
while (next())
{
switch (next.tag())
{
case WA_Title :
SetWindowTitles(window(),(UBYTE*)next.data(),(UBYTE*)-1);
break;
case WA_ScreenTitle :
SetWindowTitles(window(),(UBYTE*)-1,(UBYTE*)next.data());
break;
}
}
return GraphicObject::setAttributes(attrs);
}
ULONG WindowCV::getAttribute(Tag attr,ULONG& dataStore)
{
switch (attr)
{
case WA_Title : return (dataStore=(ULONG)window()->Title);
case WA_ScreenTitle : return (dataStore=(ULONG)window()->ScreenTitle);
default : return GraphicObject::getAttribute(attr,dataStore);
}
}
void WindowCV::modifyIDCMP(ULONG flags)
{
ModifyIDCMP(window(),(ULONG)window()->IDCMPFlags|flags);
}
void WindowCV::handleIntuiMsg(const IntuiMessageC *msg)
/* Default IDCMP message handler used with all Window classes in this library.
Each derived class has to call the inherited WindowCV class ::handleIntuiMsg()
if it overloads handleIntuiMsg(). This assures that all handleIntuiMsg() methods
get called and can do their class specific work.
*/
{
/* This version no longer works with the IDCMPMapper!!! */
if (msg->getClass()==CLASS_NEWSIZE) newsize(msg);
}
void WindowCV::newsize(const IntuiMessageC *dummy)
/* Has to be called from a derived class NEWSIZE callback.
*/
{
/* GraphicObject holds the position to the window origin and dimensions of the inner window area.
*/
setRect( window()->BorderLeft,
window()->BorderTop,
window()->Width-1-window()->BorderRight,
window()->Height-1-window()->BorderBottom);
}
/********************* friends of WindowCV *********************************/
ostream& operator << (ostream& OS,struct Window *w)
{
OS << "{"<<w->LeftEdge<<","<<w->TopEdge<<","<<w->Width<<","<<w->Height<<", UserPort at "<<w->UserPort<<"}";
return OS;
}
ostream& operator << (ostream& OS,WindowCV *win)
{
OS << "WindowCV::window=" << win->window() << endl;
OS << "window_rsp at "<<win->window_rsp<<endl;
return OS;
}
/*************************************************************************************************
WindowCV::IntuitionResponder methods
*************************************************************************************************/
IntuitionResponder::IntuitionResponder(struct MsgPort *IPort)
: SignalResponder(IPort->mp_SigBit,50)
{
_dout("IntuitionResponder::\n");
userPort = IPort;
msgInProcess = NULL;
}
IntuitionResponder::~IntuitionResponder()
{
msgInProcess = NULL; // indicate userport check.
userPort = NULL; // indicate userport no longer available.
}
WORD IntuitionResponder::release(Window *win)
/* unlink a window