Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / reqtools / req.c
blob5e6e9e3b64b61ec5a447f4763df973e88d8c94fb
2 #include <exec/types.h>
3 #include <exec/io.h>
4 #include <exec/memory.h>
5 #include <intuition/intuition.h>
6 #include <intuition/intuitionbase.h>
7 #include <intuition/sghooks.h>
8 #include <intuition/imageclass.h>
9 #include <libraries/dos.h>
10 #include <libraries/gadtools.h>
11 #include <libraries/reqtools.h>
12 #include <proto/exec.h>
13 #include <proto/gadtools.h>
14 #include <proto/graphics.h>
15 #include <proto/intuition.h>
16 #include <proto/utility.h>
17 #include <proto/reqtools.h>
18 #include <string.h>
20 #include "filereq.h"
23 #include "rtlocale.h"
25 /****************************************************************************************/
27 #ifndef __AROS__
29 #ifdef __SASC
30 #pragma libcall ReqToolsBase rtLockPrefs a8 00
31 #pragma libcall ReqToolsBase rtUnlockPrefs ae 00
32 #else
33 #warning You might have to fix rtLockPrefs/rtUnlockPrefs for your compiler
34 #endif
36 #endif
38 /****************************************************************************************/
40 #define ThisProcess() ( ( struct Process * ) FindTask( NULL ) )
42 /****************************************************************************************/
44 struct PWCallBackArgs
46 char *buffer;
47 ULONG lastchecksum, verify, retcode;
50 /****************************************************************************************/
52 extern ULONG ASM LoopReqHandler (ASM_REGPARAM(a1, struct rtHandlerInfo *,));
53 extern void REGARGS SetWinTitleFlash (struct Window *, char *);
54 extern void ShortDelay (void);
55 extern ULONG ASM myTextLength (ASM_REGPARAM(a1, char *,),
56 ASM_REGPARAM(a0, struct TextAttr *,),
57 ASM_REGPARAM(a3, UBYTE *,),
58 ASM_REGPARAM(a2, struct Image *,),
59 ASM_REGPARAM(d7, ULONG,));
61 extern struct ReqToolsBase *ReqToolsBase;
62 extern struct DosLibrary *DOSBase;
63 extern struct IntuitionBase *IntuitionBase;
64 extern struct Library *GadToolsBase;
65 extern struct GfxBase *GfxBase;
67 /****************************************************************************************/
69 struct FmtBuff
71 long numlines, bufflen;
74 #define DOFMT_COUNTNEWLINES 0
75 #define DOFMT_COUNTBARS 1
77 /****************************************************************************************/
80 extern APTR ASM DofmtCount (ASM_REGPARAM(a0, char *,),
81 ASM_REGPARAM(a1, APTR,),
82 ASM_REGPARAM(a3, struct FmtBuff *,),
83 ASM_REGPARAM(d0, int,));
84 extern APTR STDARGS DofmtArgs (char *, char *,...);
87 extern void ASM FillBarTable (ASM_REGPARAM(a1, char **,), ASM_REGPARAM(a0, char *,));
88 extern void ASM FillNewLineTable (ASM_REGPARAM(a1, char **,), ASM_REGPARAM(a0, char *,));
90 /****************************************************************************************/
92 typedef struct Req_RealHandlerInfo Req_GlobData;
93 #define STRINGGADID 32
95 struct Req_RealHandlerInfo
97 ULONG (*func)(); /* private */
98 ULONG WaitMask;
99 ULONG DoNotWait;
101 /* PRIVATE */
102 char **gadstrbuff, **buff, *stringbuff, *textfmt;
103 struct PWCallBackArgs arg;
104 struct Gadget *strgad, *yesgad, *nogad, *retgad, *selgad;
105 struct TextAttr boldattr;
106 struct KeyButtonInfo buttoninfo;
107 struct StringInfo *strinfo;
108 struct Screen *scr, *frontscr;
109 struct Window *prwin;
110 struct Window *reqwin;
111 struct DrawInfo *drinfo;
112 struct rtReqInfo *reqinfo;
113 struct Hook *imsghook, backfillhook;
114 struct TextFont *reqfont;
115 struct Catalog *catalog;
116 struct Image headimg;
117 struct NewWindow newreqwin;
118 struct FmtBuff bodyfmt, gadfmtbuff;
119 UBYTE minmaxstr[30];
120 int idcmp, mode, min, max, checksum, pubscr, reqflags;
121 int retnum, waitpointer, allowempty, lockwindow, shareidcmp, noscreenpop;
122 int textht, texttop, strgadht, strgadtop, width, nowinbackfill;
123 int numlines, len, fontht, minmax, minmaxlen, minmaxtop, minmaxleft;
124 int fkeys;
125 APTR winlock, visinfo;
126 ULONG *value, *lenptr;
129 /****************************************************************************************/
131 static UWORD pattern[] = { 0xAAAA,0x5555 };
133 static ULONG REGARGS ReqExit (Req_GlobData *, int);
134 static struct Image * REGARGS CreateRectImage
135 (Req_GlobData *, struct Image *, int, int, int, int, int, int);
136 static ULONG ASM SAVEDS myReqHandler (REGPARAM(a1, Req_GlobData *,),
137 REGPARAM(d0, ULONG,),
138 REGPARAM(a0, struct TagItem *,));
140 /****************************************************************************************/
142 #define GETSTRINGLONG_FLAGS (GSREQF_CENTERTEXT|GSREQF_HIGHLIGHTTEXT)
143 #define EZREQ_FLAGS (EZREQF_NORETURNKEY|EZREQF_LAMIGAQUAL|EZREQF_CENTERTEXT)
146 /****************************************************************************************/
148 ULONG ASM SAVEDS GetString (
149 REGPARAM(a1, UBYTE *, stringbuff), /* str in case of rtEZRequestA */
150 REGPARAM(d0, LONG, maxlen), /* args in case of rtEZRequestA */
151 REGPARAM(a2, char *, title), /* gadfmt in case of rtEZRequestA */
152 REGPARAM(d1, ULONG, checksum),
153 REGPARAM(d2, ULONG *, value),
154 REGPARAM(d3, LONG, mode),
155 REGPARAM(d4, struct rtReqInfo *, reqinfo),
156 REGPARAM(a0, struct TagItem *, taglist))
158 /* #define CLEARSIZE (28+sizeof(struct NewWindow)+sizeof(struct IntuiText)+\
159 sizeof(struct NewGadget)+2*sizeof(struct FmtBuff)) */
161 /* keep these vars together and just BEFORE NewWindow struct! */
162 /*-------------------------------------------------*/
163 int reqpos = REQPOS_DEFAULT;
164 char *pubname = NULL;
165 ULONG underscore = 0;
166 struct TextAttr *fontattr = NULL;
167 struct Locale *locale = NULL;
168 struct IntuiText itxt, *bodyitxt = NULL;
169 struct NewGadget ng;
170 struct Image *img;
171 /**/
172 /* KEEP MIN AND MAX IN THIS ORDER !!!! */
173 int max = MAXINT, min = MININT;
174 /**/
175 Req_GlobData *glob;
176 struct Gadget *gad;
177 struct TagItem *tag;
178 const struct TagItem *tstate;
179 /* for rtEZRequestA */
180 char *gadfmt = title;
181 char *ptr;
182 int val, spacing, reqhandler = FALSE, nogadfmt, gadlen = 0;
183 int height, top, showdef = TRUE;
184 int scrwidth, scrheight, i, j, npos, nlen, nogadgets, retnum;
185 int invisible, scrfontht, gadlines = 0;
186 int leftoff, rightoff;
187 ULONG *gadlenptr = NULL, *gadposptr = NULL, idcmpflags;
188 APTR gadfmtargs = NULL, textfmtargs = NULL, args;
190 memset (&itxt, 0, sizeof (struct IntuiText));
191 memset (&ng, 0, sizeof (struct NewGadget));
193 if (!(glob = AllocVec (sizeof (Req_GlobData), MEMF_PUBLIC | MEMF_CLEAR)))
194 return (FALSE);
196 glob->mode = mode;
197 glob->checksum = checksum;
198 glob->value = value;
199 glob->stringbuff = stringbuff;
200 glob->fkeys = rtLockPrefs()->Flags & RTPRF_FKEYS;
201 rtUnlockPrefs();
203 nogadfmt = (mode != IS_EZREQUEST);
204 invisible = (mode <= ENTER_PASSWORD);
206 if (mode == IS_EZREQUEST) title = NULL;
207 if (mode == ENTER_STRING) glob->width = 350; else glob->width = 180;
208 retnum = 1;
209 if ((glob->reqinfo = reqinfo))
211 if (reqinfo->Width) glob->width = reqinfo->Width;
212 if (reqinfo->ReqTitle) title = reqinfo->ReqTitle;
213 if (reqinfo->ReqPos != REQPOS_DEFAULT) reqpos = reqinfo->ReqPos;
215 glob->newreqwin.LeftEdge = reqinfo->LeftOffset;
216 glob->newreqwin.TopEdge = reqinfo->TopOffset;
217 glob->reqflags = reqinfo->Flags;
218 glob->waitpointer = reqinfo->WaitPointer;
219 glob->lockwindow = reqinfo->LockWindow;
220 glob->shareidcmp = reqinfo->ShareIDCMP;
221 glob->imsghook = reqinfo->IntuiMsgFunc;
224 /* parse tags */
225 tstate = taglist;
226 while ((tag = NextTagItem (&tstate)))
228 IPTR tagdata = tag->ti_Data;
229 if (tag->ti_Tag > RT_TagBase)
231 switch (tag->ti_Tag)
233 case RT_Window: glob->prwin = (struct Window *)tagdata; break;
234 case RT_IDCMPFlags: glob->idcmp = tagdata; break;
235 case RT_ReqPos: reqpos = tagdata; break;
236 case RT_LeftOffset: glob->newreqwin.LeftEdge = tagdata; break;
237 case RT_TopOffset: glob->newreqwin.TopEdge = tagdata; break;
238 case RT_PubScrName: pubname = (char *)tagdata; break;
239 case RT_Screen: glob->scr = (struct Screen *)tagdata; break;
240 case RT_ReqHandler: *(APTR *)tagdata = glob;
241 reqhandler = TRUE;
242 break;
243 case RT_WaitPointer: glob->waitpointer = tagdata; break;
244 case RT_Underscore: underscore = tagdata; break;
245 case RT_ShareIDCMP: glob->shareidcmp = tagdata; break;
246 case RT_LockWindow: glob->lockwindow = tagdata; break;
247 case RT_ScreenToFront: glob->noscreenpop = !tagdata; break;
248 case RT_TextAttr: fontattr = (struct TextAttr *)tagdata; break;
249 case RT_IntuiMsgFunc: glob->imsghook = (struct Hook *)tagdata; break;
250 case RT_Locale: locale = (struct Locale *)tagdata; break;
251 case RTEZ_ReqTitle: if (mode == IS_EZREQUEST) title = (char *)tagdata;
252 break;
253 /* RTGS_Flags == RTGL_Flags == RTEZ_Flags */
254 case RTEZ_Flags: glob->reqflags = tagdata; break;
255 case RTEZ_DefaultResponse: retnum = tagdata; break;
256 case RTGL_Min: min = tagdata; glob->minmax = TRUE; break;
257 case RTGL_Max: max = tagdata; glob->minmax = TRUE; break;
258 /* RTGS_Width == RTGL_Width */
259 case RTGL_Width: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
260 glob->width = tagdata;
261 break;
262 case RTGL_ShowDefault: showdef = tagdata; break;
263 /* RTGS_GadFmt == RTGL_GadFmt */
264 case RTGL_GadFmt: nogadfmt = FALSE;
265 gadfmt = (char *)tagdata;
266 break;
267 /* RTGS_GadFmtArgs == RTGL_GadFmtArgs */
268 case RTGL_GadFmtArgs: gadfmtargs = (APTR)tagdata; break;
269 /* RTGS_Invisible == RTGL_Invisible */
270 case RTGL_Invisible: invisible = tagdata; break;
271 /* RTGS_BackFill == RTGL_BackFill */
272 case RTGL_BackFill: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
273 glob->nowinbackfill = !tagdata;
274 break;
275 /* RTGS_TextFmt == RTGL_TextFmt */
276 case RTGL_TextFmt: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
277 glob->textfmt = (char *)tagdata;
278 break;
279 /* RTGS_TextFmtArgs == RTGL_TextFmtArgs */
280 case RTGL_TextFmtArgs: textfmtargs = (APTR)tagdata; break;
281 case RTGS_AllowEmpty: glob->allowempty = tagdata; break;
283 } /* switch (tag->ti_Tag) */
285 } /* if (tag->ti_Tag > RT_TagBase)*/
287 } /* while ((tag = NextTagItem (&tstate))) */
289 glob->catalog = RT_OpenCatalog (locale);
291 /* ignore RTGL_Min and RTGL_Max if not rtNewGetLongA() */
292 if (mode != ENTER_NUMBER) glob->minmax = FALSE;
293 retnum++;
294 glob->newreqwin.Flags = WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_ACTIVATE
295 |WFLG_SIMPLE_REFRESH|WFLG_RMBTRAP;
297 idcmpflags = glob->idcmp | IDCMP_REFRESHWINDOW|IDCMP_GADGETUP|IDCMP_RAWKEY;
298 if (mode != IS_EZREQUEST) idcmpflags |= IDCMP_MOUSEBUTTONS|IDCMP_ACTIVEWINDOW;
300 if (!glob->prwin || !glob->prwin->UserPort
301 || (glob->prwin->UserPort->mp_SigTask != ThisProcess()))
302 glob->shareidcmp = FALSE;
304 if (!(glob->scr = GetReqScreen (&glob->newreqwin, &glob->prwin, glob->scr, pubname)))
305 return (ReqExit (glob, FALSE));
307 spacing = rtGetVScreenSize (glob->scr, (ULONG *)&scrwidth, (ULONG *)&scrheight);
309 if (fontattr)
311 if (!(glob->reqfont = OpenFont (fontattr))) fontattr = NULL;
314 if (!fontattr) fontattr = glob->scr->Font;
316 if (!(glob->visinfo = GetVisualInfoA (glob->scr, NULL))
317 || !(glob->drinfo = GetScreenDrawInfo (glob->scr)))
318 return (ReqExit (glob, FALSE));
320 itxt.ITextFont = fontattr;
321 glob->boldattr = *fontattr;
322 glob->boldattr.ta_Style |= FSF_BOLD;
323 glob->fontht = fontattr->ta_YSize;
324 scrfontht = glob->scr->Font->ta_YSize;
325 leftoff = glob->scr->WBorLeft + 4;
326 rightoff = glob->scr->WBorRight + 4;
328 /* Calculate the width, height and position of the requester window. We try
329 to position the window as close to the mouse as possible (default). */
331 if (mode != IS_EZREQUEST)
333 if (nogadfmt)
335 underscore = '_';
336 gadfmt = GetStr (glob->catalog, MSG_OK_BAR_CANCEL);
337 if (mode <= ENTER_PASSWORD)
339 gadfmt = GetStr (glob->catalog, MSG_LAST_BAR_CANCEL);
340 if (!stringbuff[0] || mode == CHECK_PASSWORD)
341 while (*gadfmt && (*gadfmt++ != '|'));
344 glob->reqflags &= GETSTRINGLONG_FLAGS;
345 glob->reqflags |= EZREQF_NORETURNKEY;
347 else
349 glob->reqflags &= EZREQ_FLAGS;
350 glob->textfmt = stringbuff;
351 textfmtargs = (APTR)maxlen;
354 if (glob->textfmt)
356 /* Calculate size of buffer needed to expand format string, also
357 calculates number of lines in format string.
358 (APTR)maxlen points to the arguments! */
360 DofmtCount (glob->textfmt, textfmtargs, &glob->bodyfmt, DOFMT_COUNTNEWLINES);
361 glob->numlines = glob->bodyfmt.numlines;
363 if (!(glob->buff = (char **)AllocVec (glob->bodyfmt.bufflen
364 + (8 + (int)sizeof (struct IntuiText)) * glob->numlines, MEMF_PUBLIC)))
365 return (ReqExit (glob, FALSE));
367 /* expand format string and fill in table of pointers to each line */
368 glob->lenptr = (ULONG *)&glob->buff[glob->numlines];
369 bodyitxt = (struct IntuiText *)&glob->lenptr[glob->numlines];
370 ptr = (char *)&bodyitxt[glob->numlines];
371 args = Dofmt (ptr, glob->textfmt, textfmtargs);
373 if (mode == IS_EZREQUEST) gadfmtargs = args;
374 FillNewLineTable (glob->buff, ptr);
376 /* Calculate width on screen of each line, remember largest */
377 for (i = 0, glob->len = 0; i < glob->numlines; i++)
379 itxt.IText = (UBYTE *)glob->buff[i];
380 j = glob->lenptr[i] = IntuiTextLength (&itxt);
381 if (j > glob->len) glob->len = j;
383 glob->width = glob->len + 70;
386 nogadgets = (gadfmt == NULL);
388 if (!nogadgets)
390 DofmtCount (gadfmt, gadfmtargs, &glob->gadfmtbuff, DOFMT_COUNTBARS);
391 gadlines = glob->gadfmtbuff.numlines;
392 glob->gadfmtbuff.bufflen += 12 * gadlines;
393 if (!(glob->gadstrbuff = (char **)AllocVec (glob->gadfmtbuff.bufflen, MEMF_PUBLIC)))
394 return (ReqExit (glob, FALSE));
396 gadlenptr = (ULONG *)&glob->gadstrbuff[gadlines];
397 gadposptr = (ULONG *)&gadlenptr[gadlines];
398 ptr = (char *)&gadposptr[gadlines];
399 Dofmt (ptr, gadfmt, gadfmtargs);
400 FillBarTable (glob->gadstrbuff, ptr);
402 for (i = 0; i < gadlines; i++)
404 UBYTE underscorechar = (UBYTE)underscore;
406 gadlenptr[i] = myTextLength (glob->gadstrbuff[i], fontattr, &underscorechar, NULL, 0) + 24;
407 gadlen += gadlenptr[i];
410 } /* if (!nogadgets) */
412 /* else gadlines = 0; is always NULL (cleared at beginning) */
414 if (!title)
416 if (gadlines >= 2) title = GetStr (glob->catalog, MSG_REQUEST);
417 else title = GetStr (glob->catalog, MSG_INFORMATION);
420 glob->newreqwin.Title = (UBYTE *)title;
422 top = (glob->scr->WBorTop + scrfontht + 1) + spacing;
423 val = glob->fontht + 6;
426 if (mode != IS_EZREQUEST)
428 #if 1
429 /* AROS FIX: calc. was wrong because scr->WBorTop not taken into account. */
431 height = glob->scr->WBorTop + 13 + glob->fontht * 2 + scrfontht + spacing * 3 + glob->scr->WBorBottom;
433 #else
434 height = 15 + glob->fontht * 2 + scrfontht + spacing * 3 + glob->scr->WBorBottom;
435 #endif
437 if (glob->textfmt)
439 glob->texttop = top;
440 glob->textht = (glob->fontht + 1) * glob->numlines + (glob->nowinbackfill ? 0 : 15);
441 height += spacing + glob->textht;
442 top += spacing + glob->textht;
445 if (glob->minmax)
447 height += glob->fontht + spacing + 4;
448 if (min == 0x80000000)
449 DofmtArgs (glob->minmaxstr, GetStr (glob->catalog, MSG_MAX_FMT), max);
450 else DofmtArgs (glob->minmaxstr, (max != 0x7FFFFFFF) ?
451 GetStr (glob->catalog, MSG_MIN_MAX_FMT) :
452 GetStr (glob->catalog, MSG_MIN_FMT),
453 min, max);
454 itxt.IText = glob->minmaxstr;
455 glob->minmaxlen = IntuiTextLength (&itxt) + 8;
456 if (glob->minmaxlen + 16 > glob->width) glob->width = glob->minmaxlen + 16;
459 if (glob->width < 180) glob->width = 180;
461 glob->strgadtop = top;
462 glob->strgadht = val;
464 } /* if (mode != IS_EZREQUEST) */
465 else
467 glob->texttop = top;
468 glob->textht = (glob->fontht + 1) * glob->numlines + 15;
469 #if 1
470 /* AROS FIX: Did not take scr->WBorTop into account */
471 height = spacing * 2 + scrfontht + glob->textht + 1 + glob->scr->WBorTop + glob->scr->WBorBottom;
472 #else
473 height = spacing * 2 + scrfontht + glob->textht + 3 + glob->scr->WBorBottom;
474 #endif
475 if (!nogadgets) height += spacing + val;
478 i = gadlen + gadlines * 16;
479 if (i > glob->width) glob->width = i;
481 if (glob->width > scrwidth) glob->width = scrwidth;
482 if (height > scrheight) height = scrheight;
484 /* Create gadgets */
485 gad = (struct Gadget *)CreateContext (&glob->buttoninfo.glist);
486 ng.ng_VisualInfo = glob->visinfo;
487 ng.ng_TextAttr = fontattr;
488 ng.ng_TopEdge = height - spacing - val - glob->scr->WBorBottom;
489 ng.ng_Height = val;
490 ng.ng_GadgetID = 1;
492 if (!nogadgets)
494 nlen = gadlenptr[gadlines-1];
496 if (gadlines > 1)
498 npos = glob->width - (nlen + rightoff);
499 rtSpread (gadposptr, gadlenptr, gadlen,
500 leftoff, glob->width - rightoff, gadlines);
502 else
504 gadposptr[0] = npos = (glob->width - nlen) / 2;
505 retnum = 1;
508 for (i = 0; i < gadlines; i++)
510 ng.ng_GadgetID++;
511 if (i == gadlines - 1) ng.ng_GadgetID = 1;
513 ng.ng_LeftEdge = gadposptr[i];
514 ng.ng_Width = gadlenptr[i];
515 ng.ng_GadgetText = glob->gadstrbuff[i];
516 ng.ng_TextAttr = fontattr;
518 if ((val = (ng.ng_GadgetID == retnum
519 && !(glob->reqflags & EZREQF_NORETURNKEY))))
520 ng.ng_TextAttr = &glob->boldattr;
522 gad = my_CreateButtonGadget (gad, underscore, &ng);
524 if (val) glob->retgad = gad;
525 if (!i) glob->yesgad = gad;
527 glob->nogad = gad;
529 } /* if (!nogadgets) */
530 else
532 /* glob->nogad = NULL; */
533 npos = glob->width / 2;
534 nlen = 0;
537 if (!glob->nowinbackfill && glob->texttop)
539 ng.ng_LeftEdge = leftoff;
540 ng.ng_TopEdge = glob->texttop;
541 ng.ng_Width = glob->width - (leftoff + rightoff);
542 ng.ng_Height = glob->textht;
543 ng.ng_GadgetText = NULL;
545 gad = myCreateGadget (TEXT_KIND, gad, &ng, GTTX_Border, TRUE, TAG_END);
548 glob->newreqwin.Width = glob->width;
549 glob->newreqwin.Height = height;
550 reqpos = CheckReqPos (reqpos, RTPREF_OTHERREQ, &glob->newreqwin);
552 if (reqpos == REQPOS_POINTER)
554 glob->newreqwin.LeftEdge = -npos - nlen / 2;
555 glob->newreqwin.TopEdge = -height + glob->fontht / 2 + 5 + spacing;
558 rtSetReqPosition (reqpos, &glob->newreqwin, glob->scr, glob->prwin);
560 ng.ng_Height = glob->fontht + 6;
562 if (mode != IS_EZREQUEST)
564 glob->minmaxtop = ng.ng_TopEdge = height - 2 * (glob->fontht + spacing) - 10 - glob->scr->WBorBottom;
565 ng.ng_GadgetText = NULL;
567 if (glob->minmax)
569 ng.ng_LeftEdge = glob->minmaxleft = (glob->width - glob->minmaxlen) / 2;
570 ng.ng_Width = glob->minmaxlen;
571 ng.ng_Height -= 2;
573 gad = myCreateGadget (TEXT_KIND, gad, &ng,
574 GTTX_Text, (IPTR) glob->minmaxstr, GTTX_Border, TRUE, TAG_END);
575 ng.ng_Height += 2;
578 ng.ng_LeftEdge = leftoff;
579 ng.ng_Width = glob->width - (leftoff + rightoff);
580 ng.ng_TopEdge = glob->strgadtop;
581 ng.ng_GadgetID = STRINGGADID;
583 if (mode <= ENTER_PASSWORD)
585 stringbuff = NULL;
586 maxlen = 16;
589 if (mode < ENTER_NUMBER)
590 gad = my_CreateStringGadget (gad, &ng, maxlen, stringbuff);
591 else
592 gad = my_CreateIntegerGadget (gad, &ng, 16, *value, GACT_STRINGCENTER);
594 glob->strgad = gad;
595 if (gad)
597 glob->strinfo = (struct StringInfo *)glob->strgad->SpecialInfo;
598 glob->arg.buffer = glob->strinfo->Buffer;
600 if (mode == ENTER_NUMBER && !showdef) *glob->arg.buffer = 0;
601 if (invisible) *(ULONG *)(glob->strinfo->Extension->Pens) = 0;
604 /* we do this here because there seems to be a bug in GO! :-( */
605 gad = glob->strgad;
607 } /* if (mode != IS_EZREQUEST) */
609 img = &glob->headimg;
610 if (!glob->nowinbackfill)
612 val = glob->scr->WBorTop + glob->scr->Font->ta_YSize + 1;
613 img = CreateRectImage (glob, img, glob->scr->WBorLeft, val,
614 glob->width - glob->scr->WBorLeft - glob->scr->WBorRight,
615 height - val - glob->scr->WBorBottom,
616 SHINEPEN, BACKGROUNDPEN);
618 if (glob->minmax)
619 img = CreateRectImage (glob, img, glob->minmaxleft, ++glob->minmaxtop,
620 glob->minmaxlen, glob->fontht + 2,
621 BACKGROUNDPEN, BACKGROUNDPEN);
622 if (glob->texttop)
623 img = CreateRectImage (glob, img, leftoff + 1, glob->texttop + 1,
624 glob->width - (leftoff + rightoff + 2),
625 glob->textht - 2, BACKGROUNDPEN, BACKGROUNDPEN);
627 if (glob->strgadtop)
628 img = CreateRectImage (glob, img, leftoff + 2, glob->strgadtop,
629 glob->width - (leftoff + rightoff + 4), glob->strgadht,
630 BACKGROUNDPEN, BACKGROUNDPEN);
633 if (glob->textfmt)
635 /* build list of intuitexts (line by line) */
636 itxt.FrontPen = glob->drinfo->dri_Pens[
637 (glob->reqflags & GSREQF_HIGHLIGHTTEXT) ? HIGHLIGHTTEXTPEN : TEXTPEN];
638 itxt.TopEdge = glob->texttop + (glob->nowinbackfill ? 0 : 8);
639 val = (glob->width - glob->len) / 2;
640 for (i = 0, j = 0; i < glob->numlines; i++, j += glob->fontht + 1)
642 bodyitxt[i] = itxt;
643 if (glob->reqflags & EZREQF_CENTERTEXT)
644 val = (glob->width - glob->lenptr[i]) / 2;
645 if (val < 35) val = 35;
646 bodyitxt[i].LeftEdge = val;
647 bodyitxt[i].TopEdge += j;
648 bodyitxt[i].IText = glob->buff[i];
650 if (i) bodyitxt[i-1].NextText = &bodyitxt[i];
653 } /* if (glob->textfmt) */
655 if (glob->headimg.NextImage || glob->textfmt)
657 ng.ng_LeftEdge = ng.ng_TopEdge = ng.ng_Width = ng.ng_Height = 0;
658 ng.ng_GadgetText = NULL;
660 gad = myCreateGadget (GENERIC_KIND, gad, &ng, TAG_END);
661 if (gad)
663 gad->GadgetType |= GTYP_BOOLGADGET;
664 #ifdef __AROS__
665 #warning A workaround here for AROS, because this would overpaint many gadgets
666 /* This seems to rely somehow on how GadTools refreshes gadgets
667 (the order etc.).
669 This gadget is at the end of the gadget list and in GadgetRender
670 contains a linked list of fillrectclass images for the requester
671 background and textbox backgrounds. */
673 gad->Flags |= GFLG_GADGHNONE;
674 #else
675 gad->Flags |= GFLG_GADGIMAGE|GFLG_GADGHNONE;
676 gad->GadgetRender = (APTR)glob->headimg.NextImage;
677 #endif
678 gad->GadgetText = &bodyitxt[0];
683 if (!gad || (!glob->nowinbackfill && !img)) return (ReqExit (glob, FALSE));
685 glob->newreqwin.IDCMPFlags = glob->shareidcmp ? 0 : idcmpflags;
688 /* Now open the message window. */
689 if (!(glob->reqwin = OpenWindowBF (&glob->newreqwin,
690 &glob->backfillhook,
691 glob->drinfo->dri_Pens,
692 NULL,
693 NULL,
694 !glob->nowinbackfill)))
695 return (ReqExit (glob, FALSE));
697 if (glob->shareidcmp)
699 glob->reqwin->UserPort = glob->prwin->UserPort;
700 ModifyIDCMP (glob->reqwin, idcmpflags);
703 AddGList (glob->reqwin, glob->buttoninfo.glist, -1, -1, NULL);
704 RefreshGadgets (glob->buttoninfo.glist, glob->reqwin, NULL);
705 GT_RefreshWindow (glob->reqwin, NULL);
706 glob->winlock = DoLockWindow (glob->prwin, glob->lockwindow, NULL, TRUE);
707 DoWaitPointer (glob->prwin, glob->waitpointer, TRUE);
709 glob->frontscr = IntuitionBase->FirstScreen;
710 DoScreenToFront (glob->scr, glob->noscreenpop, TRUE);
712 glob->buttoninfo.win = glob->reqwin;
713 glob->min = min;
714 glob->max = max;
715 glob->pubscr = (glob->newreqwin.Type == PUBLICSCREEN);
717 /* fill in RealHandlerInfo */
718 glob->func = (ULONG (*)())myReqHandler;
719 glob->WaitMask = (1 << glob->reqwin->UserPort->mp_SigBit);
720 glob->DoNotWait = TRUE;
722 if (reqhandler) return (CALL_HANDLER);
724 return (LoopReqHandler ((struct rtHandlerInfo *)glob));
727 /****************************************************************************************/
729 static struct Image * REGARGS CreateRectImage (Req_GlobData *glob,
730 struct Image *previmg, int x, int y, int w, int h, int pen, int bgpen)
732 struct Image *img;
734 if (!previmg) return (NULL);
736 img = NewObject (NULL, "fillrectclass",
737 IA_Left, x, IA_Top, y,
738 IA_Width, w, IA_Height, h,
739 IA_FGPen, glob->drinfo->dri_Pens[pen],
740 IA_BGPen, glob->drinfo->dri_Pens[bgpen],
741 IA_Mode, JAM2,
742 (pen == SHINEPEN) ? IA_APattern : TAG_END, (IPTR) pattern,
743 IA_APatSize, 1,
744 TAG_END);
746 previmg->NextImage = img;
748 return (img);
751 /****************************************************************************************/
753 #define RETURN_KEY 13
754 #define ESC_KEY 27
755 #define SHIFT_KEY 0x60
756 #define F1_KEY 0x50
757 #define F10_KEY 0x59
759 #define QUALS_CONSIDERED ( IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND | IEQUALIFIER_LSHIFT | \
760 IEQUALIFIER_RSHIFT | IEQUALIFIER_LALT | IEQUALIFIER_RALT | \
761 IEQUALIFIER_CONTROL )
763 /****************************************************************************************/
765 static ULONG ASM SAVEDS myReqHandler (
766 REGPARAM(a1, Req_GlobData *, glob),
767 REGPARAM(d0, ULONG, sigs),
768 REGPARAM(a0, struct TagItem *, taglist))
770 struct Gadget *tmpgad, *selgad;
771 struct TagItem *tag;
772 const struct TagItem *tstate = taglist;
773 struct IntuiMessage *msg;
774 ULONG class, tagdata;
775 UWORD code, qual;
776 int gadid, val, leftamiga, doactgad, copystr;
777 char *str, key;
779 /* uncomment if sigs is no longer ignored */
780 //if (glob->DoNotWait) sigs = 0;
782 doactgad = (glob->mode != IS_EZREQUEST) && !(glob->buttoninfo.lastcode);
784 /* parse tags */
785 while ((tag = NextTagItem (&tstate)))
787 tagdata = tag->ti_Data;
788 if (tag->ti_Tag > RT_TagBase)
790 switch (tag->ti_Tag)
792 case RTRH_EndRequest:
793 glob->arg.retcode = tagdata;
794 return (ReqExit (glob, tagdata));
799 while ((msg = GetWin_GT_Msg (glob->reqwin, glob->imsghook, glob->reqinfo)))
801 class = msg->Class;
802 code = msg->Code;
803 qual = msg->Qualifier;
805 gadid = 0;
806 if (class == IDCMP_RAWKEY && glob->nogad)
808 /* Convert key to ASCII and check if a gadget pops up */
809 if (!(gadid = CheckGadgetKey (code, qual, &key, &glob->buttoninfo)))
811 if (!glob->buttoninfo.lastcode && !(qual & IEQUALIFIER_REPEAT))
813 leftamiga = (qual & IEQUALIFIER_LCOMMAND);
814 selgad = NULL;
816 if (key == RETURN_KEY) selgad = glob->retgad;
817 if (key == ESC_KEY) selgad = glob->nogad;
819 if (!(glob->reqflags & EZREQF_LAMIGAQUAL) || leftamiga)
821 switch (key)
823 case 'V': if (!leftamiga) break;
824 case 'Y': selgad = glob->yesgad; break;
825 case 'B': if (!leftamiga) break;
826 case 'N': case 'R': selgad = glob->nogad; break;
830 if ( ( glob->fkeys ) &&
831 !(qual & QUALS_CONSIDERED) &&
832 (code >= F1_KEY) && (code <= F10_KEY) &&
833 (code - F1_KEY < glob->gadfmtbuff.numlines))
835 LONG i = code - F1_KEY;
837 selgad = glob->yesgad;
839 while( i && selgad )
841 selgad = selgad->NextGadget;
842 --i;
846 if (selgad) my_DownGadget (selgad, code, &glob->buttoninfo);
848 } /* if (!glob->buttoninfo.lastcode && !(qual & IEQUALIFIER_REPEAT)) */
850 } /* if (!(gadid = CheckGadgetKey (code, qual, &key, &glob->buttoninfo))) */
852 } /* if (class == IDCMP_RAWKEY && glob->nogad) */
854 tmpgad = (struct Gadget *)msg->IAddress;
855 Reply_GT_Msg (msg);
857 if (class == IDCMP_REFRESHWINDOW)
859 GT_BeginRefresh (glob->reqwin);
860 GT_EndRefresh (glob->reqwin, TRUE);
861 continue;
864 if (class == IDCMP_GADGETUP || gadid)
866 if (!gadid) gadid = tmpgad->GadgetID;
868 if (gadid < STRINGGADID)
870 if (gadid == 1 || glob->mode == IS_EZREQUEST
871 || glob->mode == ENTER_PASSWORD)
873 glob->arg.retcode = gadid - 1;
874 return (ReqExit (glob, FALSE));
878 if (glob->mode == IS_EZREQUEST) continue;
880 if (glob->mode > ENTER_PASSWORD)
882 if (gadid == STRINGGADID)
884 if (code == 1)
886 doactgad = FALSE;
887 continue;
890 my_SelectGadget ((*glob->arg.buffer || glob->allowempty)
891 ? glob->yesgad : glob->nogad, glob->reqwin);
892 ShortDelay();
895 if (glob->mode == ENTER_STRING)
897 copystr = (glob->arg.buffer[0] != 0);
898 glob->arg.retcode = copystr;
899 if (glob->allowempty) copystr = glob->arg.retcode = TRUE;
900 if (gadid > 2 && gadid < STRINGGADID) glob->arg.retcode = gadid - 1;
901 return (ReqExit (glob, copystr));
904 /* glob->mode == ENTER_NUMBER */
905 if (glob->arg.buffer[0])
907 val = glob->strinfo->LongInt;
908 str = NULL;
909 if (val < glob->min) str = GetStr (glob->catalog, MSG_TOO_SMALL);
910 else if (val > glob->max) str = GetStr (glob->catalog, MSG_TOO_BIG);
911 if (str)
913 if (gadid == STRINGGADID)
914 my_SelectGadget (glob->yesgad, glob->reqwin);
915 SetWinTitleFlash (glob->reqwin, str);
916 continue;
918 *glob->value = val;
921 glob->arg.retcode = (glob->arg.buffer[0] != 0);
922 if (gadid > 2 && gadid < STRINGGADID) glob->arg.retcode = gadid - 1;
924 return (ReqExit (glob, FALSE));
926 } /* if (glob->mode > ENTER_PASSWORD) */
928 if (gadid == STRINGGADID)
930 if (code == 1)
932 doactgad = FALSE;
933 continue;
937 if (glob->arg.buffer[0])
939 if ((str = ((PWCALLBACKFUNPTR)
940 glob->value)(glob->mode, glob->checksum, &glob->arg)))
942 /* Check if return was 'Please verify', MAJOR HACK !! */
943 if (*str != 'P') DisplayBeep (glob->scr);
944 SetWindowTitles (glob->reqwin, str, (char *)~0);
945 my_SetStringGadget (glob->reqwin, glob->strgad, "");
947 else return (ReqExit (glob, glob->arg.retcode));
950 } /* if (glob->mode > ENTER_PASSWORD) */
951 else if (class & glob->idcmp)
953 glob->arg.retcode = glob->idcmp;
954 return (ReqExit (glob, FALSE));
957 } /* while ((msg = GetWin_GT_Msg (glob->reqwin, glob->imsghook, glob->reqinfo))) */
959 if (doactgad)
961 ActivateGadget (glob->strgad, glob->reqwin, NULL);
964 glob->DoNotWait = FALSE;
966 return (CALL_HANDLER);
969 /****************************************************************************************/
971 static ULONG REGARGS ReqExit (Req_GlobData *glob, int cpystr)
973 ULONG ret = glob->arg.retcode;
974 struct Image *img, *img2;
976 if (cpystr && glob->mode <= ENTER_STRING)
977 strcpy (glob->stringbuff, glob->arg.buffer);
979 DoScreenToFront (glob->frontscr, glob->noscreenpop, FALSE);
981 if (glob->reqwin)
983 DoLockWindow (glob->prwin, glob->lockwindow, glob->winlock, FALSE);
984 DoWaitPointer (glob->prwin, glob->waitpointer, FALSE);
985 DoCloseWindow (glob->reqwin, glob->shareidcmp);
988 RT_CloseCatalog (glob->catalog);
989 my_FreeGadgets (glob->buttoninfo.glist);
990 img = glob->headimg.NextImage;
992 while (img)
994 img2 = img->NextImage;
995 DisposeObject (img);
996 img = img2;
999 FreeVec (glob->buff);
1000 FreeVec (glob->gadstrbuff);
1002 if (glob->drinfo) FreeScreenDrawInfo (glob->scr, glob->drinfo);
1004 FreeVisualInfo (glob->visinfo);
1006 if (glob->pubscr) UnlockPubScreen (NULL, glob->scr);
1007 if (glob->reqfont) CloseFont (glob->reqfont);
1009 FreeVec (glob);
1011 return (ret);
1014 /****************************************************************************************/