add place-holder directory for the a3000 wd533c93 scsi controller implementation.
[AROS.git] / workbench / libs / reqtools / req.c
blob5e3b57f8b8faadb2bed4daaf8c07b3a82d5530f6
1 /*
2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <exec/types.h>
9 #include <exec/io.h>
10 #include <exec/memory.h>
11 #include <intuition/intuition.h>
12 #include <intuition/intuitionbase.h>
13 #include <intuition/sghooks.h>
14 #include <intuition/imageclass.h>
15 #include <libraries/dos.h>
16 #include <libraries/gadtools.h>
17 #include <libraries/reqtools.h>
18 #include <proto/exec.h>
19 #include <proto/gadtools.h>
20 #include <proto/graphics.h>
21 #include <proto/intuition.h>
22 #include <proto/utility.h>
23 #include <proto/reqtools.h>
24 #include <string.h>
26 #include "filereq.h"
29 #include "rtlocale.h"
31 /****************************************************************************************/
33 #ifndef __AROS__
35 #ifdef __SASC
36 #pragma libcall ReqToolsBase rtLockPrefs a8 00
37 #pragma libcall ReqToolsBase rtUnlockPrefs ae 00
38 #else
39 #warning You might have to fix rtLockPrefs/rtUnlockPrefs for your compiler
40 #endif
42 #endif
44 /****************************************************************************************/
46 #define ThisProcess() ( ( struct Process * ) FindTask( NULL ) )
48 /****************************************************************************************/
50 struct PWCallBackArgs
52 char *buffer;
53 ULONG lastchecksum, verify, retcode;
56 /****************************************************************************************/
58 extern IPTR ASM LoopReqHandler (ASM_REGPARAM(a1, struct rtHandlerInfo *,));
59 extern void REGARGS SetWinTitleFlash (struct Window *, char *);
60 extern void ShortDelay (void);
61 extern ULONG ASM myTextLength (ASM_REGPARAM(a1, char *,),
62 ASM_REGPARAM(a0, struct TextAttr *,),
63 ASM_REGPARAM(a3, UBYTE *,),
64 ASM_REGPARAM(a2, struct Image *,),
65 ASM_REGPARAM(d7, ULONG,));
67 extern struct ReqToolsBase *ReqToolsBase;
68 extern struct DosLibrary *DOSBase;
69 extern struct IntuitionBase *IntuitionBase;
70 extern struct Library *GadToolsBase;
71 extern struct GfxBase *GfxBase;
73 /****************************************************************************************/
75 struct FmtBuff
77 LONG numlines, bufflen;
80 #define DOFMT_COUNTNEWLINES 0
81 #define DOFMT_COUNTBARS 1
83 /****************************************************************************************/
86 extern APTR DofmtCount (char *, APTR, ULONG *, int);
87 extern APTR STDARGS DofmtArgs (char *, char *,...);
90 extern void FillBarTable (char **, char *);
91 extern void FillNewLineTable (char **, char *);
93 /****************************************************************************************/
95 typedef struct Req_RealHandlerInfo Req_GlobData;
96 #define STRINGGADID 32
98 struct Req_RealHandlerInfo
100 IPTR (*func)(); /* private */
101 ULONG WaitMask;
102 ULONG DoNotWait;
104 /* PRIVATE */
105 char **gadstrbuff, **buff, *stringbuff, *textfmt;
106 struct PWCallBackArgs arg;
107 struct Gadget *strgad, *yesgad, *nogad, *retgad, *selgad;
108 struct TextAttr boldattr;
109 struct KeyButtonInfo buttoninfo;
110 struct StringInfo *strinfo;
111 struct Screen *scr, *frontscr;
112 struct Window *prwin;
113 struct Window *reqwin;
114 struct DrawInfo *drinfo;
115 struct rtReqInfo *reqinfo;
116 struct Hook *imsghook, backfillhook;
117 struct TextFont *reqfont;
118 struct Catalog *catalog;
119 struct Image headimg;
120 struct NewWindow newreqwin;
121 struct FmtBuff bodyfmt, gadfmtbuff;
122 UBYTE minmaxstr[30];
123 int idcmp, mode, min, max, checksum, pubscr, reqflags;
124 int retnum, waitpointer, allowempty, lockwindow, shareidcmp, noscreenpop;
125 int textht, texttop, strgadht, strgadtop, width, nowinbackfill;
126 int numlines, len, fontht, minmax, minmaxlen, minmaxtop, minmaxleft;
127 int fkeys;
128 APTR winlock, visinfo;
129 ULONG *value, *lenptr;
132 /****************************************************************************************/
134 static CONST UWORD pattern[] = { 0xAAAA,0x5555 };
136 static ULONG REGARGS ReqExit (Req_GlobData *, int);
137 static struct Image * REGARGS CreateRectImage
138 (Req_GlobData *, struct Image *, int, int, int, int, int, int);
139 static IPTR ASM SAVEDS myReqHandler (REGPARAM(a1, Req_GlobData *,),
140 REGPARAM(d0, ULONG,),
141 REGPARAM(a0, struct TagItem *,));
143 /****************************************************************************************/
145 #define GETSTRINGLONG_FLAGS (GSREQF_CENTERTEXT|GSREQF_HIGHLIGHTTEXT)
146 #define EZREQ_FLAGS (EZREQF_NORETURNKEY|EZREQF_LAMIGAQUAL|EZREQF_CENTERTEXT)
149 /****************************************************************************************/
151 ULONG ASM SAVEDS GetString (
152 REGPARAM(a1, UBYTE *, stringbuff), /* str in case of rtEZRequestA */
153 REGPARAM(d0, SIPTR, maxlen), /* args in case of rtEZRequestA */
154 REGPARAM(a2, char *, title), /* gadfmt in case of rtEZRequestA */
155 REGPARAM(d1, ULONG, checksum),
156 REGPARAM(d2, ULONG *, value),
157 REGPARAM(d3, LONG, mode),
158 REGPARAM(d4, struct rtReqInfo *, reqinfo),
159 REGPARAM(a0, struct TagItem *, taglist))
161 /* #define CLEARSIZE (28+sizeof(struct NewWindow)+sizeof(struct IntuiText)+\
162 sizeof(struct NewGadget)+2*sizeof(struct FmtBuff)) */
164 // FIXME: obsolete comment?
165 /* keep these vars together and just BEFORE NewWindow struct! */
166 /*-------------------------------------------------*/
167 int reqpos = REQPOS_DEFAULT;
168 char *pubname = NULL;
169 ULONG underscore = 0;
170 struct TextAttr *fontattr = NULL;
171 struct Locale *locale = NULL;
172 struct IntuiText itxt, *bodyitxt = NULL;
173 struct NewGadget ng;
174 struct Image *img;
175 /**/
176 // FIXME: obsolete comment?
177 /* KEEP MIN AND MAX IN THIS ORDER !!!! */
178 int max = MAXINT, min = MININT;
179 /**/
180 Req_GlobData *glob;
181 struct Gadget *gad;
182 struct TagItem *tag, *tstate;
183 /* for rtEZRequestA */
184 char *gadfmt = title;
185 char *ptr;
186 int val, spacing, reqhandler = FALSE, nogadfmt, gadlen = 0;
187 int height, top, showdef = TRUE;
188 int scrwidth, scrheight, i, j, npos, nlen, nogadgets, retnum;
189 int invisible, scrfontht, gadlines = 0;
190 int leftoff, rightoff;
191 ULONG *gadlenptr = NULL, *gadposptr = NULL, idcmpflags;
192 APTR gadfmtargs = NULL, textfmtargs = NULL;
194 memset (&itxt, 0, sizeof (struct IntuiText));
195 memset (&ng, 0, sizeof (struct NewGadget));
197 if (!(glob = AllocVec (sizeof (Req_GlobData), MEMF_PUBLIC | MEMF_CLEAR)))
198 return (FALSE);
200 glob->mode = mode;
201 glob->checksum = checksum;
202 glob->value = value;
203 glob->stringbuff = stringbuff;
204 glob->fkeys = rtLockPrefs()->Flags & RTPRF_FKEYS;
205 rtUnlockPrefs();
207 nogadfmt = (mode != IS_EZREQUEST);
208 invisible = (mode <= ENTER_PASSWORD);
210 if (mode == IS_EZREQUEST) title = NULL;
211 if (mode == ENTER_STRING) glob->width = 350; else glob->width = 180;
212 retnum = 1;
213 if ((glob->reqinfo = reqinfo))
215 if (reqinfo->Width) glob->width = reqinfo->Width;
216 if (reqinfo->ReqTitle) title = reqinfo->ReqTitle;
217 if (reqinfo->ReqPos != REQPOS_DEFAULT) reqpos = reqinfo->ReqPos;
219 glob->newreqwin.LeftEdge = reqinfo->LeftOffset;
220 glob->newreqwin.TopEdge = reqinfo->TopOffset;
221 glob->reqflags = reqinfo->Flags;
222 glob->waitpointer = reqinfo->WaitPointer;
223 glob->lockwindow = reqinfo->LockWindow;
224 glob->shareidcmp = reqinfo->ShareIDCMP;
225 glob->imsghook = reqinfo->IntuiMsgFunc;
228 /* parse tags */
229 tstate = taglist;
230 while ((tag = NextTagItem (&tstate)))
232 IPTR tagdata = tag->ti_Data;
233 if (tag->ti_Tag > RT_TagBase)
235 switch (tag->ti_Tag)
237 case RT_Window: glob->prwin = (struct Window *)tagdata; break;
238 case RT_IDCMPFlags: glob->idcmp = tagdata; break;
239 case RT_ReqPos: reqpos = tagdata; break;
240 case RT_LeftOffset: glob->newreqwin.LeftEdge = tagdata; break;
241 case RT_TopOffset: glob->newreqwin.TopEdge = tagdata; break;
242 case RT_PubScrName: pubname = (char *)tagdata; break;
243 case RT_Screen: glob->scr = (struct Screen *)tagdata; break;
244 case RT_ReqHandler: *(APTR *)tagdata = glob;
245 reqhandler = TRUE;
246 break;
247 case RT_WaitPointer: glob->waitpointer = tagdata; break;
248 case RT_Underscore: underscore = tagdata; break;
249 case RT_ShareIDCMP: glob->shareidcmp = tagdata; break;
250 case RT_LockWindow: glob->lockwindow = tagdata; break;
251 case RT_ScreenToFront: glob->noscreenpop = !tagdata; break;
252 case RT_TextAttr: fontattr = (struct TextAttr *)tagdata; break;
253 case RT_IntuiMsgFunc: glob->imsghook = (struct Hook *)tagdata; break;
254 case RT_Locale: locale = (struct Locale *)tagdata; break;
255 case RTEZ_ReqTitle: if (mode == IS_EZREQUEST) title = (char *)tagdata;
256 break;
257 /* RTGS_Flags == RTGL_Flags == RTEZ_Flags */
258 case RTEZ_Flags: glob->reqflags = tagdata; break;
259 case RTEZ_DefaultResponse: retnum = tagdata; break;
260 case RTGL_Min: min = tagdata; glob->minmax = TRUE; break;
261 case RTGL_Max: max = tagdata; glob->minmax = TRUE; break;
262 /* RTGS_Width == RTGL_Width */
263 case RTGL_Width: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
264 glob->width = tagdata;
265 break;
266 case RTGL_ShowDefault: showdef = tagdata; break;
267 /* RTGS_GadFmt == RTGL_GadFmt */
268 case RTGL_GadFmt: nogadfmt = FALSE;
269 gadfmt = (char *)tagdata;
270 break;
271 /* RTGS_GadFmtArgs == RTGL_GadFmtArgs */
272 case RTGL_GadFmtArgs: gadfmtargs = (APTR)tagdata; break;
273 /* RTGS_Invisible == RTGL_Invisible */
274 case RTGL_Invisible: invisible = tagdata; break;
275 /* RTGS_BackFill == RTGL_BackFill */
276 case RTGL_BackFill: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
277 glob->nowinbackfill = !tagdata;
278 break;
279 /* RTGS_TextFmt == RTGL_TextFmt */
280 case RTGL_TextFmt: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
281 glob->textfmt = (char *)tagdata;
282 break;
283 /* RTGS_TextFmtArgs == RTGL_TextFmtArgs */
284 case RTGL_TextFmtArgs: textfmtargs = (APTR)tagdata; break;
285 case RTGS_AllowEmpty: glob->allowempty = tagdata; break;
287 } /* switch (tag->ti_Tag) */
289 } /* if (tag->ti_Tag > RT_TagBase)*/
291 } /* while ((tag = NextTagItem (&tstate))) */
293 glob->catalog = RT_OpenCatalog (locale);
295 /* ignore RTGL_Min and RTGL_Max if not rtNewGetLongA() */
296 if (mode != ENTER_NUMBER) glob->minmax = FALSE;
297 retnum++;
298 glob->newreqwin.Flags = WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_ACTIVATE
299 |WFLG_SIMPLE_REFRESH|WFLG_RMBTRAP;
301 idcmpflags = glob->idcmp | IDCMP_REFRESHWINDOW|IDCMP_GADGETUP|IDCMP_RAWKEY;
302 if (mode != IS_EZREQUEST) idcmpflags |= IDCMP_MOUSEBUTTONS|IDCMP_ACTIVEWINDOW;
304 if (!glob->prwin || !glob->prwin->UserPort
305 || (glob->prwin->UserPort->mp_SigTask != ThisProcess()))
306 glob->shareidcmp = FALSE;
308 if (!(glob->scr = GetReqScreen (&glob->newreqwin, &glob->prwin, glob->scr, pubname)))
309 return (ReqExit (glob, FALSE));
311 spacing = rtGetVScreenSize (glob->scr, (ULONG *)&scrwidth, (ULONG *)&scrheight);
313 if (fontattr)
315 if (!(glob->reqfont = OpenFont (fontattr))) fontattr = NULL;
318 if (!fontattr) fontattr = glob->scr->Font;
320 if (!(glob->visinfo = GetVisualInfoA (glob->scr, NULL))
321 || !(glob->drinfo = GetScreenDrawInfo (glob->scr)))
322 return (ReqExit (glob, FALSE));
324 itxt.ITextFont = fontattr;
325 glob->boldattr = *fontattr;
326 glob->boldattr.ta_Style |= FSF_BOLD;
327 glob->fontht = fontattr->ta_YSize;
328 scrfontht = glob->scr->Font->ta_YSize;
329 leftoff = glob->scr->WBorLeft + 4;
330 rightoff = glob->scr->WBorRight + 4;
332 /* Calculate the width, height and position of the requester window. We try
333 to position the window as close to the mouse as possible (default). */
335 if (mode != IS_EZREQUEST)
337 if (nogadfmt)
339 underscore = '_';
340 gadfmt = GetStr (glob->catalog, MSG_OK_BAR_CANCEL);
341 if (mode <= ENTER_PASSWORD)
343 gadfmt = GetStr (glob->catalog, MSG_LAST_BAR_CANCEL);
344 if (!stringbuff[0] || mode == CHECK_PASSWORD)
345 while (*gadfmt && (*gadfmt++ != '|'));
348 glob->reqflags &= GETSTRINGLONG_FLAGS;
349 glob->reqflags |= EZREQF_NORETURNKEY;
351 else
353 glob->reqflags &= EZREQ_FLAGS;
354 glob->textfmt = stringbuff;
355 textfmtargs = (APTR)(IPTR)maxlen;
358 if (glob->textfmt)
360 /* Calculate size of buffer needed to expand format string, also
361 calculates number of lines in format string.
362 (APTR)maxlen points to the arguments! */
364 DofmtCount (glob->textfmt, textfmtargs, &glob->bodyfmt.numlines, DOFMT_COUNTNEWLINES);
365 glob->numlines = glob->bodyfmt.numlines;
367 if (!(glob->buff = (char **)AllocVec (glob->bodyfmt.bufflen
368 + ((sizeof(APTR) * 2) + (int)sizeof (struct IntuiText)) * glob->numlines, MEMF_PUBLIC)))
369 return (ReqExit (glob, FALSE));
371 /* expand format string and fill in table of pointers to each line */
372 glob->lenptr = (ULONG *)&glob->buff[glob->numlines];
373 bodyitxt = (struct IntuiText *)&glob->lenptr[glob->numlines];
374 ptr = (char *)&bodyitxt[glob->numlines];
375 Dofmt (ptr, glob->textfmt, textfmtargs);
377 if (mode == IS_EZREQUEST) gadfmtargs = textfmtargs;
378 FillNewLineTable (glob->buff, ptr);
380 /* Calculate width on screen of each line, remember largest */
381 for (i = 0, glob->len = 0; i < glob->numlines; i++)
383 itxt.IText = (UBYTE *)glob->buff[i];
384 j = glob->lenptr[i] = IntuiTextLength (&itxt);
385 if (j > glob->len) glob->len = j;
387 glob->width = glob->len + 70;
390 nogadgets = (gadfmt == NULL);
392 if (!nogadgets)
394 DofmtCount (gadfmt, gadfmtargs, &glob->gadfmtbuff.numlines, DOFMT_COUNTBARS);
395 gadlines = glob->gadfmtbuff.numlines;
397 glob->gadfmtbuff.bufflen += (sizeof(APTR) * 3) * gadlines;
398 if (!(glob->gadstrbuff = (char **)AllocVec (glob->gadfmtbuff.bufflen, MEMF_PUBLIC)))
399 return (ReqExit (glob, FALSE));
401 gadlenptr = (ULONG *)&glob->gadstrbuff[gadlines];
402 gadposptr = (ULONG *)&gadlenptr[gadlines];
403 ptr = (char *)&gadposptr[gadlines];
404 Dofmt (ptr, gadfmt, gadfmtargs);
405 FillBarTable (glob->gadstrbuff, ptr);
407 for (i = 0; i < gadlines; i++)
409 UBYTE underscorechar = (UBYTE)underscore;
411 gadlenptr[i] = myTextLength (glob->gadstrbuff[i], fontattr, &underscorechar, NULL, 0) + 24;
412 gadlen += gadlenptr[i];
415 } /* if (!nogadgets) */
417 /* else gadlines = 0; is always NULL (cleared at beginning) */
419 if (!title)
421 if (gadlines >= 2) title = GetStr (glob->catalog, MSG_REQUEST);
422 else title = GetStr (glob->catalog, MSG_INFORMATION);
425 glob->newreqwin.Title = (UBYTE *)title;
427 top = (glob->scr->WBorTop + scrfontht + 1) + spacing;
428 val = glob->fontht + 6;
431 if (mode != IS_EZREQUEST)
433 #if 1
434 /* AROS FIX: calc. was wrong because scr->WBorTop not taken into account. */
436 height = glob->scr->WBorTop + 13 + glob->fontht * 2 + scrfontht + spacing * 3 + glob->scr->WBorBottom;
438 #else
439 height = 15 + glob->fontht * 2 + scrfontht + spacing * 3 + glob->scr->WBorBottom;
440 #endif
442 if (glob->textfmt)
444 glob->texttop = top;
445 glob->textht = (glob->fontht + 1) * glob->numlines + (glob->nowinbackfill ? 0 : 15);
446 height += spacing + glob->textht;
447 top += spacing + glob->textht;
450 if (glob->minmax)
452 height += glob->fontht + spacing + 4;
453 if (min == 0x80000000)
454 DofmtArgs (glob->minmaxstr, GetStr (glob->catalog, MSG_MAX_FMT), max);
455 else if (max != 0x7FFFFFFF)
456 DofmtArgs (glob->minmaxstr, GetStr (glob->catalog, MSG_MIN_MAX_FMT), min, max);
457 else
458 DofmtArgs (glob->minmaxstr, GetStr (glob->catalog, MSG_MIN_FMT), min);
459 itxt.IText = glob->minmaxstr;
460 glob->minmaxlen = IntuiTextLength (&itxt) + 8;
461 if (glob->minmaxlen + 16 > glob->width) glob->width = glob->minmaxlen + 16;
464 if (glob->width < 180) glob->width = 180;
466 glob->strgadtop = top;
467 glob->strgadht = val;
469 } /* if (mode != IS_EZREQUEST) */
470 else
472 glob->texttop = top;
473 glob->textht = (glob->fontht + 1) * glob->numlines + 15;
474 #if 1
475 /* AROS FIX: Did not take scr->WBorTop into account */
476 height = spacing * 2 + scrfontht + glob->textht + 1 + glob->scr->WBorTop + glob->scr->WBorBottom;
477 #else
478 height = spacing * 2 + scrfontht + glob->textht + 3 + glob->scr->WBorBottom;
479 #endif
480 if (!nogadgets) height += spacing + val;
483 i = gadlen + gadlines * 16;
484 if (i > glob->width) glob->width = i;
486 if (glob->width > scrwidth) glob->width = scrwidth;
487 if (height > scrheight) height = scrheight;
489 /* Create gadgets */
490 gad = (struct Gadget *)CreateContext (&glob->buttoninfo.glist);
491 ng.ng_VisualInfo = glob->visinfo;
492 ng.ng_TextAttr = fontattr;
493 ng.ng_TopEdge = height - spacing - val - glob->scr->WBorBottom;
494 ng.ng_Height = val;
495 ng.ng_GadgetID = 1;
497 if (!nogadgets)
499 nlen = gadlenptr[gadlines-1];
501 if (gadlines > 1)
503 npos = glob->width - (nlen + rightoff);
504 rtSpread (gadposptr, gadlenptr, gadlen,
505 leftoff, glob->width - rightoff, gadlines);
507 else
509 gadposptr[0] = npos = (glob->width - nlen) / 2;
510 retnum = 1;
513 for (i = 0; i < gadlines; i++)
515 ng.ng_GadgetID++;
516 if (i == gadlines - 1) ng.ng_GadgetID = 1;
518 ng.ng_LeftEdge = gadposptr[i];
519 ng.ng_Width = gadlenptr[i];
520 ng.ng_GadgetText = glob->gadstrbuff[i];
521 ng.ng_TextAttr = fontattr;
523 if ((val = (ng.ng_GadgetID == retnum
524 && !(glob->reqflags & EZREQF_NORETURNKEY))))
525 ng.ng_TextAttr = &glob->boldattr;
527 gad = my_CreateButtonGadget (gad, underscore, &ng);
529 if (val) glob->retgad = gad;
530 if (!i) glob->yesgad = gad;
532 glob->nogad = gad;
534 } /* if (!nogadgets) */
535 else
537 /* glob->nogad = NULL; */
538 npos = glob->width / 2;
539 nlen = 0;
542 if (!glob->nowinbackfill && glob->texttop)
544 ng.ng_LeftEdge = leftoff;
545 ng.ng_TopEdge = glob->texttop;
546 ng.ng_Width = glob->width - (leftoff + rightoff);
547 ng.ng_Height = glob->textht;
548 ng.ng_GadgetText = NULL;
550 gad = myCreateGadget (TEXT_KIND, gad, &ng, GTTX_Border, TRUE, TAG_END);
553 glob->newreqwin.Width = glob->width;
554 glob->newreqwin.Height = height;
555 reqpos = CheckReqPos (reqpos, RTPREF_OTHERREQ, &glob->newreqwin);
557 if (reqpos == REQPOS_POINTER)
559 glob->newreqwin.LeftEdge = -npos - nlen / 2;
560 glob->newreqwin.TopEdge = -height + glob->fontht / 2 + 5 + spacing;
563 rtSetReqPosition (reqpos, &glob->newreqwin, glob->scr, glob->prwin);
565 ng.ng_Height = glob->fontht + 6;
567 if (mode != IS_EZREQUEST)
569 glob->minmaxtop = ng.ng_TopEdge = height - 2 * (glob->fontht + spacing) - 10 - glob->scr->WBorBottom;
570 ng.ng_GadgetText = NULL;
572 if (glob->minmax)
574 ng.ng_LeftEdge = glob->minmaxleft = (glob->width - glob->minmaxlen) / 2;
575 ng.ng_Width = glob->minmaxlen;
576 ng.ng_Height -= 2;
578 gad = myCreateGadget (TEXT_KIND, gad, &ng,
579 GTTX_Text, (IPTR) glob->minmaxstr, GTTX_Border, TRUE, TAG_END);
580 ng.ng_Height += 2;
583 ng.ng_LeftEdge = leftoff;
584 ng.ng_Width = glob->width - (leftoff + rightoff);
585 ng.ng_TopEdge = glob->strgadtop;
586 ng.ng_GadgetID = STRINGGADID;
588 if (mode <= ENTER_PASSWORD)
590 stringbuff = NULL;
591 maxlen = 16;
594 if (mode < ENTER_NUMBER)
595 gad = my_CreateStringGadget (gad, &ng, maxlen, stringbuff);
596 else
597 gad = my_CreateIntegerGadget (gad, &ng, 16, *value, GACT_STRINGCENTER);
599 glob->strgad = gad;
600 if (gad)
602 glob->strinfo = (struct StringInfo *)glob->strgad->SpecialInfo;
603 glob->arg.buffer = glob->strinfo->Buffer;
605 if (mode == ENTER_NUMBER && !showdef) *glob->arg.buffer = 0;
606 if (invisible) {
607 glob->strinfo->Extension->Pens[0] = 0;
608 glob->strinfo->Extension->Pens[1] = 0;
609 glob->strinfo->Extension->ActivePens[0] = 0;
610 glob->strinfo->Extension->ActivePens[1] = 0;
614 /* we do this here because there seems to be a bug in GO! :-( */
615 gad = glob->strgad;
617 } /* if (mode != IS_EZREQUEST) */
619 img = &glob->headimg;
620 if (!glob->nowinbackfill)
622 val = glob->scr->WBorTop + glob->scr->Font->ta_YSize + 1;
623 img = CreateRectImage (glob, img, glob->scr->WBorLeft, val,
624 glob->width - glob->scr->WBorLeft - glob->scr->WBorRight,
625 height - val - glob->scr->WBorBottom,
626 SHINEPEN, BACKGROUNDPEN);
628 if (glob->minmax)
629 img = CreateRectImage (glob, img, glob->minmaxleft, ++glob->minmaxtop,
630 glob->minmaxlen, glob->fontht + 2,
631 BACKGROUNDPEN, BACKGROUNDPEN);
632 if (glob->texttop)
633 img = CreateRectImage (glob, img, leftoff + 1, glob->texttop + 1,
634 glob->width - (leftoff + rightoff + 2),
635 glob->textht - 2, BACKGROUNDPEN, BACKGROUNDPEN);
637 if (glob->strgadtop)
638 img = CreateRectImage (glob, img, leftoff + 2, glob->strgadtop,
639 glob->width - (leftoff + rightoff + 4), glob->strgadht,
640 BACKGROUNDPEN, BACKGROUNDPEN);
643 if (glob->textfmt)
645 /* build list of intuitexts (line by line) */
646 itxt.FrontPen = glob->drinfo->dri_Pens[
647 (glob->reqflags & GSREQF_HIGHLIGHTTEXT) ? HIGHLIGHTTEXTPEN : TEXTPEN];
648 itxt.TopEdge = glob->texttop + (glob->nowinbackfill ? 0 : 8);
649 val = (glob->width - glob->len) / 2;
650 for (i = 0, j = 0; i < glob->numlines; i++, j += glob->fontht + 1)
652 bodyitxt[i] = itxt;
653 if (glob->reqflags & EZREQF_CENTERTEXT)
654 val = (glob->width - glob->lenptr[i]) / 2;
655 if (val < 35) val = 35;
656 bodyitxt[i].LeftEdge = val;
657 bodyitxt[i].TopEdge += j;
658 bodyitxt[i].IText = glob->buff[i];
660 if (i) bodyitxt[i-1].NextText = &bodyitxt[i];
663 } /* if (glob->textfmt) */
665 if (glob->headimg.NextImage || glob->textfmt)
667 ng.ng_LeftEdge = ng.ng_TopEdge = ng.ng_Width = ng.ng_Height = 0;
668 ng.ng_GadgetText = NULL;
670 gad = myCreateGadget (GENERIC_KIND, gad, &ng, TAG_END);
671 if (gad)
673 gad->GadgetType |= GTYP_BOOLGADGET;
674 #ifdef __AROS__
675 /* FIXME: A workaround here for AROS, because this would overpaint many gadgets */
676 /* This seems to rely somehow on how GadTools refreshes gadgets
677 (the order etc.).
679 This gadget is at the end of the gadget list and in GadgetRender
680 contains a linked list of fillrectclass images for the requester
681 background and textbox backgrounds. */
683 gad->Flags |= GFLG_GADGHNONE;
684 #else
685 gad->Flags |= GFLG_GADGIMAGE|GFLG_GADGHNONE;
686 gad->GadgetRender = (APTR)glob->headimg.NextImage;
687 #endif
688 gad->GadgetText = &bodyitxt[0];
693 if (!gad || (!glob->nowinbackfill && !img)) return (ReqExit (glob, FALSE));
695 glob->newreqwin.IDCMPFlags = glob->shareidcmp ? 0 : idcmpflags;
698 /* Now open the message window. */
699 if (!(glob->reqwin = OpenWindowBF (&glob->newreqwin,
700 &glob->backfillhook,
701 glob->drinfo->dri_Pens,
702 NULL,
703 NULL,
704 !glob->nowinbackfill)))
705 return (ReqExit (glob, FALSE));
707 if (glob->shareidcmp)
709 glob->reqwin->UserPort = glob->prwin->UserPort;
710 ModifyIDCMP (glob->reqwin, idcmpflags);
713 AddGList (glob->reqwin, glob->buttoninfo.glist, -1, -1, NULL);
714 RefreshGadgets (glob->buttoninfo.glist, glob->reqwin, NULL);
715 GT_RefreshWindow (glob->reqwin, NULL);
716 glob->winlock = DoLockWindow (glob->prwin, glob->lockwindow, NULL, TRUE);
717 DoWaitPointer (glob->prwin, glob->waitpointer, TRUE);
719 glob->frontscr = IntuitionBase->FirstScreen;
720 DoScreenToFront (glob->scr, glob->noscreenpop, TRUE);
722 glob->buttoninfo.win = glob->reqwin;
723 glob->min = min;
724 glob->max = max;
725 glob->pubscr = (glob->newreqwin.Type == PUBLICSCREEN);
727 /* fill in RealHandlerInfo */
728 glob->func = (IPTR (*)())myReqHandler;
729 glob->WaitMask = (1 << glob->reqwin->UserPort->mp_SigBit);
730 glob->DoNotWait = TRUE;
732 if (reqhandler) return (CALL_HANDLER);
734 return (LoopReqHandler ((struct rtHandlerInfo *)glob));
737 /****************************************************************************************/
739 static struct Image * REGARGS CreateRectImage (Req_GlobData *glob,
740 struct Image *previmg, int x, int y, int w, int h, int pen, int bgpen)
742 struct Image *img;
744 if (!previmg) return (NULL);
746 img = NewObject (NULL, "fillrectclass",
747 IA_Left, x, IA_Top, y,
748 IA_Width, w, IA_Height, h,
749 IA_FGPen, glob->drinfo->dri_Pens[pen],
750 IA_BGPen, glob->drinfo->dri_Pens[bgpen],
751 IA_Mode, JAM2,
752 (pen == SHINEPEN) ? IA_APattern : TAG_END, (IPTR) pattern,
753 IA_APatSize, 1,
754 TAG_END);
756 previmg->NextImage = img;
758 return (img);
761 /****************************************************************************************/
763 #define RETURN_KEY 13
764 #define ESC_KEY 27
765 #define SHIFT_KEY 0x60
766 #define F1_KEY 0x50
767 #define F10_KEY 0x59
769 #define QUALS_CONSIDERED ( IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND | IEQUALIFIER_LSHIFT | \
770 IEQUALIFIER_RSHIFT | IEQUALIFIER_LALT | IEQUALIFIER_RALT | \
771 IEQUALIFIER_CONTROL )
773 /****************************************************************************************/
775 static IPTR ASM SAVEDS myReqHandler (
776 REGPARAM(a1, Req_GlobData *, glob),
777 REGPARAM(d0, ULONG, sigs),
778 REGPARAM(a0, struct TagItem *, taglist))
780 struct Gadget *tmpgad, *selgad;
781 struct TagItem *tag;
782 struct TagItem *tstate = taglist;
783 struct IntuiMessage *msg;
784 ULONG class, tagdata;
785 UWORD code, qual;
786 int gadid, val, leftamiga, doactgad, copystr;
787 char *str, key;
789 /* uncomment if sigs is no longer ignored */
790 //if (glob->DoNotWait) sigs = 0;
792 doactgad = (glob->mode != IS_EZREQUEST) && !(glob->buttoninfo.lastcode);
794 /* parse tags */
795 while ((tag = NextTagItem (&tstate)))
797 tagdata = tag->ti_Data;
798 if (tag->ti_Tag > RT_TagBase)
800 switch (tag->ti_Tag)
802 case RTRH_EndRequest:
803 glob->arg.retcode = tagdata;
804 return (ReqExit (glob, tagdata));
809 while ((msg = GetWin_GT_Msg (glob->reqwin, glob->imsghook, glob->reqinfo)))
811 class = msg->Class;
812 code = msg->Code;
813 qual = msg->Qualifier;
815 gadid = 0;
816 if (class == IDCMP_RAWKEY && glob->nogad)
818 /* Convert key to ASCII and check if a gadget pops up */
819 if (!(gadid = CheckGadgetKey (code, qual, &key, &glob->buttoninfo)))
821 if (!glob->buttoninfo.lastcode && !(qual & IEQUALIFIER_REPEAT))
823 leftamiga = (qual & IEQUALIFIER_LCOMMAND);
824 selgad = NULL;
826 if (key == RETURN_KEY) selgad = glob->retgad;
827 if (key == ESC_KEY) selgad = glob->nogad;
829 if (!(glob->reqflags & EZREQF_LAMIGAQUAL) || leftamiga)
831 switch (key)
833 case 'V': if (!leftamiga) break;
834 case 'Y': selgad = glob->yesgad; break;
835 case 'B': if (!leftamiga) break;
836 case 'N': case 'R': selgad = glob->nogad; break;
840 if ( ( glob->fkeys ) &&
841 !(qual & QUALS_CONSIDERED) &&
842 (code >= F1_KEY) && (code <= F10_KEY) &&
843 (code - F1_KEY < glob->gadfmtbuff.numlines))
845 LONG i = code - F1_KEY;
847 selgad = glob->yesgad;
849 while( i && selgad )
851 selgad = selgad->NextGadget;
852 --i;
856 if (selgad) my_DownGadget (selgad, code, &glob->buttoninfo);
858 } /* if (!glob->buttoninfo.lastcode && !(qual & IEQUALIFIER_REPEAT)) */
860 } /* if (!(gadid = CheckGadgetKey (code, qual, &key, &glob->buttoninfo))) */
862 } /* if (class == IDCMP_RAWKEY && glob->nogad) */
864 tmpgad = (struct Gadget *)msg->IAddress;
865 Reply_GT_Msg (msg);
867 if (class == IDCMP_REFRESHWINDOW)
869 GT_BeginRefresh (glob->reqwin);
870 GT_EndRefresh (glob->reqwin, TRUE);
871 continue;
874 if (class == IDCMP_GADGETUP || gadid)
876 if (!gadid) gadid = tmpgad->GadgetID;
878 if (gadid < STRINGGADID)
880 if (gadid == 1 || glob->mode == IS_EZREQUEST
881 || glob->mode == ENTER_PASSWORD)
883 glob->arg.retcode = gadid - 1;
884 return (ReqExit (glob, FALSE));
888 if (glob->mode == IS_EZREQUEST) continue;
890 if (glob->mode > ENTER_PASSWORD)
892 if (gadid == STRINGGADID)
894 if (code == 1)
896 doactgad = FALSE;
897 continue;
900 my_SelectGadget ((*glob->arg.buffer || glob->allowempty)
901 ? glob->yesgad : glob->nogad, glob->reqwin);
902 ShortDelay();
905 if (glob->mode == ENTER_STRING)
907 copystr = (glob->arg.buffer[0] != 0);
908 glob->arg.retcode = copystr;
909 if (glob->allowempty) copystr = glob->arg.retcode = TRUE;
910 if (gadid > 2 && gadid < STRINGGADID) glob->arg.retcode = gadid - 1;
911 return (ReqExit (glob, copystr));
914 /* glob->mode == ENTER_NUMBER */
915 if (glob->arg.buffer[0])
917 val = glob->strinfo->LongInt;
918 str = NULL;
919 if (val < glob->min) str = GetStr (glob->catalog, MSG_TOO_SMALL);
920 else if (val > glob->max) str = GetStr (glob->catalog, MSG_TOO_BIG);
921 if (str)
923 if (gadid == STRINGGADID)
924 my_SelectGadget (glob->yesgad, glob->reqwin);
925 SetWinTitleFlash (glob->reqwin, str);
926 continue;
928 *glob->value = val;
931 glob->arg.retcode = (glob->arg.buffer[0] != 0);
932 if (gadid > 2 && gadid < STRINGGADID) glob->arg.retcode = gadid - 1;
934 return (ReqExit (glob, FALSE));
936 } /* if (glob->mode > ENTER_PASSWORD) */
938 if (gadid == STRINGGADID)
940 if (code == 1)
942 doactgad = FALSE;
943 continue;
947 if (glob->arg.buffer[0])
949 if ((str = ((PWCALLBACKFUNPTR)
950 glob->value)(glob->mode, glob->checksum, &glob->arg)))
952 /* Check if return was 'Please verify', MAJOR HACK !! */
953 if (*str != 'P') DisplayBeep (glob->scr);
954 SetWindowTitles (glob->reqwin, str, (char *)~0);
955 my_SetStringGadget (glob->reqwin, glob->strgad, "");
957 else return (ReqExit (glob, glob->arg.retcode));
960 } /* if (glob->mode > ENTER_PASSWORD) */
961 else if (class & glob->idcmp)
963 glob->arg.retcode = glob->idcmp;
964 return (ReqExit (glob, FALSE));
967 } /* while ((msg = GetWin_GT_Msg (glob->reqwin, glob->imsghook, glob->reqinfo))) */
969 if (doactgad)
971 ActivateGadget (glob->strgad, glob->reqwin, NULL);
974 glob->DoNotWait = FALSE;
976 return (CALL_HANDLER);
979 /****************************************************************************************/
981 static ULONG REGARGS ReqExit (Req_GlobData *glob, int cpystr)
983 ULONG ret = glob->arg.retcode;
984 struct Image *img, *img2;
986 if (cpystr && glob->mode <= ENTER_STRING)
987 strcpy (glob->stringbuff, glob->arg.buffer);
989 DoScreenToFront (glob->frontscr, glob->noscreenpop, FALSE);
991 if (glob->reqwin)
993 DoLockWindow (glob->prwin, glob->lockwindow, glob->winlock, FALSE);
994 DoWaitPointer (glob->prwin, glob->waitpointer, FALSE);
995 DoCloseWindow (glob->reqwin, glob->shareidcmp);
998 RT_CloseCatalog (glob->catalog);
999 my_FreeGadgets (glob->buttoninfo.glist);
1000 img = glob->headimg.NextImage;
1002 while (img)
1004 img2 = img->NextImage;
1005 DisposeObject (img);
1006 img = img2;
1009 FreeVec (glob->buff);
1010 FreeVec (glob->gadstrbuff);
1012 if (glob->drinfo) FreeScreenDrawInfo (glob->scr, glob->drinfo);
1014 FreeVisualInfo (glob->visinfo);
1016 if (glob->pubscr) UnlockPubScreen (NULL, glob->scr);
1017 if (glob->reqfont) CloseFont (glob->reqfont);
1019 FreeVec (glob);
1021 return (ret);
1024 /****************************************************************************************/