home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
coders
/
iffconverter
/
handleintuimessages.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-07
|
19KB
|
547 lines
/*
** $VER: HandleIntuiMessage.c V0.01 (14-06-95)
**
** Author: Gerben Venekamp
** Updates: 14-06-95 Version 0.01 Initial module
**
** HandleIntuiMessages.c waits for a message and acts accordingly to it.
**
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include "IFFConverter.h"
#define MouseCoordsTextX 140L
#define MouseCoordsTextY 1L
// Defining Variables
BOOL PictureValid = FALSE;
BOOL Clipping = FALSE;
BOOL ChangeActivationWindow = TRUE;
BOOL DrawHairCross;
enum ByteBoundry ByteBoundry = BB_None; // initialise with default value.
UWORD PicWidth;
UWORD PicHeight;
UWORD PicDepth;
ULONG PicSize;
// This is a structure, because we need to pass these variables to another module.
IFFClip_s IFFClip;
// Set 'OldClipLeft' to a value < 0, so when drawing the clip rectangle
// for the first time, we don't REMOVE the rectangle. Because none
// has been drawn.
WORD OldClipLeft = -1;
WORD OldClipTop;
WORD OldClipRight;
WORD OldClipBottom;
// Same here for 'OldMouseX' as 'OldClipLeft' above. Just that it is
// for the hot cursor point cross.
WORD OldMouseX = -1;
WORD OldMouseY;
UBYTE *MouseCoords;
char NoMouseCoords[] = "---- × ----"; // String length should be exactly the same as in IText_MouseCoords
struct IntuiText IText_MouseCoords = {
1, 2,
JAM2,
0, 0,
NULL,
"---- × ----",
NULL,
};
// Defining protos
void HandleIntuiMessages(void);
void HandleClipping_Mouse(WORD, WORD);
void HandleClipping_Gadget(void);
void DrawClipRect(struct RastPort *, UWORD, UWORD, UWORD, UWORD);
void DrawCross(struct RastPort *, UWORD, UWORD);
void MakeByteBoundry(WORD *, BOOL);
void UpdateClipping(void);
/*
** HandleIntuiMessages()
**
** Waits for an events to happen. This done through the Wait(...)
** call. If a signal comes in, 'HandleIntuiMessages' gets the message
** associated with the signal from the right messageport. The signal
** can come from either the 'PanelWindow' or 'ViewWindow'. The same
** code is used to handle the message from both screens. This is SAVE,
** because all messages generated by the 'ViewWindow' are shared by
** the 'PanelWindow'. The additional messages generated by the
** 'PanelWindow' are only generated by pressing gadgets. These
** gadgets ONLY appear on the 'PanelWindow'.
**
** pre: None.
** post: None.
**
*/
void HandleIntuiMessages()
{
BOOL ExitLoop = FALSE;
BOOL PanelInFront = TRUE;
BOOL RemoveInfoWindow;
ULONG Signals;
ULONG PanelSignal = 1L << PanelWindow->UserPort->mp_SigBit;
ULONG ViewSignal = 1L << ViewWindow ->UserPort->mp_SigBit;
ULONG InfoSignal = NULL;
struct IntuiMessage *ConverterMessage = NULL;
SavePicStruct_t PictureToSave;
// Make 'MouseCoords' point to the right text.
MouseCoords = IText_MouseCoords.IText;
// Print the mouse coordinates one time. This is because when we
// startup, no picture is loaded and 'PrintIText' inside
// 'case IDCMP_MOUSEMOVE:' will never be called, until a good picture
// is loaded.
PrintIText(&(PanelScreen->RastPort), &IText_MouseCoords, MouseCoordsTextX, MouseCoordsTextY);
do {
Signals = Wait(PanelSignal | ViewSignal | InfoSignal);
RemoveInfoWindow = FALSE;
do {
if( Signals & PanelSignal ) // Check if 'PanelWindow' sent the message.
ConverterMessage = GT_GetIMsg(PanelWindow->UserPort);
else
if( Signals & ViewSignal ) // Check if 'ViewWindow' sent the message.
ConverterMessage = GT_GetIMsg(ViewWindow->UserPort);
else
if( Signals & InfoSignal ) // Check if 'InfoWindow' sent the message.
ConverterMessage = GT_GetIMsg(InfoWindow->UserPort);
if(ConverterMessage ) // Did a valid message appear?
{
switch( ((struct Gadget *) ConverterMessage->IAddress)->GadgetID )
{
LONG TempLong, TempLong2;
case GD_Quit:
FadeColours( FADE_DOWN, 320, ViewScreen );
ExitLoop = TRUE;
break;
case GD_Load:
CloseThisWindow(&InfoWindow);
InfoSignal = NULL;
PositionScreen(PanelScreen, 0, 12);
GetGadgetStatus(GD_FileMode, GTCY_Active, &TempLong,
TAG_DONE);
LoadPicture( (enum FileModeType) TempLong);
PositionScreen(PanelScreen, PubScreenHeight-PanelHeight, 12);
PrintIText( &(PanelScreen->RastPort), &IText_MouseCoords, MouseCoordsTextX, MouseCoordsTextY );
break;
case GD_Save:
CloseThisWindow(&InfoWindow);
InfoSignal = NULL;
PositionScreen(PanelScreen, 0, 12);
GetGadgetStatus(GD_FileMode, GTCY_Active, &TempLong,
TAG_DONE);
GetGadgetStatus(GD_RenderMode, GTCY_Active, &TempLong2,
TAG_DONE);
SavePicture( &PictureToSave );
// SavePicture(struct Screen *, enum FileModeType, enum RenderModeType, IFFClip_s *);
PositionScreen(PanelScreen, PubScreenHeight-PanelHeight, 12);
PrintIText(&(PanelScreen->RastPort), &IText_MouseCoords, MouseCoordsTextX, MouseCoordsTextY);
break;
case GD_ClipWidth:
GetGadgetStatus(GD_ClipWidth, GTIN_Number, &TempLong,
TAG_DONE);
if(TempLong != 0)
{
if( TempLong >= 1 )
IFFClip.ClipWidth = TempLong - 1;
else
IFFClip.ClipWidth = TempLong + 1;
HandleClipping_Gadget();
}
break;
case GD_ClipHeight:
GetGadgetStatus(GD_ClipHeight, GTIN_Number, &TempLong,
TAG_DONE);
if(TempLong != 0)
{
if( TempLong >= 1 )
IFFClip.ClipHeight = TempLong - 1;
else
IFFClip.ClipHeight = TempLong + 1;
HandleClipping_Gadget();
}
break;
case GD_ClipLeft:
GetGadgetStatus(GD_ClipLeft, GTIN_Number, &TempLong,
TAG_DONE);
IFFClip.ClipWidth = IFFClip.ClipWidth - TempLong + IFFClip.ClipLeft;
IFFClip.ClipLeft = TempLong;
HandleClipping_Gadget();
break;
case GD_ClipTop:
GetGadgetStatus(GD_ClipTop, GTIN_Number, &TempLong,
TAG_DONE);
IFFClip.ClipHeight = IFFClip.ClipHeight - TempLong + IFFClip.ClipTop;
IFFClip.ClipTop = TempLong;
HandleClipping_Gadget();
break;
case GD_DrawCross:
GetGadgetStatus(GD_DrawCross, GTCB_Checked, &TempLong,
TAG_DONE);
DrawHairCross = (BOOL)TempLong;
break;
case GD_Info:
InfoSignal = DisplayInfo();
break;
case GD_ByteBoundry:
GetGadgetStatus(GD_ByteBoundry, GTMX_Active, &ByteBoundry,
TAG_DONE);
break;
}
switch(ConverterMessage->Class)
{
case IDCMP_MOUSEMOVE:
if( ((PanelWindow->MouseY < 0) || Clipping) && PictureValid )
{
WORD MouseX = ViewWindow->MouseX;
WORD MouseY = ViewWindow->MouseY;
MakeByteBoundry( &MouseX, Clipping );
if(MouseX < 0 ) MouseX = 0;
if(MouseX >= PicWidth ) MouseX = PicWidth-1;
if(MouseY < 0 ) MouseY = 0;
if(MouseY >= PicHeight) MouseY = PicHeight-1;
MakeDecimal(MouseX, MouseCoords, 4);
MakeDecimal(MouseY, MouseCoords+7, 4);
PrintIText(&(PanelScreen->RastPort), &IText_MouseCoords, MouseCoordsTextX, MouseCoordsTextY);
if( !Clipping )
{
if( OldMouseX >= 0 )
DrawCross( &(ViewScreen->RastPort), OldMouseX, OldMouseY );
DrawCross( &(ViewScreen->RastPort), MouseX, MouseY );
OldMouseX = MouseX;
OldMouseY = MouseY;
}
else
HandleClipping_Mouse( MouseX, MouseY );
}
else
{
UWORD i;
UBYTE *copy1 = MouseCoords;
UBYTE *copy2 = NoMouseCoords;
for(i=0; i<sizeof(NoMouseCoords); i++)
*copy1++ = *copy2++;
PrintIText(&(PanelScreen->RastPort), &IText_MouseCoords, MouseCoordsTextX, MouseCoordsTextY);
if( OldMouseX >= 0 )
DrawCross( &(ViewScreen->RastPort), OldMouseX, OldMouseY );
OldMouseX = -1;
}
break;
case IDCMP_MOUSEBUTTONS:
if( ConverterMessage->Code == IECODE_RBUTTON )
{
ULONG register ScreenDepthFlag;
if( PanelInFront )
ScreenDepthFlag = SDEPTH_TOBACK;
else
ScreenDepthFlag = SDEPTH_TOFRONT;
ScreenDepth(PanelScreen, ScreenDepthFlag | SDEPTH_INFAMILY, NULL);
PanelInFront = !PanelInFront;
}
if( (ConverterMessage->Code == IECODE_LBUTTON) && PictureValid )
{
if( PanelWindow->MouseY < 0 )
{
IFFClip.ClipPointX = ViewWindow->MouseX;
IFFClip.ClipPointY = ViewWindow->MouseY;
Clipping = TRUE;
DrawCross( &(ViewScreen->RastPort), OldMouseX, OldMouseY );
HandleClipping_Mouse( IFFClip.ClipPointX, IFFClip.ClipPointY );
}
}
else
if( ConverterMessage->Code == (IECODE_LBUTTON | IECODE_UP_PREFIX) )
{
if( Clipping == TRUE )
{
OldMouseX = ViewWindow->MouseX;
OldMouseY = ViewWindow->MouseY;
DrawCross( &(ViewScreen->RastPort), OldMouseX, OldMouseY );
}
Clipping = FALSE;
}
break;
case IDCMP_ACTIVEWINDOW:
RemoveInfoWindow = TRUE;
break;
} // END switch
} // END if
GT_ReplyIMsg(ConverterMessage);
} while (ConverterMessage); // More messages?
if( RemoveInfoWindow )
{
CloseThisWindow(&InfoWindow);
InfoSignal = NULL;
}
} while (!ExitLoop); // Loop until exit.
}
/*
** HandlClipping_Mouse(MouseX, MouseY)
**
** Handle clipping when the mouse moved.
**
** pre: MouseX, MouseY - Current x,y coordinates of the mouse.
** post: None.
**
*/
void HandleClipping_Mouse(register WORD MouseX, register WORD MouseY)
{
if(MouseX < 0 ) MouseX = 0;
if(MouseX >= PicWidth ) MouseX = PicWidth-1;
if(MouseY < 0 ) MouseY = 0;
if(MouseY >= PicHeight) MouseY = PicHeight-1;
if( MouseX >= IFFClip.ClipPointX )
IFFClip.ClipLeft = IFFClip.ClipPointX;
else
IFFClip.ClipLeft = MouseX;
if( MouseY >= IFFClip.ClipPointY )
IFFClip.ClipTop = IFFClip.ClipPointY;
else
IFFClip.ClipTop = MouseY;
if( (IFFClip.ClipWidth = MouseX - IFFClip.ClipPointX) < 0 )
IFFClip.ClipWidth = -IFFClip.ClipWidth;
if( (IFFClip.ClipHeight = MouseY - IFFClip.ClipPointY) < 0 )
IFFClip.ClipHeight = -IFFClip.ClipHeight;
IFFClip.ClipSize = ((IFFClip.ClipWidth + 8) >> 3) * (IFFClip.ClipHeight + 1) * PicDepth;
UpdateClipping();
}
/*
** HandleClipping_Gadget()
**
** Handle all clipping when one or more of the clipping gadgets has changed.
**
** pre: None.
** post: None.
**
*/
void HandleClipping_Gadget()
{
// Check if 'ClipWidth' is negative.
if( IFFClip.ClipWidth < 0 )
{
// Negative 'ClipWidth' makes little sence, so make it postive
// and adjust 'ClipLeft' to compensate for negative width.
IFFClip.ClipWidth = -IFFClip.ClipWidth;
IFFClip.ClipLeft = IFFClip.ClipLeft - IFFClip.ClipWidth;
}
// Check if 'ClipHeight' is negative.
if( IFFClip.ClipHeight < 0 )
{
// Negative 'ClipHeight' makes little sence, so make it postive
// and adjust 'ClipTop' to compensate for negative height.
IFFClip.ClipHeight = -IFFClip.ClipHeight;
IFFClip.ClipTop = IFFClip.ClipTop - IFFClip.ClipHeight;
}
if( IFFClip.ClipLeft < 0 )
// 'ClipLeft' cannot be smaller than 0! So, when nagative, make it 0.
IFFClip.ClipLeft = 0;
else
if( IFFClip.ClipLeft >= PicWidth )
// 'ClipLeft' cannot be greater than 'PicWidth'.
IFFClip.ClipLeft = PicWidth - 1;
if( IFFClip.ClipTop < 0 )
// 'ClipTop' cannot be negative. Make it 0.
IFFClip.ClipTop = 0;
else
if( IFFClip.ClipTop >= PicHeight )
// 'ClipTop' cannot be greater than 'PicHeight'.
IFFClip.ClipTop = PicHeight - 1;
// See whether 'ClipWidth' and 'ClipHeight' still fits the screen boundry.
if( (IFFClip.ClipWidth + IFFClip.ClipPointX) > PicWidth )
IFFClip.ClipWidth = PicWidth - IFFClip.ClipLeft - 1;
if( (IFFClip.ClipHeight + IFFClip.ClipPointY) > PicHeight )
IFFClip.ClipHeight = PicHeight - IFFClip.ClipTop - 1;
IFFClip.ClipSize = ((IFFClip.ClipWidth + 8) >> 3) * (IFFClip.ClipHeight + 1) * PicDepth;
UpdateClipping();
}
/*
** UpdateClipping()
**
** 'UpdateClipping' preforms a total update of the clipping. This
** means that the old Clip rectangle is ereased and the new one
** drawn. Also, the gadget containing size and offset, are updated.
**
** pre: None.
** post: None.
**
*/
void UpdateClipping()
{
UpdateDimensions(GD_ClipLeft, IFFClip.ClipLeft,
GD_ClipTop, IFFClip.ClipTop,
GD_ClipWidth, IFFClip.ClipWidth + 1,
GD_ClipHeight, IFFClip.ClipHeight + 1,
GD_ClipSize, IFFClip.ClipSize,
GD_Sentinal);
if( OldClipLeft >= 0 )
DrawClipRect( &(ViewScreen->RastPort), OldClipLeft, OldClipTop, OldClipRight, OldClipBottom );
DrawClipRect( &(ViewScreen->RastPort), IFFClip.ClipLeft, IFFClip.ClipTop, IFFClip.ClipLeft + IFFClip.ClipWidth, IFFClip.ClipTop + IFFClip.ClipHeight );
OldClipLeft = IFFClip.ClipLeft;
OldClipTop = IFFClip.ClipTop;
OldClipRight = IFFClip.ClipLeft + IFFClip.ClipWidth;
OldClipBottom = IFFClip.ClipTop + IFFClip.ClipHeight;
}
/*
** DrawClipRect(rp, X1, Y1, X2, Y2)
**
** Draws a rectangle.
**
** pre: rp - pointer to the destination RastPort.
** X1, Y1 - x, y coordinates of rectangle.
** X2, Y2 - x, y coordinates of rectangle.
** post: None.
**
*/
void DrawClipRect(struct RastPort *rp, UWORD X1, UWORD Y1, UWORD X2, UWORD Y2)
{
register UBYTE ViewDrawMode = GetDrMd( &(ViewScreen->RastPort) );
SetDrMd( &(ViewScreen->RastPort), COMPLEMENT );
Move(rp, X1, Y1);
Draw(rp, X2, Y1);
Draw(rp, X2, Y2);
Draw(rp, X1, Y2);
Draw(rp, X1, Y1);
SetDrMd( &(ViewScreen->RastPort), ViewDrawMode );
}
/*
** DrawCross(rp, X, Y)
**
** Draw a cross to indicate the cursor hot point.
**
** pre: rp- pointer to the destination RastPort
** X, Y - x, y coordinates of cursor hot point.
** post: None.
**
*/
void DrawCross(struct RastPort *rp, UWORD X, UWORD Y)
{
register UBYTE ViewDrawMode;
if( DrawHairCross )
{
ViewDrawMode = GetDrMd( &(ViewScreen->RastPort) );
SetDrMd( &(ViewScreen->RastPort), COMPLEMENT );
Move(rp, 0, Y);
Draw(rp, (ViewScreen->Width) - 1, Y);
Move(rp, X, 0);
Draw(rp, X, (ViewScreen->Height) - 1);
SetDrMd( &(ViewScreen->RastPort), ViewDrawMode );
}
}
/*
** MakeByteBoundry( coord )
**
** Depending on the type of Boundry coord gets a new value.
** There are several different Boundry types:
** None - No changes to coord.
** Type 1 - The width of the clip reagon is a multple of 8.
** Type 2 - The left coordinate of the clip reagon is a multiple of 8.
** Type 3 - The left and width of the clip reagon are both a multiple of 8.
**
** pre: coord - Pixel values.
** post: coord - Pixel values according to ByteBoundry.
**
*/
void MakeByteBoundry(WORD *coord, BOOL Clipping)
{
switch( ByteBoundry )
{
case BB_Type1:
*coord = (*coord +7) & 0xfff8;
case BB_Type2:
if( Clipping )
*coord = (*coord +7) & 0xfff8;
case BB_Type3:
break;
}
}