home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
disk
/
misc
/
dcmp
/
source
/
source.lha
/
req.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-02
|
14KB
|
435 lines
/*---------------------------------------------------*
$Id: req.c,v 1.6 92/11/03 17:16:31 tf Exp $
dcmp_Request() a quick requster hack for dcmp.c,v
This code has been created in haste. So be careful!
*---------------------------------------------------*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>
#include <stdio.h>
#ifndef AUTOSCROLL
#define AUTOSCROLL 0x4000 /* screen is to autoscoll (V36+) */
#endif
static char rcs_id[] = "$Id: req.c,v 1.6 92/11/03 17:16:31 tf Exp $";
/*
* Compile with -D xxxx, where xxxx can be one of those: (default: all of them ;)
*
* #define INFOBOX * an infobox has no visible window border
* #define NICEBORDER * alternative border for the INFOBOX
* #define NICEOPEN * open windows via NiceOpenWindow()
* #define MAGICTEXT * Text() odd lines top-down, even lines bottom-up
*/
#define DETAILPEN (0x0000) /* compatible Intuition rendering pens */
#define BLOCKPEN (0x0001) /* compatible Intuition rendering pens */
#define TEXTPEN (0x0002) /* text on background */
#define SHINEPEN (0x0002) /* bright edge on 3D objects */
#define SHADOWPEN (0x0001) /* dark edge on 3D objects */
#define BACKFILL (0x0003) /* window background */
#ifdef NICEOPEN
extern struct Window *NiceOpenWindow(struct NewWindow *);
extern void NiceCloseWindow(struct Window *);
#endif
UBYTE *ReqWindowTitle= (UBYTE *)"dcmp Request";
struct Screen *ReqScreen= (struct Screen *)NULL;
struct TextAttr ReqTextAttr= {
(STRPTR) "topaz.font", /* ta_Name */
8, /* ta_YSize */
FS_NORMAL, /* ta_Style */
FPF_ROMFONT /* ta_Flags */
};
struct IntuiText ReqGadgetText[2]= {
{ TEXTPEN,BACKFILL,JAM2,4+4,2,&ReqTextAttr,NULL,NULL },
{ TEXTPEN,BACKFILL,JAM2,4+4,2,&ReqTextAttr,NULL,NULL }
};
SHORT ReqBorderPairs0[2][] = {
{ 0,0, 0,11, 1,11, 1,0, 86,0 },
{ 1,11, 86,11, 86,1, 87,0, 87,11 }
};
SHORT ReqBorderPairs1[2][] = {
{ 0,0, 0,11, 1,11, 1,0, 86,0 },
{ 1,11, 86,11, 86,1, 87,0, 87,11 }
};
struct Border ReqBorder0[] = {
{ 0,0,2,0,JAM1,5,(SHORT *)ReqBorderPairs0[0],&ReqBorder0[1] },
{ 0,0,1,0,JAM1,5,(SHORT *)ReqBorderPairs0[1],NULL }
};
struct Border ReqBorder1[] = {
{ 0,0,2,0,JAM1,5,(SHORT *)ReqBorderPairs1[0],&ReqBorder1[1] },
{ 0,0,1,0,JAM1,5,(SHORT *)ReqBorderPairs1[1],NULL }
};
struct Gadget ReqGadget[2]= {
{ NULL, /* NextGadget */
0,0,0,12, /* LeftEdge, TopEdge, Width, Height */
GADGHCOMP, /* Flags */
GADGIMMEDIATE|RELVERIFY, /* Activation */
BOOLGADGET, /* GadgetType */
&ReqBorder0[0],NULL, /* GadgetRender, SelectRender */
&ReqGadgetText[0], /* GadgetText */
NULL,NULL, /* MutualExclude, SpecialInfo */
1L,NULL /* GadgetID, UserData */
},
{ NULL, /* NextGadget */
0,0,0,12, /* LeftEdge, TopEdge, Width, Height */
GADGHCOMP, /* Flags */
GADGIMMEDIATE|RELVERIFY, /* Activation */
BOOLGADGET, /* GadgetType */
&ReqBorder1[0],NULL, /* GadgetRender, SelectRender */
&ReqGadgetText[1], /* GadgetText */
NULL,NULL, /* MutualExclude, SpecialInfo */
0L,NULL /* GadgetID, UserData */
}
};
struct NewWindow ReqNewWindow= {
50,50,80,40, /* LeftEdge, TopEdge, Width, Height */
DETAILPEN,BLOCKPEN, /* DetailPen, BlockPen */
CLOSEWINDOW|GADGETUP|RAWKEY, /* IDCMPFlags */
RMBTRAP|ACTIVATE, /* Flags */
NULL,NULL, /* FirstGadget, CheckMark */
NULL,NULL,NULL, /* Title, Screen, BitMap */
0,0,0,0, /* MinWidth, MinHeight, MaxWidth, MaxHeight */
WBENCHSCREEN /* Type */
};
long dcmp_Request(text, pos, neg)
char *text, *pos, *neg;
{ long whichwitch=0; /* return code */
BOOL done= FALSE;
int ReqTextLines[30];
int i, t, m, c, y;
/*
* If you're already using some of these pointers, then don't forget to
* declare them locally (or as static), because otherwise the global ones
* will be used! Note also that this could crash the system because
* dcmp_Request() closes it's stuff then using the global vectors !
*/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct TextFont *TextFont;
struct Screen *Screen;
struct Window *ReqWindow;
struct RastPort *RastPort;
struct IntuiMessage *IntuiMessage;
if(!text) return(-1L); /* just to be sure */
IntuitionBase= (struct IntuitionBase *)OpenLibrary("intuition.library",LIBRARY_VERSION);
if(!IntuitionBase)
return(-1L);
GfxBase= (struct GfxBase *)OpenLibrary("graphics.library",LIBRARY_VERSION);
if(!GfxBase)
{ CloseLibrary(IntuitionBase);
return(-1L);
}
TextFont= (struct TextFont *)OpenFont(&ReqTextAttr);
if(!TextFont)
{ CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
return(-1L);
}
m=0; /* length (#of chars) in longest text line */
for(i=0,t=0; i<30 && !done; i++)
{ c=0; /* char counter (this line) */
while(text[t]!='\0' && text[t]!='\n') { t++; c++; }
ReqTextLines[i]= c;
if(text[t]=='\0') done= TRUE;
else t++;
if(c>m) m=c;
}
if(i<29) ReqTextLines[i]= (-1);
ReqNewWindow.Width= 20+ m * TextFont->tf_XSize;
ReqNewWindow.Height= 30+ i * (1+ TextFont->tf_YSize);
if(pos && *pos)
{
ReqGadget[0].LeftEdge= 10;
#ifdef NICEBORDER
ReqGadget[0].TopEdge= ReqNewWindow.Height- 17;
#else
ReqGadget[0].TopEdge= ReqNewWindow.Height- 15;
#endif
ReqGadget[0].Width= 2* ReqGadgetText[0].LeftEdge
+ strlen(pos) * TextFont->tf_XSize;
ReqGadgetText[0].IText= pos;
ReqBorderPairs0[0][8]= ReqBorderPairs0[1][2]
= ReqBorderPairs0[1][4] = ReqGadget[0].Width -2;
ReqBorderPairs0[1][6]= ReqBorderPairs0[1][8] = ReqGadget[0].Width -1;
ReqNewWindow.FirstGadget= &ReqGadget[0];
}
if(neg && *neg)
{
ReqGadget[1].Width= 2* ReqGadgetText[1].LeftEdge
+ strlen(neg) * TextFont->tf_XSize;
ReqGadget[1].LeftEdge= ReqNewWindow.Width- ReqGadget[1].Width- 10;
#ifdef NICEBORDER
ReqGadget[1].TopEdge= ReqNewWindow.Height- 17;
#else
ReqGadget[1].TopEdge= ReqNewWindow.Height- 15;
#endif
ReqGadgetText[1].IText= neg;
ReqBorderPairs1[0][8]= ReqBorderPairs1[1][2]
= ReqBorderPairs1[1][4] = ReqGadget[1].Width -2;
ReqBorderPairs1[1][6]= ReqBorderPairs1[1][8] = ReqGadget[1].Width -1;
if(pos && *pos) ReqGadget[0].NextGadget= &ReqGadget[1];
else ReqNewWindow.FirstGadget= &ReqGadget[1];
}
/* calculate window's minimum width (as if there were no text) */
m= 20 + ReqGadget[0].Width + ReqGadget[1].Width + 8;
if(m < 83) m= 83; /* absolute minimum width: 83 */
if(ReqNewWindow.Width < m)
{ ReqNewWindow.Width= m;
if(neg && *neg)
ReqGadget[1].LeftEdge= ReqNewWindow.Width- ReqGadget[1].Width- 10;
}
if(ReqScreen != NULL) Screen= ReqScreen;
/* Find the Screen on which we're going to pop up. */
else
{ ULONG lock= LockIBase(NULL);
Screen= IntuitionBase->ActiveScreen;
UnlockIBase(lock);
if(!Screen || ReqNewWindow.Width > Screen->Width
|| ReqNewWindow.Height > Screen->Height )
{ lock= LockIBase(NULL);
Screen= IntuitionBase->FirstScreen;
UnlockIBase(lock);
while(Screen && (Screen->Flags & WBENCHSCREEN) != WBENCHSCREEN)
Screen= Screen->NextScreen;
if(!Screen || ReqNewWindow.Width > Screen->Width
|| ReqNewWindow.Height > Screen->Height )
{ CloseFont(TextFont);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
return(-1L);
}
}
}
ReqNewWindow.Screen= Screen;
ReqNewWindow.Type= Screen->Flags & SCREENTYPE;
/*
* If we're to open up on an AUTOSCROLL screen it would be very annoying
* for the user to search for our requester... In this case we'll try to
* center our window under the mouse:
*/
if((Screen->Flags & AUTOSCROLL) == AUTOSCROLL)
{ ReqNewWindow.LeftEdge= Screen->MouseX - ReqNewWindow.Width/2;
if(ReqNewWindow.LeftEdge < 0) ReqNewWindow.LeftEdge= 0;
if(ReqNewWindow.LeftEdge + ReqNewWindow.Width > Screen->Width)
ReqNewWindow.LeftEdge= Screen->Width - ReqNewWindow.Width;
ReqNewWindow.TopEdge= Screen->MouseY - ReqNewWindow.Height/2;
if(ReqNewWindow.TopEdge < 0) ReqNewWindow.TopEdge= 0;
if(ReqNewWindow.TopEdge + ReqNewWindow.Height > Screen->Height)
ReqNewWindow.TopEdge= Screen->Height - ReqNewWindow.Height;
}
else /* center our window on this screen */
{ ReqNewWindow.LeftEdge= (Screen->Width- ReqNewWindow.Width)/2;
ReqNewWindow.TopEdge= (Screen->Height- ReqNewWindow.Height)/2;
}
#ifdef INFOBOX
ReqNewWindow.Flags |= BORDERLESS;
#else /* => we are to have a visible window border */
ReqNewWindow.Title= ReqWindowTitle;
ReqNewWindow.Flags |= WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG;
#endif
#ifdef NICEOPEN
ReqWindow= (struct Window *)NiceOpenWindow(&ReqNewWindow);
#else
ReqWindow= (struct Window *)OpenWindow(&ReqNewWindow);
#endif
if(!ReqWindow)
{ CloseFont(TextFont);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
return(-1L);
}
RastPort= ReqWindow->RPort;
SetAPen(RastPort,BACKFILL);
#ifdef INFOBOX
RectFill(RastPort, 0, 0, ReqNewWindow.Width, ReqNewWindow.Height);
#ifdef NICEBORDER
SetAPen(RastPort,SHINEPEN);
Move(RastPort,ReqNewWindow.Width-2,0);
Draw(RastPort,0,0);
Draw(RastPort,0,ReqNewWindow.Height-1);
SetAPen(RastPort,SHADOWPEN);
Move(RastPort,1,ReqNewWindow.Height-1);
Draw(RastPort,ReqNewWindow.Width-1,ReqNewWindow.Height-1);
Draw(RastPort,ReqNewWindow.Width-1,0);
SetAPen(RastPort,SHADOWPEN);
Move(RastPort,ReqNewWindow.Width-5,1);
Draw(RastPort,3,1);
Draw(RastPort,3,ReqNewWindow.Height-2);
SetAPen(RastPort,SHINEPEN);
Move(RastPort,4,ReqNewWindow.Height-2);
Draw(RastPort,ReqNewWindow.Width-4,ReqNewWindow.Height-2);
Draw(RastPort,ReqNewWindow.Width-4,0);
y= 5; /* y-position of the first text line */
#else
SetAPen(RastPort,SHINEPEN);
Move(RastPort,ReqNewWindow.Width-1,0);
Draw(RastPort,0,0);
Draw(RastPort,0,ReqNewWindow.Height-1);
Move(RastPort,1,0);
Draw(RastPort,1,ReqNewWindow.Height-2);
SetAPen(RastPort,SHADOWPEN);
Move(RastPort,1,ReqNewWindow.Height-1);
Draw(RastPort,ReqNewWindow.Width-1,ReqNewWindow.Height-1);
Draw(RastPort,ReqNewWindow.Width-1,0);
Move(RastPort,ReqNewWindow.Width-2,ReqNewWindow.Height-1);
Draw(RastPort,ReqNewWindow.Width-2,1);
y= 6; /* y-position of the first text line */
#endif
#else
RectFill(RastPort, 4, 11, ReqNewWindow.Width-5, ReqNewWindow.Height-3);
y= 11;
#endif
if(ReqNewWindow.FirstGadget) /* we just removed it/them from view */
RefreshGList(ReqNewWindow.FirstGadget, ReqWindow, NULL, -1L);
SetAPen(RastPort,TEXTPEN);
SetBPen(RastPort,BACKFILL);
SetFont(RastPort,TextFont);
#ifdef MAGICTEXT
/* Attention: hacky code! */
for(m=0; m<30 && ReqTextLines[m]>=0; m++); --m; /* get #of lines */
t= (m>0 && m%2)?(m):(m-1); /* skip last line if #of lines even */
{ int d=strlen(text)-ReqTextLines[t]; /* first character, last line */
if((m%2)==0) d-= 1+ReqTextLines[m]; /* skip last (even) line */
y+= (1+ TextFont->tf_YSize);
for(i=0, c=0; i<=m; i+=2, t-=2)
{ Move(RastPort, 10, y+ i*(1+ TextFont->tf_YSize));
Text(RastPort, &text[c], ReqTextLines[i]);
c+= 1+ ReqTextLines[i]; /* skip `\n' character */
c+= 1+ ReqTextLines[i+1]; /* skip next (odd) line */
WaitTOF();
if(t>0)
{ Move(RastPort, 10, y+ t*(1+ TextFont->tf_YSize));
Text(RastPort, &text[d], ReqTextLines[t]);
d-= 1+ ReqTextLines[t-1]; /* skip `\n' character */
d-= 1+ ReqTextLines[t-2]; /* skip previous (even) line */
WaitTOF();
}
}
}
#else
for(i=0, c=0; i<30 && ReqTextLines[i]>=0; i++)
{ y+= (1+ TextFont->tf_YSize);
Move(RastPort, 10,y);
Text(RastPort, &text[c], ReqTextLines[i]);
c+= 1+ ReqTextLines[i]; /* skip `\n' character */
}
#endif
done= FALSE;
while(!done)
{ ULONG class;
USHORT code; /* rawkey code */
struct Gadget *address;
Wait(1L<<ReqWindow->UserPort->mp_SigBit);
while(IntuiMessage= (struct IntuiMessage *)GetMsg(ReqWindow->UserPort))
{ class = IntuiMessage->Class;
code = IntuiMessage->Code;
address = (struct Gadget *)IntuiMessage->IAddress;
ReplyMsg(IntuiMessage);
switch(class)
{ case GADGETUP:
whichwitch= address->GadgetID;
case CLOSEWINDOW:
done= TRUE;
break;
case RAWKEY: /* evaluate rawkey code! no conversion (yet) */
{ switch(code)
{ case 0x43: case 0x44: case 0x15: case 0x31:
whichwitch= 1L; /* ENTER, RETURN, Y, Z */
done= TRUE;
break;
case 0x45: case 0x36: case 0x13: /* ESC, N, R */
whichwitch= 0L;
done= TRUE;
break;
}
}
}
}
}
#ifdef NICEOPEN
NiceCloseWindow(ReqWindow);
#else
CloseWindow(ReqWindow);
#endif
CloseFont(TextFont);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
return(whichwitch);
}