/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $XConsortium: vgsiaform.c /main/5 1996/05/07 12:22:34 drk $ */ /* * * (c) Copyright 1993, 1994 Hewlett-Packard Company * * (c) Copyright 1993, 1994 International Business Machines Corp. * * (c) Copyright 1993, 1994 Sun Microsystems, Inc. * * (c) Copyright 1993, 1994 Novell, Inc. * */ /* * @DEC_COPYRIGHT@ */ /* * HISTORY * $Log$ * Revision 1.1.2.2 1995/06/06 19:39:54 Chris_Beute * New file added for SIA password expiration forms handling * [1995/05/31 19:52:41 Chris_Beute] * * Revision 1.1.2.2 1995/05/22 18:13:32 Peter_Derr * Add a Cancel button. * [1995/05/15 18:06:21 Peter_Derr] * * Support SIAMENUONE and SIAMENUANY * [1995/05/12 20:29:53 Peter_Derr] * * SIA form UI * [1995/05/11 22:09:09 Peter_Derr] * * $EndLog$ */ #include "vg.h" #include "vgmsg.h" #include #include #include #include #include #include #include #include XmString multiline_xmstring(char *); static void NoEchoCB( Widget, XtPointer, XtPointer); static void RespondSiaFormCB( Widget, XtPointer, XtPointer); static void CancelSiaFormCB( Widget, XtPointer, XtPointer); static void SiaBackspace( Widget, XEvent *, char **, Cardinal *); static char textEventBindings[] = { "Return: next-tab-group()" }; static char activateBindings[] = { "osfActivate: activate()\n\ Ctrl Return: activate()\n\ Return: activate()" }; static char activatePBBindings[] = { "osfActivate: ArmAndActivate()\n\ Ctrl Return: ArmAndActivate()\n\ Return: ArmAndActivate()" }; static char noEchoBindings[] = { "Ctrl: my-insert()\n\ osfBackSpace: sia-bksp()\n\ osfDelete: sia-bksp()" }; static XtActionsRec textActions[] = { {"sia-bksp", (XtActionProc)SiaBackspace}, }; SiaFormInfo *globalSiaFormInfo; /*************************************************************************** * * SiaForm * * Widgets: sia_form, sia_title, sia_prompts ***************************************************************************/ void SiaForm(SiaFormInfo *siaFormInfo) { int i; int j; LoginTextPtr textdata; XtTranslations textTable; Widget sia_form, title_label, ok_button, cancel_button, prompts_row_col; Widget *prompt_labels; Widget *prompt_answers; XmString xmstr; XtTranslations noecho_trans, text_trans, activate_trans, activatePBtrans; globalSiaFormInfo = siaFormInfo; siaFormInfo->collect_status = 1; /* * XmCreateFormDialog() * XmCreateLabel() * XmCreateRowColumn() * for each prompt * XmCreateLabel() * XmCreateTextField() * if not visible * add ModifyVerify callback * XmCreatePushButton * PB callback will collect answers, send them down the pipe * and destroy the sia_form. */ /* * create the SIA form */ i = 0; i = InitArg(Form); XtSetArg(argt[i], XmNmarginHeight, MBOX_MARGIN_HEIGHT ); i++; XtSetArg(argt[i], XmNmarginWidth, MBOX_MARGIN_WIDTH ); i++; XtSetArg(argt[i], XmNshadowThickness, SHADOW_THICKNESS ); i++; XtSetArg(argt[i], XmNnoResize, False ); i++; XtSetArg(argt[i], XmNresizePolicy, XmRESIZE_ANY ); i++; sia_form = XmCreateFormDialog(login_shell, "sia_form", argt, i); siaFormInfo->sia_form_widget = sia_form; /* * create the title label */ /* i = 0; */ i = InitArg(Label); XtSetArg(argt[i], XmNlabelString, siaFormInfo->title ); i++; XtSetArg(argt[i], XmNtraversalOn, False ); i++; XtSetArg(argt[i], XmNtopAttachment, XmATTACH_FORM ); i++; XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM ); i++; XtSetArg(argt[i], XmNrightAttachment, XmATTACH_FORM ); i++; XtSetArg(argt[i], XmNalignment, XmALIGNMENT_CENTER ); i++; xmstr = multiline_xmstring(siaFormInfo->title); XtSetArg(argt[i], XmNlabelString, xmstr ); i++; title_label = XmCreateLabel(sia_form, "title_label", argt, i); XtManageChild(title_label); XmStringFree(xmstr); /* ok button */ activate_trans = XtParseTranslationTable(activateBindings); activatePBtrans = XtParseTranslationTable(activatePBBindings); i = InitArg(PushB); XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_FORM ); i++; XtSetArg(argt[i], XmNtraversalOn, True ); i++; xmstr = ReadCatalogXms(MC_LABEL_SET, MC_OK_LABEL, MC_DEF_OK_LABEL ); XtSetArg(argt[i], XmNlabelString, xmstr ); i++; ok_button = XmCreatePushButton(sia_form, "ok_button", argt, i); XtOverrideTranslations(ok_button, activatePBtrans); XmStringFree(xmstr); XtManageChild(ok_button); XtAddCallback(ok_button, XmNactivateCallback, RespondSiaFormCB, siaFormInfo); /* Cancel button */ i = InitArg(PushB); XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_FORM ); i++; XtSetArg(argt[i], XmNtraversalOn, True ); i++; xmstr = ReadCatalogXms(MC_LABEL_SET, MC_CANCEL_LABEL, MC_DEF_CANCEL_LABEL ); XtSetArg(argt[i], XmNlabelString, xmstr ); i++; cancel_button = XmCreatePushButton(sia_form, "cancel_button", argt, i); XmStringFree(xmstr); XtManageChild(cancel_button); XtAddCallback(cancel_button, XmNactivateCallback, CancelSiaFormCB, siaFormInfo); /* * create the RowColumn widget for prompts */ i =0; XtSetArg(argt[i], XmNorientation, XmHORIZONTAL ); i++; XtSetArg(argt[i], XmNentryVerticalAlignment, XmALIGNMENT_CENTER ); i++; XtSetArg(argt[i], XmNrowColumnType, XmWORK_AREA ); i++; XtSetArg(argt[i], XmNnumColumns, siaFormInfo->num_prompts); i++; XtSetArg(argt[i], XmNpacking, XmPACK_COLUMN ); i++; XtSetArg(argt[i], XmNtopAttachment, XmATTACH_WIDGET ); i++; XtSetArg(argt[i], XmNtopWidget, title_label ); i++; XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_WIDGET ); i++; XtSetArg(argt[i], XmNbottomWidget, ok_button ); i++; XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM ); i++; XtSetArg(argt[i], XmNrightAttachment, XmATTACH_FORM ); i++; switch (siaFormInfo->rendition) { case SIAMENUONE: XtSetArg(argt[i], XmNradioBehavior, True ); i++; /* no break */ case SIAMENUANY: XtSetArg(argt[i], XmNisHomogeneous, True ); i++; XtSetArg(argt[i], XmNentryClass, xmToggleButtonGadgetClass); i++; XtSetArg(argt[i], XmNentryAlignment, XmALIGNMENT_BEGINNING ); i++; break; case SIAONELINER: /* no break */ case SIAFORM: XtSetArg(argt[i], XmNentryAlignment, XmALIGNMENT_END ); i++; } prompts_row_col = XmCreateRowColumn(sia_form, "prompts_row_col", argt, i); XtManageChild(prompts_row_col); prompt_labels = (Widget *) alloca(sizeof(Widget *) * siaFormInfo->num_prompts); prompt_answers = siaFormInfo->answer_widgets; noecho_trans = XtParseTranslationTable(noEchoBindings); text_trans = XtParseTranslationTable(textEventBindings); for (j=0; jnum_prompts; j++) { /* * create the prompt label */ char label_name[81]; char answer_name[81]; sprintf(label_name,"Prompt %d",j); sprintf(answer_name,"Answer %d",j); xmstr = multiline_xmstring(siaFormInfo->prompts[j]); switch (siaFormInfo->rendition) { case SIAMENUANY: case SIAMENUONE: { /* i = InitArg(ToggleBG); */ i = 0; XtSetArg(argt[i], XmNtraversalOn, True ); i++; XtSetArg(argt[i], XmNlabelString, xmstr ); i++; prompt_answers[j] = XmCreateToggleButtonGadget(prompts_row_col, answer_name, argt, i); } break; case SIAONELINER: /* no break */ case SIAFORM: { i = 0; XtSetArg(argt[i], XmNtraversalOn, True ); i++; XtSetArg(argt[i], XmNlabelString, xmstr ); i++; prompt_labels[j] = XmCreateLabel(prompts_row_col, label_name, argt, i); XtManageChild(prompt_labels[j]); /* * create the answer text field */ i = InitArg(Text); XtSetArg(argt[i], XmNselectionArrayCount, 1 ); i++; XtSetArg(argt[i], XmNmaxLength, 80 ); i++; XtSetArg(argt[i], XmNmappedWhenManaged, True ); i++; XtAddActions(textActions, 1); prompt_answers[j] = XmCreateTextField(prompts_row_col, answer_name, argt, i); /* Make Return advance to next field. */ XtOverrideTranslations(prompt_answers[j], text_trans); if (!siaFormInfo->visible[j]) { /* * allocate the answer buffer */ siaFormInfo->answers[j] = XtMalloc(SIAMXPASSWORD+1); (siaFormInfo->answers[j])[0] = '\0'; XtAddCallback(prompt_answers[j], XmNmodifyVerifyCallback, NoEchoCB, siaFormInfo); XtAddCallback(prompt_answers[j], XmNmotionVerifyCallback, NoEchoCB, siaFormInfo); /* handle Delete/Backspace in the no-echo case */ XtOverrideTranslations(prompt_answers[j], noecho_trans); } } break; } /* end switch (siaFormInfo->rendition) */ XtManageChild(prompt_answers[j]); } XtManageChild(sia_form); /* * Center the OK and Cancel buttons */ { Dimension width; i = 0; XtSetArg(argt[i], XmNwidth, &width); i++; XtGetValues(ok_button, argt, i); i = 0; XtSetArg(argt[i], XmNleftAttachment, XmATTACH_POSITION); i++; XtSetArg(argt[i], XmNleftPosition, 33); i++; XtSetArg(argt[i], XmNleftOffset, -(width/2)); i++; XtSetValues(ok_button, argt, i); i = 0; XtSetArg(argt[i], XmNwidth, &width); i++; XtGetValues(cancel_button, argt, i); i = 0; XtSetArg(argt[i], XmNleftAttachment, XmATTACH_POSITION); i++; XtSetArg(argt[i], XmNleftPosition, 66); i++; XtSetArg(argt[i], XmNleftOffset, -(width/2)); i++; XtSetValues(cancel_button, argt, i); } if (siaFormInfo->rendition == SIAONELINER || siaFormInfo->rendition == SIAFORM) { /* * Make the Return key Activate on the last text field. */ XtOverrideTranslations(prompt_answers[siaFormInfo->num_prompts - 1], activate_trans); XtAddCallback(prompt_answers[siaFormInfo->num_prompts - 1], XmNactivateCallback, RespondSiaFormCB, siaFormInfo); XSetInputFocus(XtDisplay(prompt_answers[0]), XtWindow(prompt_answers[0]), RevertToPointerRoot, CurrentTime); i = 0; XtSetArg(argt[i], XmNinitialFocus, prompt_answers[0]); i++; XtSetValues(sia_form, argt, i); XmProcessTraversal(prompt_answers[0],XmTRAVERSE_CURRENT); } } /* ***************** * NoEchoCB * * Save the text entered but do not display it ***************** */ static void NoEchoCB( Widget w, XtPointer client_data, XtPointer call_data ) { int i; SiaFormInfo *siaFormInfo; XmTextVerifyPtr call; siaFormInfo = (SiaFormInfo *)client_data; call = (XmTextVerifyPtr) call_data; if(call->reason == XmCR_MOVING_INSERT_CURSOR) { call->doit=False; return; } for (i=0; inum_prompts; i++) { if (w == siaFormInfo->answer_widgets[i]) { if (call->text->ptr) strcat(siaFormInfo->answers[i], call->text->ptr); call->text->ptr[0] = '\0'; return; } } } /* ************************ * RespondSiaFormCB * * PB callback collects answers, sends them down the pipe * and destroys the sia_form. ************************ */ static void RespondSiaFormCB( Widget w, XtPointer client_data, XtPointer call_data ) { char buf[REQUEST_LIM_MAXLEN]; ResponseForm *r; int i; SiaFormInfo *siaFormInfo; char *answer_ptr; r = (ResponseForm *)buf; siaFormInfo = (SiaFormInfo *)client_data; r->hdr.opcode = REQUEST_OP_FORM; r->hdr.reserved = 0; r->hdr.length = sizeof(ResponseForm); r->collect_status = siaFormInfo->collect_status; r->num_answers = siaFormInfo->num_prompts; r->offAnswers = sizeof(ResponseForm); answer_ptr = buf + sizeof(ResponseForm); for (i=0; inum_prompts; i++) { if (siaFormInfo->rendition == SIAMENUONE || siaFormInfo->rendition == SIAMENUANY) { if (XmToggleButtonGadgetGetState(siaFormInfo->answer_widgets[i])) siaFormInfo->answers[i] = "X"; else siaFormInfo->answers[i] = NULL; } else if (siaFormInfo->visible[i]) siaFormInfo->answers[i] = XmTextFieldGetString(siaFormInfo->answer_widgets[i]); if (!siaFormInfo->answers[i] || (siaFormInfo->answers[i])[0] == '\0') { *answer_ptr = '\0'; *answer_ptr++; r->hdr.length++; } else { int tmp; r->hdr.length += strlen(siaFormInfo->answers[i]) + 1; strcpy(answer_ptr, siaFormInfo->answers[i]); tmp = strlen(answer_ptr) + 1; answer_ptr+= tmp; r->hdr.length += tmp; } } #ifdef DEBUG for (i=0; inum_prompts; i++) printf("answer %d : %s\n", i, siaFormInfo->answers[i]); #else write(1, buf, r->hdr.length); #endif for (i=0; inum_prompts; i++) { XtFree(siaFormInfo->answers[i]); XtFree(siaFormInfo->prompts[i]); XtFree(siaFormInfo->title); } XtDestroyWidget(siaFormInfo->sia_form_widget); } /*************************************************************************** * * SiaBackspace * * Local backspace action for the no-echo case text widget. * Deletes the last character of the string in the * widget for each backspace key press. ***************************************************************************/ static void SiaBackspace( Widget w, XEvent *event, char **params, Cardinal *num_params ) { int i, len; for (i=0; inum_prompts; i++) { if (globalSiaFormInfo->answer_widgets[i] == w) { len = strlen(globalSiaFormInfo->answers[i]); if (len > 0) globalSiaFormInfo->answers[i][len-1] = '\0'; return; } } } /* ************************ * CancelSiaFormCB * * Set collect_status to failure, call RespondSiaFormCB. * ************************ */ static void CancelSiaFormCB( Widget w, XtPointer client_data, XtPointer call_data ) { SiaFormInfo *siaFormInfo; siaFormInfo = (SiaFormInfo *)client_data; siaFormInfo->collect_status = 0; RespondSiaFormCB(w, client_data, call_data); }