4 * A program which requests a string from the user and prints it on
7 * Written by Peter Bengtsson who does not agree to be held responsible
8 * for any damage or loss resulting from the use of this program.
10 * Use it as you wish for any and all nice things you can think of.
16 /******************************************************************************
21 RequestString [STRING] [TEXT] [TITLE] [NOGADS] [WIDTH] [SAFE] [PERSIST]
22 [ENCRYPT] [COMPARE] [PUBSCREEN]
26 STRING, TEXT/K, TITLE/K, NOGADS/S, WIDTH/N, SAFE/S, PERSIST/S,
27 ENCRYPT/S, COMPARE/K, PUBSCREEN/K
35 Shows a requester with a string gadget for user input.
39 STRING -- Initial content of string gadget.
41 TITLE -- Title string of requester. This also adds dragbar, closegadget
43 NOGADS -- Suppress gadgets when TITLE argument is given.
44 WIDTH -- Minimal width as number of characters.
45 SAFE -- Hide user input with "*".
46 PERSIST -- Intuition is blocked until requester is quitted.
47 ENCRYPT -- Encrypt result before returning. Requires that one of these
48 environment variables is set: USER, USERNAME or LOGIN.
49 COMPARE -- If the input string is not equal to the argument
50 of COMPARE return WARN.
51 PUBSCREEN -- Open requester on given pubscreen.
66 ******************************************************************************/
68 #include <exec/memory.h>
69 #include <graphics/gfxbase.h>
70 #include <utility/tagitem.h>
71 #include <utility/hooks.h>
72 #include <intuition/sghooks.h>
73 #include <intuition/intuition.h>
75 #include <proto/exec.h>
76 #include <proto/dos.h>
77 #include <proto/intuition.h>
78 #include <proto/graphics.h>
79 #include <proto/gadtools.h>
80 #include <clib/alib_protos.h>
85 AROS_UFP3(ULONG
, HookFunc
,
86 AROS_UFPA(struct Hook
*, TheHook
, A0
),
87 AROS_UFPA(struct SGWork
*, Obj
, A2
),
88 AROS_UFPA(UBYTE
*, Mess
, A1
));
91 #define TEMPLATE "STRING,TEXT/K,TITLE/K,NOGADS/S,WIDTH/N,SAFE/S,PERSIST/S,ENCRYPT/S,COMPARE/K,PUBSCREEN/K"
93 #define NArgs 10 /* Number of arguments */
106 #define MINWIDTH 8 /* Minimum width of gadget in characters */
108 const char version
[] = "\0$VER: RequestString 39.5 (06.07.2009)";
115 char CBuffer
[12], UName
[48];
116 struct TextExtent TExtent
;
117 struct Hook SGHook
= { {0} , 0, 0, 0};
118 struct RDArgs
*Args
= NULL
;
119 struct ExtIntuiMessage
*EIMess
= NULL
;
120 struct Gadget
*Gad
= NULL
, *GList
= NULL
;
121 struct Window
*Win
= NULL
;
122 struct Screen
*Scr
= NULL
;
123 char *ReturnText
= NULL
;
125 int WWidth
= 0, WHeight
= 0;
126 int GWidth
= 32, GHeight
= 0;
127 long TXPos
= 0, TYPos
= 0;
129 int TWidth
= 0, THeight
= 0;
133 struct TagItem WindowTags
[] =
142 {WA_DepthGadget
, FALSE
},
143 {WA_CloseGadget
, FALSE
},
145 {WA_IDCMP
, IDCMP_GADGETUP
| IDCMP_INACTIVEWINDOW
| IDCMP_ACTIVEWINDOW
| IDCMP_REFRESHWINDOW
| IDCMP_CLOSEWINDOW
},
146 {WA_SizeGadget
, FALSE
},
150 struct NewGadget StringGad
= {10, 5, 80, 15, NULL
, NULL
, 0, 0, NULL
, NULL
};
152 memset(ArgList
, 0, sizeof(ArgList
)); /* Clear the ArgList array */
154 if ((Args
= ReadArgs(TEMPLATE
, ArgList
, NULL
)) != NULL
)
156 if ((Scr
= LockPubScreen((UBYTE
*)ArgList
[PUBSCREEN
])) != NULL
)
158 if ((VisInfo
= GetVisualInfo(Scr
, NULL
)) != NULL
)
160 if ((Gad
= CreateContext(&GList
)) != NULL
)
162 if (ArgList
[WIDTH
] != 0)
163 GWidth
= *((LONG
*)ArgList
[WIDTH
]);
164 if (GWidth
< MINWIDTH
)
167 GHeight
= Scr
->RastPort
.TxHeight
+ 6;
168 WHeight
= GHeight
+ Scr
->WBorTop
+ Scr
->WBorBottom
+ 8;
170 GWidth
= GWidth
* Scr
->RastPort
.TxWidth
;
172 /* Forbid()/Permit() around this following poking in GfxBase? */
173 FontExtent(GfxBase
->DefaultFont
, &TExtent
);
175 if (ArgList
[TEXT
] != 0)
177 TLength
= strlen((char *)ArgList
[TEXT
]);
178 TWidth
= TExtent
.te_Width
* TLength
;
179 THeight
= TExtent
.te_Height
;
185 WWidth
= GWidth
+ Scr
->WBorLeft
+ Scr
->WBorRight
+ 6;
189 WWidth
= TWidth
+ Scr
->WBorLeft
+ Scr
->WBorRight
+ 6;
192 if (WWidth
> Scr
->Width
)
195 if (GWidth
+ Scr
->WBorLeft
+ Scr
->WBorRight
> WWidth
)
197 GWidth
= WWidth
- Scr
->WBorLeft
- Scr
->WBorRight
;
199 if (TWidth
+ Scr
->WBorLeft
+ Scr
->WBorRight
> WWidth
)
201 TWidth
= WWidth
- Scr
->WBorLeft
- Scr
->WBorRight
;
205 /* If the window has a title, it will also have a dragbar, closegadget
208 if (ArgList
[TITLE
] != 0)
210 WindowTags
[6].ti_Data
= TRUE
;
211 if (ArgList
[NOGADS
] == 0)
213 WindowTags
[7].ti_Data
= TRUE
;
214 WindowTags
[8].ti_Data
= TRUE
;
216 WindowTags
[9].ti_Data
= ArgList
[TITLE
];
217 WHeight
+= Scr
->BarHeight
;
220 StringGad
.ng_VisualInfo
= VisInfo
;
221 StringGad
.ng_Width
= GWidth
;
222 StringGad
.ng_Height
= GHeight
;
223 StringGad
.ng_TopEdge
= WHeight
- GHeight
- Scr
->WBorBottom
- 3;
224 StringGad
.ng_LeftEdge
= (WWidth
- GWidth
) / 2;
226 /* Initialize the Hook if we are using a safe stringgadget.
227 * SGHook.d_Data points to storage space for the string which
228 * will be returned. Memory should be cleared.
231 if (ArgList
[SAFE
] != 0)
233 SGHook
.h_Entry
= (HOOKFUNC
)HookFunc
;
234 /* SGHook.h_SubEntry=NULL; */
235 SGHook
.h_Data
= AllocVec(98, MEMF_ANY
| MEMF_CLEAR
); /* Should be made dynamic if possible */
236 if (ArgList
[STRING
] != 0)
239 strcpy((char *)SGHook
.h_Data
, (char *)ArgList
[STRING
]);
240 while (((char *)ArgList
[STRING
])[++i
] != 0)
241 ((char *)ArgList
[STRING
])[i
] = '*';
252 GTST_EditHook
, (ArgList
[SAFE
] == 0) ? NULL
: &SGHook
,
253 GTST_String
, ArgList
[STRING
],
260 WindowTags
[0].ti_Data
= (IPTR
)Scr
;
261 WindowTags
[1].ti_Data
= (IPTR
)GList
;
263 WindowTags
[4].ti_Data
= WWidth
;
264 WindowTags
[5].ti_Data
= WHeight
;
266 WindowTags
[2].ti_Data
= (Scr
->Width
-WWidth
) >> 1;
267 WindowTags
[3].ti_Data
= (Scr
->Height
-WHeight
) >> 1;
269 if ((Win
= OpenWindowTagList(NULL
, WindowTags
)) != NULL
)
271 /* Is there some (un)informative text in the window? */
273 if (ArgList
[TEXT
] != 0)
275 /* Colour should rather be selected with thougt to the background of the window, fix this. */
276 SetAPen(Win
->RPort
, 1);
277 TXPos
= (WWidth
- TWidth
) / 2;
278 TYPos
= GfxBase
->DefaultFont
->tf_Baseline
+ Win
->BorderTop
+ 1;
279 Move(Win
->RPort
, TXPos
, TYPos
);
280 Text(Win
->RPort
, (char *)ArgList
[TEXT
], TLength
);
285 WaitPort(Win
->UserPort
);
286 EIMess
= (struct ExtIntuiMessage
*)GT_GetIMsg(Win
->UserPort
);
287 MsgClass
=EIMess
->eim_IntuiMessage
.Class
;
288 GT_ReplyIMsg((struct IntuiMessage
*)EIMess
);
292 case IDCMP_ACTIVEWINDOW
:
293 ActivateGadget(Gad
, Win
, NULL
);
296 case IDCMP_INACTIVEWINDOW
:
297 if (ArgList
[PERSIST
])
299 ScreenToFront(Win
->WScreen
);
305 case IDCMP_REFRESHWINDOW
:
306 GT_BeginRefresh(Win
);
307 if (ArgList
[TEXT
] != 0)
309 Move(Win
->RPort
, TXPos
, TYPos
);
310 Text(Win
->RPort
, (char *)ArgList
[TEXT
], TLength
);
312 GT_EndRefresh(Win
,TRUE
);
317 while ((MsgClass
!= IDCMP_GADGETUP
) && (MsgClass
!= IDCMP_CLOSEWINDOW
));
319 GT_GetGadgetAttrs(Gad
, Win
, NULL
, GTST_String
, &ReturnText
, TAG_END
);
321 if (ArgList
[SAFE
] != 0)
322 ReturnText
= (char *)SGHook
.h_Data
;
324 /* Try to find out who the user is if we are to encrypt the output. */
325 /* I really don't know how to acquire the username, but this might */
326 /* be a good guess of how to do it. */
328 if (ArgList
[ENCRYPT
] != 0)
330 if (GetVar("USER", UName
, 47, 0) == -1)
331 if (GetVar("USERNAME", UName
, 47, 0) == -1)
332 if (GetVar("LOGIN", UName
, 47, 0) == -1)
334 ACrypt(CBuffer
, ReturnText
, UName
);
335 ReturnText
= CBuffer
;
338 Printf("\"%s\"\n", ReturnText
);
340 /* Here follows the COMPARE parameter. If the input string is not equal
341 * to the argument of COMPARE we return WARN.
344 if (ArgList
[COMPARE
] != 0)
345 Ret
= (strcmp(ReturnText
, (char *)ArgList
[COMPARE
])) ? RETURN_WARN
: 0;
354 else if (ArgList
[PUBSCREEN
] != 0)
359 PrintFault(IoErr(), "RequestString");
363 if (SGHook
.h_Data
!= NULL
)
364 FreeVec(SGHook
.h_Data
);
372 FreeVisualInfo(VisInfo
);
374 UnlockPubScreen(NULL
, Scr
);
380 /* EditHook function for safe stringgadgets */
382 AROS_UFH3(ULONG
, HookFunc
,
383 AROS_UFHA(struct Hook
*, TheHook
, A0
),
384 AROS_UFHA(struct SGWork
*, Obj
, A2
),
385 AROS_UFHA(UBYTE
*, Mess
, A1
))
390 char * const Tmp
=(char *)TheHook
->h_Data
;
392 if (Mess
[0] == SGH_KEY
)
394 Obj
->Actions
|= SGA_USE
;
398 case EO_DELBACKWARD
:
399 i0
= Obj
->StringInfo
->BufferPos
;
400 i1
= Obj
->StringInfo
->NumChars
- Obj
->NumChars
;
401 strcpy(&Tmp
[i0
- i1
], &Tmp
[i0
]);
405 i0
= Obj
->StringInfo
->BufferPos
;
406 i1
= Obj
->StringInfo
->NumChars
- Obj
->NumChars
;
407 strcpy(&Tmp
[i0
], &Tmp
[i0
+ i1
]);
419 if (strlen(Tmp
) > 96)
420 Obj
->Actions
&= ~SGA_USE
;
421 i0
= Obj
->StringInfo
->BufferPos
;
422 Obj
->WorkBuffer
[i0
] = '*';
423 i1
= strlen(Tmp
) + 1;
425 Tmp
[i1
+ 1] = Tmp
[i1
];
433 case EO_BIGCHANGE
: /* Not Allowed */
436 Obj
->Actions
&= ~SGA_USE
;
443 Obj
->Actions
&= ~ SGA_USE
;