2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: vgsiaform.c /main/5 1996/05/07 12:22:34 drk $ */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
26 * (c) Copyright 1993, 1994 International Business Machines Corp. *
27 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
28 * (c) Copyright 1993, 1994 Novell, Inc. *
37 * Revision 1.1.2.2 1995/06/06 19:39:54 Chris_Beute
38 * New file added for SIA password expiration forms handling
39 * [1995/05/31 19:52:41 Chris_Beute]
41 * Revision 1.1.2.2 1995/05/22 18:13:32 Peter_Derr
42 * Add a Cancel button.
43 * [1995/05/15 18:06:21 Peter_Derr]
45 * Support SIAMENUONE and SIAMENUANY
46 * [1995/05/12 20:29:53 Peter_Derr]
49 * [1995/05/11 22:09:09 Peter_Derr]
61 #include <Xm/RowColumn.h>
63 #include <Xm/ToggleBG.h>
65 XmString multiline_xmstring(char *);
66 static void NoEchoCB( Widget, XtPointer, XtPointer);
67 static void RespondSiaFormCB( Widget, XtPointer, XtPointer);
68 static void CancelSiaFormCB( Widget, XtPointer, XtPointer);
69 static void SiaBackspace( Widget, XEvent *, char **, Cardinal *);
72 static char textEventBindings[] = {
73 "<Key>Return: next-tab-group()"
76 static char activateBindings[] = {
77 "<Key>osfActivate: activate()\n\
78 Ctrl <Key>Return: activate()\n\
79 <Key>Return: activate()"
82 static char activatePBBindings[] = {
83 "<Key>osfActivate: ArmAndActivate()\n\
84 Ctrl <Key>Return: ArmAndActivate()\n\
85 <Key>Return: ArmAndActivate()"
88 static char noEchoBindings[] = {
89 "Ctrl<Key>: my-insert()\n\
90 <Key>osfBackSpace: sia-bksp()\n\
91 <Key>osfDelete: sia-bksp()"
94 static XtActionsRec textActions[] = {
95 {"sia-bksp", (XtActionProc)SiaBackspace},
100 SiaFormInfo *globalSiaFormInfo;
102 /***************************************************************************
106 * Widgets: sia_form, sia_title, sia_prompts
107 ***************************************************************************/
110 SiaForm(SiaFormInfo *siaFormInfo)
114 LoginTextPtr textdata;
115 XtTranslations textTable;
116 Widget sia_form, title_label, ok_button, cancel_button, prompts_row_col;
117 Widget *prompt_labels;
118 Widget *prompt_answers;
120 XtTranslations noecho_trans, text_trans, activate_trans, activatePBtrans;
122 globalSiaFormInfo = siaFormInfo;
123 siaFormInfo->collect_status = 1;
125 * XmCreateFormDialog()
127 * XmCreateRowColumn()
130 * XmCreateTextField()
132 * add ModifyVerify callback
134 * PB callback will collect answers, send them down the pipe
135 * and destroy the sia_form.
140 * create the SIA form
145 XtSetArg(argt[i], XmNmarginHeight, MBOX_MARGIN_HEIGHT ); i++;
146 XtSetArg(argt[i], XmNmarginWidth, MBOX_MARGIN_WIDTH ); i++;
147 XtSetArg(argt[i], XmNshadowThickness, SHADOW_THICKNESS ); i++;
148 XtSetArg(argt[i], XmNnoResize, False ); i++;
149 XtSetArg(argt[i], XmNresizePolicy, XmRESIZE_ANY ); i++;
151 sia_form = XmCreateFormDialog(login_shell, "sia_form", argt, i);
152 siaFormInfo->sia_form_widget = sia_form;
155 * create the title label
159 XtSetArg(argt[i], XmNlabelString, siaFormInfo->title ); i++;
160 XtSetArg(argt[i], XmNtraversalOn, False ); i++;
161 XtSetArg(argt[i], XmNtopAttachment, XmATTACH_FORM ); i++;
162 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM ); i++;
163 XtSetArg(argt[i], XmNrightAttachment, XmATTACH_FORM ); i++;
164 XtSetArg(argt[i], XmNalignment, XmALIGNMENT_CENTER ); i++;
165 xmstr = multiline_xmstring(siaFormInfo->title);
166 XtSetArg(argt[i], XmNlabelString, xmstr ); i++;
168 title_label = XmCreateLabel(sia_form, "title_label", argt, i);
169 XtManageChild(title_label);
176 activate_trans = XtParseTranslationTable(activateBindings);
177 activatePBtrans = XtParseTranslationTable(activatePBBindings);
180 XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_FORM ); i++;
181 XtSetArg(argt[i], XmNtraversalOn, True ); i++;
182 xmstr = ReadCatalogXms(MC_LABEL_SET, MC_OK_LABEL, MC_DEF_OK_LABEL );
183 XtSetArg(argt[i], XmNlabelString, xmstr ); i++;
185 ok_button = XmCreatePushButton(sia_form, "ok_button", argt, i);
187 XtOverrideTranslations(ok_button, activatePBtrans);
190 XtManageChild(ok_button);
192 XtAddCallback(ok_button, XmNactivateCallback, RespondSiaFormCB,
199 XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_FORM ); i++;
200 XtSetArg(argt[i], XmNtraversalOn, True ); i++;
201 xmstr = ReadCatalogXms(MC_LABEL_SET, MC_CANCEL_LABEL, MC_DEF_CANCEL_LABEL );
202 XtSetArg(argt[i], XmNlabelString, xmstr ); i++;
204 cancel_button = XmCreatePushButton(sia_form, "cancel_button", argt, i);
207 XtManageChild(cancel_button);
209 XtAddCallback(cancel_button, XmNactivateCallback, CancelSiaFormCB,
213 * create the RowColumn widget for prompts
217 XtSetArg(argt[i], XmNorientation, XmHORIZONTAL ); i++;
218 XtSetArg(argt[i], XmNentryVerticalAlignment, XmALIGNMENT_CENTER ); i++;
219 XtSetArg(argt[i], XmNrowColumnType, XmWORK_AREA ); i++;
220 XtSetArg(argt[i], XmNnumColumns, siaFormInfo->num_prompts); i++;
221 XtSetArg(argt[i], XmNpacking, XmPACK_COLUMN ); i++;
222 XtSetArg(argt[i], XmNtopAttachment, XmATTACH_WIDGET ); i++;
223 XtSetArg(argt[i], XmNtopWidget, title_label ); i++;
224 XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_WIDGET ); i++;
225 XtSetArg(argt[i], XmNbottomWidget, ok_button ); i++;
226 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM ); i++;
227 XtSetArg(argt[i], XmNrightAttachment, XmATTACH_FORM ); i++;
229 switch (siaFormInfo->rendition)
232 XtSetArg(argt[i], XmNradioBehavior, True ); i++;
235 XtSetArg(argt[i], XmNisHomogeneous, True ); i++;
236 XtSetArg(argt[i], XmNentryClass, xmToggleButtonGadgetClass); i++;
237 XtSetArg(argt[i], XmNentryAlignment, XmALIGNMENT_BEGINNING ); i++;
243 XtSetArg(argt[i], XmNentryAlignment, XmALIGNMENT_END ); i++;
246 prompts_row_col = XmCreateRowColumn(sia_form, "prompts_row_col", argt, i);
247 XtManageChild(prompts_row_col);
249 prompt_labels = (Widget *) alloca(sizeof(Widget *) * siaFormInfo->num_prompts);
250 prompt_answers = siaFormInfo->answer_widgets;
252 noecho_trans = XtParseTranslationTable(noEchoBindings);
253 text_trans = XtParseTranslationTable(textEventBindings);
255 for (j=0; j<siaFormInfo->num_prompts; j++)
258 * create the prompt label
261 char answer_name[81];
263 sprintf(label_name,"Prompt %d",j);
264 sprintf(answer_name,"Answer %d",j);
265 xmstr = multiline_xmstring(siaFormInfo->prompts[j]);
267 switch (siaFormInfo->rendition)
272 /* i = InitArg(ToggleBG); */
274 XtSetArg(argt[i], XmNtraversalOn, True ); i++;
275 XtSetArg(argt[i], XmNlabelString, xmstr ); i++;
277 prompt_answers[j] = XmCreateToggleButtonGadget(prompts_row_col,
278 answer_name, argt, i);
287 XtSetArg(argt[i], XmNtraversalOn, True ); i++;
288 XtSetArg(argt[i], XmNlabelString, xmstr ); i++;
290 prompt_labels[j] = XmCreateLabel(prompts_row_col, label_name,
292 XtManageChild(prompt_labels[j]);
295 * create the answer text field
299 XtSetArg(argt[i], XmNselectionArrayCount, 1 ); i++;
300 XtSetArg(argt[i], XmNmaxLength, 80 ); i++;
301 XtSetArg(argt[i], XmNmappedWhenManaged, True ); i++;
303 XtAddActions(textActions, 1);
304 prompt_answers[j] = XmCreateTextField(prompts_row_col,
305 answer_name, argt, i);
306 /* Make Return advance to next field. */
307 XtOverrideTranslations(prompt_answers[j], text_trans);
309 if (!siaFormInfo->visible[j])
312 * allocate the answer buffer
314 siaFormInfo->answers[j] = XtMalloc(SIAMXPASSWORD+1);
315 (siaFormInfo->answers[j])[0] = '\0';
317 XtAddCallback(prompt_answers[j], XmNmodifyVerifyCallback,
318 NoEchoCB, siaFormInfo);
319 XtAddCallback(prompt_answers[j], XmNmotionVerifyCallback,
320 NoEchoCB, siaFormInfo);
322 /* handle Delete/Backspace in the no-echo case */
323 XtOverrideTranslations(prompt_answers[j], noecho_trans);
328 } /* end switch (siaFormInfo->rendition) */
330 XtManageChild(prompt_answers[j]);
334 XtManageChild(sia_form);
336 * Center the OK and Cancel buttons
341 XtSetArg(argt[i], XmNwidth, &width); i++;
342 XtGetValues(ok_button, argt, i);
344 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_POSITION); i++;
345 XtSetArg(argt[i], XmNleftPosition, 33); i++;
346 XtSetArg(argt[i], XmNleftOffset, -(width/2)); i++;
347 XtSetValues(ok_button, argt, i);
350 XtSetArg(argt[i], XmNwidth, &width); i++;
351 XtGetValues(cancel_button, argt, i);
353 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_POSITION); i++;
354 XtSetArg(argt[i], XmNleftPosition, 66); i++;
355 XtSetArg(argt[i], XmNleftOffset, -(width/2)); i++;
356 XtSetValues(cancel_button, argt, i);
359 if (siaFormInfo->rendition == SIAONELINER
360 || siaFormInfo->rendition == SIAFORM)
363 * Make the Return key Activate on the last text field.
365 XtOverrideTranslations(prompt_answers[siaFormInfo->num_prompts - 1],
367 XtAddCallback(prompt_answers[siaFormInfo->num_prompts - 1],
368 XmNactivateCallback, RespondSiaFormCB, siaFormInfo);
369 XSetInputFocus(XtDisplay(prompt_answers[0]),
370 XtWindow(prompt_answers[0]), RevertToPointerRoot, CurrentTime);
373 XtSetArg(argt[i], XmNinitialFocus, prompt_answers[0]); i++;
374 XtSetValues(sia_form, argt, i);
375 XmProcessTraversal(prompt_answers[0],XmTRAVERSE_CURRENT);
383 * Save the text entered but do not display it
387 static void NoEchoCB( Widget w, XtPointer client_data, XtPointer call_data )
390 SiaFormInfo *siaFormInfo;
391 XmTextVerifyPtr call;
393 siaFormInfo = (SiaFormInfo *)client_data;
394 call = (XmTextVerifyPtr) call_data;
395 if(call->reason == XmCR_MOVING_INSERT_CURSOR)
400 for (i=0; i<siaFormInfo->num_prompts; i++)
402 if (w == siaFormInfo->answer_widgets[i])
405 strcat(siaFormInfo->answers[i], call->text->ptr);
407 call->text->ptr[0] = '\0';
414 ************************
417 * PB callback collects answers, sends them down the pipe
418 * and destroys the sia_form.
419 ************************
422 static void RespondSiaFormCB( Widget w, XtPointer client_data,
423 XtPointer call_data )
425 char buf[REQUEST_LIM_MAXLEN];
428 SiaFormInfo *siaFormInfo;
431 r = (ResponseForm *)buf;
432 siaFormInfo = (SiaFormInfo *)client_data;
434 r->hdr.opcode = REQUEST_OP_FORM;
436 r->hdr.length = sizeof(ResponseForm);
438 r->collect_status = siaFormInfo->collect_status;
439 r->num_answers = siaFormInfo->num_prompts;
440 r->offAnswers = sizeof(ResponseForm);
442 answer_ptr = buf + sizeof(ResponseForm);
444 for (i=0; i<siaFormInfo->num_prompts; i++)
446 if (siaFormInfo->rendition == SIAMENUONE
447 || siaFormInfo->rendition == SIAMENUANY)
449 if (XmToggleButtonGadgetGetState(siaFormInfo->answer_widgets[i]))
450 siaFormInfo->answers[i] = "X";
452 siaFormInfo->answers[i] = NULL;
454 else if (siaFormInfo->visible[i])
455 siaFormInfo->answers[i] =
456 XmTextFieldGetString(siaFormInfo->answer_widgets[i]);
457 if (!siaFormInfo->answers[i] || (siaFormInfo->answers[i])[0] == '\0')
467 r->hdr.length += strlen(siaFormInfo->answers[i]) + 1;
468 strcpy(answer_ptr, siaFormInfo->answers[i]);
469 tmp = strlen(answer_ptr) + 1;
471 r->hdr.length += tmp;
475 for (i=0; i<siaFormInfo->num_prompts; i++)
476 printf("answer %d : %s\n", i, siaFormInfo->answers[i]);
478 write(1, buf, r->hdr.length);
481 for (i=0; i<siaFormInfo->num_prompts; i++)
483 XtFree(siaFormInfo->answers[i]);
484 XtFree(siaFormInfo->prompts[i]);
485 XtFree(siaFormInfo->title);
487 XtDestroyWidget(siaFormInfo->sia_form_widget);
491 /***************************************************************************
495 * Local backspace action for the no-echo case text widget.
496 * Deletes the last character of the string in the
497 * widget for each backspace key press.
498 ***************************************************************************/
501 SiaBackspace( Widget w, XEvent *event, char **params, Cardinal *num_params )
505 for (i=0; i<globalSiaFormInfo->num_prompts; i++)
507 if (globalSiaFormInfo->answer_widgets[i] == w)
509 len = strlen(globalSiaFormInfo->answers[i]);
511 globalSiaFormInfo->answers[i][len-1] = '\0';
518 ************************
521 * Set collect_status to failure, call RespondSiaFormCB.
523 ************************
526 static void CancelSiaFormCB( Widget w, XtPointer client_data,
527 XtPointer call_data )
529 SiaFormInfo *siaFormInfo;
531 siaFormInfo = (SiaFormInfo *)client_data;
532 siaFormInfo->collect_status = 0;
534 RespondSiaFormCB(w, client_data, call_data);