Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / reqtools / req.c
blob83eef2a14d7b79966a01032764caf8c7c7989732
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/types.h>
7 #include <exec/io.h>
8 #include <exec/memory.h>
9 #include <intuition/intuition.h>
10 #include <intuition/intuitionbase.h>
11 #include <intuition/sghooks.h>
12 #include <intuition/imageclass.h>
13 #include <libraries/dos.h>
14 #include <libraries/gadtools.h>
15 #include <libraries/reqtools.h>
16 #include <proto/exec.h>
17 #include <proto/gadtools.h>
18 #include <proto/graphics.h>
19 #include <proto/intuition.h>
20 #include <proto/utility.h>
21 #include <proto/reqtools.h>
22 #include <string.h>
24 #include "filereq.h"
27 #include "rtlocale.h"
29 /****************************************************************************************/
31 #ifndef __AROS__
33 #ifdef __SASC
34 #pragma libcall ReqToolsBase rtLockPrefs a8 00
35 #pragma libcall ReqToolsBase rtUnlockPrefs ae 00
36 #else
37 #warning You might have to fix rtLockPrefs/rtUnlockPrefs for your compiler
38 #endif
40 #endif
42 /****************************************************************************************/
44 #define ThisProcess() ( ( struct Process * ) FindTask( NULL ) )
46 /****************************************************************************************/
48 struct PWCallBackArgs
50 char *buffer;
51 ULONG lastchecksum, verify, retcode;
54 /****************************************************************************************/
56 extern IPTR ASM LoopReqHandler (ASM_REGPARAM(a1, struct rtHandlerInfo *,));
57 extern void REGARGS SetWinTitleFlash (struct Window *, char *);
58 extern void ShortDelay (void);
59 extern ULONG ASM myTextLength (ASM_REGPARAM(a1, char *,),
60 ASM_REGPARAM(a0, struct TextAttr *,),
61 ASM_REGPARAM(a3, UBYTE *,),
62 ASM_REGPARAM(a2, struct Image *,),
63 ASM_REGPARAM(d7, ULONG,));
65 extern struct ReqToolsBase *ReqToolsBase;
66 extern struct DosLibrary *DOSBase;
67 extern struct IntuitionBase *IntuitionBase;
68 extern struct Library *GadToolsBase;
69 extern struct GfxBase *GfxBase;
71 /****************************************************************************************/
73 struct FmtBuff
75 long numlines, bufflen;
78 #define DOFMT_COUNTNEWLINES 0
79 #define DOFMT_COUNTBARS 1
81 /****************************************************************************************/
84 extern APTR ASM DofmtCount (ASM_REGPARAM(a0, char *,),
85 ASM_REGPARAM(a1, APTR,),
86 ASM_REGPARAM(a3, struct FmtBuff *,),
87 ASM_REGPARAM(d0, int,));
88 extern APTR STDARGS DofmtArgs (char *, char *,...);
91 extern void ASM FillBarTable (ASM_REGPARAM(a1, char **,), ASM_REGPARAM(a0, char *,));
92 extern void ASM FillNewLineTable (ASM_REGPARAM(a1, char **,), ASM_REGPARAM(a0, char *,));
94 /****************************************************************************************/
96 typedef struct Req_RealHandlerInfo Req_GlobData;
97 #define STRINGGADID 32
99 struct Req_RealHandlerInfo
101 ULONG (*func)(); /* private */
102 ULONG WaitMask;
103 ULONG DoNotWait;
105 /* PRIVATE */
106 char **gadstrbuff, **buff, *stringbuff, *textfmt;
107 struct PWCallBackArgs arg;
108 struct Gadget *strgad, *yesgad, *nogad, *retgad, *selgad;
109 struct TextAttr boldattr;
110 struct KeyButtonInfo buttoninfo;
111 struct StringInfo *strinfo;
112 struct Screen *scr, *frontscr;
113 struct Window *prwin;
114 struct Window *reqwin;
115 struct DrawInfo *drinfo;
116 struct rtReqInfo *reqinfo;
117 struct Hook *imsghook, backfillhook;
118 struct TextFont *reqfont;
119 struct Catalog *catalog;
120 struct Image headimg;
121 struct NewWindow newreqwin;
122 struct FmtBuff bodyfmt, gadfmtbuff;
123 UBYTE minmaxstr[30];
124 int idcmp, mode, min, max, checksum, pubscr, reqflags;
125 int retnum, waitpointer, allowempty, lockwindow, shareidcmp, noscreenpop;
126 int textht, texttop, strgadht, strgadtop, width, nowinbackfill;
127 int numlines, len, fontht, minmax, minmaxlen, minmaxtop, minmaxleft;
128 int fkeys;
129 APTR winlock, visinfo;
130 ULONG *value, *lenptr;
133 /****************************************************************************************/
135 static CONST UWORD pattern[] = { 0xAAAA,0x5555 };
137 static ULONG REGARGS ReqExit (Req_GlobData *, int);
138 static struct Image * REGARGS CreateRectImage
139 (Req_GlobData *, struct Image *, int, int, int, int, int, int);
140 static ULONG ASM SAVEDS myReqHandler (REGPARAM(a1, Req_GlobData *,),
141 REGPARAM(d0, ULONG,),
142 REGPARAM(a0, struct TagItem *,));
144 /****************************************************************************************/
146 #define GETSTRINGLONG_FLAGS (GSREQF_CENTERTEXT|GSREQF_HIGHLIGHTTEXT)
147 #define EZREQ_FLAGS (EZREQF_NORETURNKEY|EZREQF_LAMIGAQUAL|EZREQF_CENTERTEXT)
150 /****************************************************************************************/
152 ULONG ASM SAVEDS GetString (
153 REGPARAM(a1, UBYTE *, stringbuff), /* str in case of rtEZRequestA */
154 REGPARAM(d0, LONG, maxlen), /* args in case of rtEZRequestA */
155 REGPARAM(a2, char *, title), /* gadfmt in case of rtEZRequestA */
156 REGPARAM(d1, ULONG, checksum),
157 REGPARAM(d2, ULONG *, value),
158 REGPARAM(d3, LONG, mode),
159 REGPARAM(d4, struct rtReqInfo *, reqinfo),
160 REGPARAM(a0, struct TagItem *, taglist))
162 /* #define CLEARSIZE (28+sizeof(struct NewWindow)+sizeof(struct IntuiText)+\
163 sizeof(struct NewGadget)+2*sizeof(struct FmtBuff)) */
165 // FIXME: obsolete comment?
166 /* keep these vars together and just BEFORE NewWindow struct! */
167 /*-------------------------------------------------*/
168 int reqpos = REQPOS_DEFAULT;
169 char *pubname = NULL;
170 ULONG underscore = 0;
171 struct TextAttr *fontattr = NULL;
172 struct Locale *locale = NULL;
173 struct IntuiText itxt, *bodyitxt = NULL;
174 struct NewGadget ng;
175 struct Image *img;
176 /**/
177 // FIXME: obsolete comment?
178 /* KEEP MIN AND MAX IN THIS ORDER !!!! */
179 int max = MAXINT, min = MININT;
180 /**/
181 Req_GlobData *glob;
182 struct Gadget *gad;
183 struct TagItem *tag, *tstate;
184 /* for rtEZRequestA */
185 char *gadfmt = title;
186 char *ptr;
187 int val, spacing, reqhandler = FALSE, nogadfmt, gadlen = 0;
188 int height, top, showdef = TRUE;
189 int scrwidth, scrheight, i, j, npos, nlen, nogadgets, retnum;
190 int invisible, scrfontht, gadlines = 0;
191 int leftoff, rightoff;
192 ULONG *gadlenptr = NULL, *gadposptr = NULL, idcmpflags;
193 APTR gadfmtargs = NULL, textfmtargs = NULL, args;
195 memset (&itxt, 0, sizeof (struct IntuiText));
196 memset (&ng, 0, sizeof (struct NewGadget));
198 if (!(glob = AllocVec (sizeof (Req_GlobData), MEMF_PUBLIC | MEMF_CLEAR)))
199 return (FALSE);
201 glob->mode = mode;
202 glob->checksum = checksum;
203 glob->value = value;
204 glob->stringbuff = stringbuff;
205 glob->fkeys = rtLockPrefs()->Flags & RTPRF_FKEYS;
206 rtUnlockPrefs();
208 nogadfmt = (mode != IS_EZREQUEST);
209 invisible = (mode <= ENTER_PASSWORD);
211 if (mode == IS_EZREQUEST) title = NULL;
212 if (mode == ENTER_STRING) glob->width = 350; else glob->width = 180;
213 retnum = 1;
214 if ((glob->reqinfo = reqinfo))
216 if (reqinfo->Width) glob->width = reqinfo->Width;
217 if (reqinfo->ReqTitle) title = reqinfo->ReqTitle;
218 if (reqinfo->ReqPos != REQPOS_DEFAULT) reqpos = reqinfo->ReqPos;
220 glob->newreqwin.LeftEdge = reqinfo->LeftOffset;
221 glob->newreqwin.TopEdge = reqinfo->TopOffset;
222 glob->reqflags = reqinfo->Flags;
223 glob->waitpointer = reqinfo->WaitPointer;
224 glob->lockwindow = reqinfo->LockWindow;
225 glob->shareidcmp = reqinfo->ShareIDCMP;
226 glob->imsghook = reqinfo->IntuiMsgFunc;
229 /* parse tags */
230 tstate = taglist;
231 while ((tag = NextTagItem (&tstate)))
233 IPTR tagdata = tag->ti_Data;
234 if (tag->ti_Tag > RT_TagBase)
236 switch (tag->ti_Tag)
238 case RT_Window: glob->prwin = (struct Window *)tagdata; break;
239 case RT_IDCMPFlags: glob->idcmp = tagdata; break;
240 case RT_ReqPos: reqpos = tagdata; break;
241 case RT_LeftOffset: glob->newreqwin.LeftEdge = tagdata; break;
242 case RT_TopOffset: glob->newreqwin.TopEdge = tagdata; break;
243 case RT_PubScrName: pubname = (char *)tagdata; break;
244 case RT_Screen: glob->scr = (struct Screen *)tagdata; break;
245 case RT_ReqHandler: *(APTR *)tagdata = glob;
246 reqhandler = TRUE;
247 break;
248 case RT_WaitPointer: glob->waitpointer = tagdata; break;
249 case RT_Underscore: underscore = tagdata; break;
250 case RT_ShareIDCMP: glob->shareidcmp = tagdata; break;
251 case RT_LockWindow: glob->lockwindow = tagdata; break;
252 case RT_ScreenToFront: glob->noscreenpop = !tagdata; break;
253 case RT_TextAttr: fontattr = (struct TextAttr *)tagdata; break;
254 case RT_IntuiMsgFunc: glob->imsghook = (struct Hook *)tagdata; break;
255 case RT_Locale: locale = (struct Locale *)tagdata; break;
256 case RTEZ_ReqTitle: if (mode == IS_EZREQUEST) title = (char *)tagdata;
257 break;
258 /* RTGS_Flags == RTGL_Flags == RTEZ_Flags */
259 case RTEZ_Flags: glob->reqflags = tagdata; break;
260 case RTEZ_DefaultResponse: retnum = tagdata; break;
261 case RTGL_Min: min = tagdata; glob->minmax = TRUE; break;
262 case RTGL_Max: max = tagdata; glob->minmax = TRUE; break;
263 /* RTGS_Width == RTGL_Width */
264 case RTGL_Width: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
265 glob->width = tagdata;
266 break;
267 case RTGL_ShowDefault: showdef = tagdata; break;
268 /* RTGS_GadFmt == RTGL_GadFmt */
269 case RTGL_GadFmt: nogadfmt = FALSE;
270 gadfmt = (char *)tagdata;
271 break;
272 /* RTGS_GadFmtArgs == RTGL_GadFmtArgs */
273 case RTGL_GadFmtArgs: gadfmtargs = (APTR)tagdata; break;
274 /* RTGS_Invisible == RTGL_Invisible */
275 case RTGL_Invisible: invisible = tagdata; break;
276 /* RTGS_BackFill == RTGL_BackFill */
277 case RTGL_BackFill: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
278 glob->nowinbackfill = !tagdata;
279 break;
280 /* RTGS_TextFmt == RTGL_TextFmt */
281 case RTGL_TextFmt: if (mode == ENTER_NUMBER || mode == ENTER_STRING)
282 glob->textfmt = (char *)tagdata;
283 break;
284 /* RTGS_TextFmtArgs == RTGL_TextFmtArgs */
285 case RTGL_TextFmtArgs: textfmtargs = (APTR)tagdata; break;
286 case RTGS_AllowEmpty: glob->allowempty = tagdata; break;
288 } /* switch (tag->ti_Tag) */
290 } /* if (tag->ti_Tag > RT_TagBase)*/
292 } /* while ((tag = NextTagItem (&tstate))) */
294 glob->catalog = RT_OpenCatalog (locale);
296 /* ignore RTGL_Min and RTGL_Max if not rtNewGetLongA() */
297 if (mode != ENTER_NUMBER) glob->minmax = FALSE;
298 retnum++;
299 glob->newreqwin.Flags = WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_ACTIVATE
300 |WFLG_SIMPLE_REFRESH|WFLG_RMBTRAP;
302 idcmpflags = glob->idcmp | IDCMP_REFRESHWINDOW|IDCMP_GADGETUP|IDCMP_RAWKEY;
303 if (mode != IS_EZREQUEST) idcmpflags |= IDCMP_MOUSEBUTTONS|IDCMP_ACTIVEWINDOW;
305 if (!glob->prwin || !glob->prwin->UserPort
306 || (glob->prwin->UserPort->mp_SigTask != ThisProcess()))
307 glob->shareidcmp = FALSE;
309 if (!(glob->scr = GetReqScreen (&glob->newreqwin, &glob->prwin, glob->scr, pubname)))
310 return (ReqExit (glob, FALSE));
312 spacing = rtGetVScreenSize (glob->scr, (ULONG *)&scrwidth, (ULONG *)&scrheight);
314 if (fontattr)
316 if (!(glob->reqfont = OpenFont (fontattr))) fontattr = NULL;
319 if (!fontattr) fontattr = glob->scr->Font;
321 if (!(glob->visinfo = GetVisualInfoA (glob->scr, NULL))
322 || !(glob->drinfo = GetScreenDrawInfo (glob->scr)))
323 return (ReqExit (glob, FALSE));
325 itxt.ITextFont = fontattr;
326 glob->boldattr = *fontattr;
327 glob->boldattr.ta_Style |= FSF_BOLD;
328 glob->fontht = fontattr->ta_YSize;
329 scrfontht = glob->scr->Font->ta_YSize;
330 leftoff = glob->scr->WBorLeft + 4;
331 rightoff = glob->scr->WBorRight + 4;
333 /* Calculate the width, height and position of the requester window. We try
334 to position the window as close to the mouse as possible (default). */
336 if (mode != IS_EZREQUEST)
338 if (nogadfmt)
340 underscore = '_';
341 gadfmt = GetStr (glob->catalog, MSG_OK_BAR_CANCEL);
342 if (mode <= ENTER_PASSWORD)
344 gadfmt = GetStr (glob->catalog, MSG_LAST_BAR_CANCEL);
345 if (!stringbuff[0] || mode == CHECK_PASSWORD)
346 while (*gadfmt && (*gadfmt++ != '|'));
349 glob->reqflags &= GETSTRINGLONG_FLAGS;
350 glob->reqflags |= EZREQF_NORETURNKEY;
352 else
354 glob->reqflags &= EZREQ_FLAGS;
355 glob->textfmt = stringbuff;
356 textfmtargs = (APTR)(IPTR)maxlen;
359 if (glob->textfmt)
361 /* Calculate size of buffer needed to expand format string, also
362 calculates number of lines in format string.
363 (APTR)maxlen points to the arguments! */
365 DofmtCount (glob->textfmt, textfmtargs, &glob->bodyfmt, DOFMT_COUNTNEWLINES);
366 glob->numlines = glob->bodyfmt.numlines;
368 if (!(glob->buff = (char **)AllocVec (glob->bodyfmt.bufflen
369 + (8 + (int)sizeof (struct IntuiText)) * glob->numlines, MEMF_PUBLIC)))
370 return (ReqExit (glob, FALSE));
372 /* expand format string and fill in table of pointers to each line */
373 glob->lenptr = (ULONG *)&glob->buff[glob->numlines];
374 bodyitxt = (struct IntuiText *)&glob->lenptr[glob->numlines];
375 ptr = (char *)&bodyitxt[glob->numlines];
376 args = Dofmt (ptr, glob->textfmt, textfmtargs);
378 if (mode == IS_EZREQUEST) gadfmtargs = args;
379 FillNewLineTable (glob->buff, ptr);
381 /* Calculate width on screen of each line, remember largest */
382 for (i = 0, glob->len = 0; i < glob->numlines; i++)
384 itxt.IText = (UBYTE *)glob->buff[i];
385 j = glob->lenptr[i] = IntuiTextLength (&itxt);
386 if (j > glob->len) glob->len = j;
388 glob->width = glob->len + 70;
391 nogadgets = (gadfmt == NULL);
393 if (!nogadgets)
395 DofmtCount (gadfmt, gadfmtargs, &glob->gadfmtbuff, DOFMT_COUNTBARS);
396 gadlines = glob->gadfmtbuff.numlines;
397 glob->gadfmtbuff.bufflen += 12 * 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 DofmtArgs (glob->minmaxstr, (max != 0x7FFFFFFF) ?
456 GetStr (glob->catalog, MSG_MIN_MAX_FMT) :
457 GetStr (glob->catalog, MSG_MIN_FMT),
458 min, max);
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 = (ULONG (*)())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 ULONG 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 /****************************************************************************************/