home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------*
- $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);
- }
-