1 /* $TOG: vgcallback.c /main/16 1998/11/02 18:34:55 mgreess $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
4 * (c) Copyright 1993, 1994 International Business Machines Corp. *
5 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
6 * (c) Copyright 1993, 1994 Novell, Inc. *
8 /************************************<+>*************************************
9 ****************************************************************************
13 ** Project: HP Visual User Environment (DT)
15 ** Description: Callback routines Dtgreet application.
17 ** These routines handle the callbacks from the widgets.
20 ** (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company
24 ****************************************************************************
25 ************************************<+>*************************************/
28 /***************************************************************************
32 ***************************************************************************/
38 #include <sys/signal.h>
39 #include <sys/param.h>
42 #include <Xm/MessageB.h>
44 #include <Xm/TextFP.h>
45 #include <Xm/PushBG.h>
46 #include <Xm/ToggleBG.h>
47 #include <Dt/IconFile.h>
53 # include <sys/audit.h>
56 /* necessary for bzero */
58 #include <X11/Xfuncs.h>
65 /***************************************************************************
67 * External declarations
69 ***************************************************************************/
71 extern LogoInfo logoInfo; /* information about the logo */
75 /***************************************************************************
77 * Procedure declarations
79 ***************************************************************************/
81 static void CenterForm( Widget w1, Widget w2);
82 static void PingLost( void ) ;
83 static SIGVAL PingBlocked( int arg ) ;
84 static void ProcessTraversal( Widget w, int direction) ;
85 static void _DtShowDialog(DialogType dtype, XmString msg);
86 static void TellRequester(char * buf, size_t nbytes);
89 static void PromptSensitivityLevel(void); /* prompt for B1 Sen. Level */
90 int VerifySensitivityLevel(void); /* verify B1 Sensitivity Level */
93 static int session_selected = False;
94 static Widget default_dt = NULL;
97 /***************************************************************************
101 ***************************************************************************/
103 Widget focusWidget = NULL;
105 char *userName = "\0";
106 struct passwd *user_p;
110 static int normalPasswordWidget = True;
111 char *sensitivityLevel = NULL;
115 long groups[NGROUPS];
122 SiaFormInfo siaFormInfo;
125 XmString multiline_xmstring(char *text)
130 XmString string = NULL;
132 XmString separator = NULL;
135 if (!text) return (NULL);
138 buffer = alloca(strlen((const char *)text) + 1);
144 while ( ! done) /* loop thu local copy */
145 { /* looking for \n */
148 while ((*end != '\0') && (*end != '\n')) end++;
151 done = TRUE; /* we are at the end */
153 /* Don't convert empty string unless it's an initial newline. */
154 if ((start != end) || (start == text))
156 strncpy(buffer, start, end - start);
157 buffer[end - start] = '\0';
159 string = XmStringCreate(buffer, XmFONTLIST_DEFAULT_TAG);
162 tmp_string = XmStringCreate(buffer, XmFONTLIST_DEFAULT_TAG);
163 string = XmStringConcat(string, tmp_string);
164 XmStringFree(tmp_string);
168 /* Make a separator if this isn't the last segment. */
172 separator = XmStringSeparatorCreate();
173 string = XmStringConcat(string, separator);
174 start = ++end; /* start at next char */
179 XmStringFree(separator);
187 /***************************************************************************
191 * Utility function to center one form horizontally within another.
192 ***************************************************************************/
195 CenterForm( Widget w1, Widget w2 )
199 int i, width1, width2;
201 XtSetArg(argt[0], XmNwidth, &width);
202 XtGetValues(w1, argt, 1);
205 XtSetArg(argt[0], XmNwidth, &width);
206 XtGetValues(w2, argt, 1);
210 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM ); i++;
211 XtSetArg(argt[i], XmNleftOffset, (width1 - width2) / 2 ); i++;
212 XtSetValues(w2, argt, i);
218 /***************************************************************************
222 * close things down gracefully and exit
223 ***************************************************************************/
226 CleanupAndExit( Widget w, int exit_code )
229 Boolean toggleon; /* status of session toggle buttons */
232 vg_TRACE_EXECUTION("main: entered CleanupAndExit ...");
233 #endif /* VG_TRACE */
239 * if user is logging in, set type of session desired. No more than
240 * one session type can be selected at a time (if any) ...
243 if ( exit_code == NOTIFY_OK ) {
244 XtSetArg(argt[0], XmNset, &toggleon );
246 XtGetValues(options_failsafe, argt, 1);
247 if ( toggleon ) exit_code = NOTIFY_FAILSAFE;
249 XtGetValues(options_dtlite, argt, 1);
250 if ( toggleon ) exit_code = NOTIFY_DTLITE;
253 XtGetValues(options_dt, argt, 1);
254 if ( toggleon ) exit_code = NOTIFY_DT;
257 if(options_last_dt != NULL) {
258 XtGetValues(options_last_dt, argt, 1);
259 if ( toggleon ) exit_code = NOTIFY_LAST_DT;
262 for(i = 0; i < appInfo.altDts ; ++i) {
263 if(alt_dts[i] != NULL) {
264 XtGetValues(alt_dts[i], argt, 1);
265 if ( toggleon ) exit_code = NOTIFY_ALT_DTS + i + 1; /* alt desktops start at 1 */
272 if (!session_selected)
273 exit_code = NOTIFY_OK;
279 XSync (dpyinfo.dpy, 0);
281 XtCloseDisplay(dpyinfo.dpy);
286 /***************************************************************************
290 ***************************************************************************/
299 vg_TRACE_EXECUTION("ClearDtlabel: entered ...");
300 #endif /* VG_TRACE */
303 xms = XmStringCreateLocalized(" ");
304 XtSetArg(argt[i], XmNlabelString, xms); i++;
305 XtSetValues(dt_label, argt, i);
310 /***************************************************************************
314 ***************************************************************************/
322 * Clear Dt toggles...
324 XtSetArg(argt[0], XmNset, False);
326 for (i=0; i<appInfo.altDts; ++i)
327 if (alt_dts[i] != NULL)
328 XtSetValues(alt_dts[i], argt, 1);
330 if (options_failsafe) XtSetValues(options_failsafe, argt, 1);
331 if (options_dtlite) XtSetValues(options_dtlite, argt, 1);
332 if (options_dt) XtSetValues(options_dt, argt, 1);
333 if (options_last_dt) XtSetValues(options_last_dt, argt, 1);
339 /***************************************************************************
343 * clear name/password text fields
344 ***************************************************************************/
347 RespondClearCB( Widget w, XtPointer client, XtPointer call )
349 char buf[REQUEST_LIM_MAXLEN];
350 ResponseClear *r = (ResponseClear *)buf;
353 vg_TRACE_EXECUTION("main: entered RespondClearCB ...");
354 #endif /* VG_TRACE */
360 r->hdr.opcode = REQUEST_OP_CLEAR;
362 r->hdr.length = sizeof(*r);
364 TellRequester(buf, (size_t) r->hdr.length);
369 /***************************************************************************
373 * move the highlight back to login or password fields AFTER the copyright
374 * dialog is unposted.
376 ***************************************************************************/
379 CopyrightCB( Widget w, XtPointer client_data, XtPointer call_data )
383 vg_TRACE_EXECUTION("main: entered CopyrightCB ...");
384 #endif /* VG_TRACE */
386 if ( focusWidget != NULL)
387 ProcessTraversal(focusWidget, XmTRAVERSE_CURRENT);
393 /***************************************************************************
397 * implement no-echo and no-cursor motion of the password
398 ***************************************************************************/
401 EditPasswdCB(Widget w, XtPointer client, XtPointer call_data)
403 LoginTextPtr textdata;
404 XmTextVerifyPtr cbs = (XmTextVerifyPtr) call_data;
406 static char buffer[MAXPATHLEN];
407 register char *s, *t;
410 vg_TRACE_EXECUTION("main: entered EditPasswdCB ...");
412 "currInsert=%d newInsert=%d startPos=%d endPos=%d\n",
413 cbs->currInsert,cbs->newInsert,cbs->startPos, cbs->endPos);
414 if (cbs->text->ptr) vg_TRACE_EXECUTION("text->ptr=%s\n", cbs->text->ptr);
415 vg_TRACE_EXECUTION("noechobuf=%s\n", textdata->noechobuf);
416 #endif /* VG_TRACE */
418 textdata = GetLoginTextPtr(w);
419 if (NULL == textdata || textdata->bEcho) return;
420 if (cbs->reason == XmCR_MOVING_INSERT_CURSOR) return;
422 for (i=0, s=buffer, t=textdata->noechobuf;
423 (*t && i<cbs->startPos);
429 strcpy(s, cbs->text->ptr);
430 s += cbs->text->length;
435 if (strlen(textdata->noechobuf) >= cbs->endPos)
437 t = textdata->noechobuf+cbs->endPos;
442 strcpy(textdata->noechobuf, buffer);
445 for (i=0, s=cbs->text->ptr; i<cbs->text->length; i++, s++)
449 vg_TRACE_EXECUTION("textdata->noechobuf=%s\n", textdata->noechobuf);
454 /***************************************************************************
458 * simulate a FocusIn event to the login_shell in order to turn on
459 * traversal. There is a bug in the Toolkit that is normally masked by
460 * the window manager. Since we have no window manager, we need to simulate
461 * the FocusIn event it sends to the application.
463 * Also force the initial focus to the login_text widget.
464 ***************************************************************************/
467 FakeFocusIn( Widget focus_widget, XtPointer client_data, XEvent *eventprm,
468 Boolean *continue_to_dispatch )
471 XEvent * eventPtr = &event;
474 vg_TRACE_EXECUTION("main: entered FakeFocusIn ...");
475 #endif /* VG_TRACE */
478 * set the input focus to the login text widget...
481 XSetInputFocus( XtDisplay(focus_widget),
482 XtWindow(focus_widget),
487 * create a synthetic focus-in event.
489 * Note: The above call to XSetInputFocus() was not originally included
490 * in this routine. A bug fix to Motif made it necessary to add
491 * the call. The synthetic focus-in event is probably now
492 * unnecessary but is left in for caution's sake. (12/08/92)
495 /* focus_widget = login_shell; */
497 eventPtr->type = FocusIn;
498 eventPtr->xfocus.serial = LastKnownRequestProcessed(XtDisplay(focus_widget));
499 eventPtr->xfocus.send_event = True;
500 eventPtr->xfocus.display = XtDisplay(focus_widget);
501 eventPtr->xfocus.window = XtWindow(focus_widget);
502 eventPtr->xfocus.mode = NotifyNormal;
503 eventPtr->xfocus.detail = NotifyAncestor;
505 XtDispatchEvent (eventPtr);
507 ProcessTraversal(focus_widget, XmTRAVERSE_CURRENT);
509 XtRemoveEventHandler(focus_widget, ExposureMask, FALSE,
513 /***************************************************************************
517 * do final layout adjustments right before windows are mapped. This is
518 * necessary because the size of managers (Forms, etc) is not known until
519 * their window has been created (XtRealize). We want to make adjustments
520 * before the windows become visible
522 * 1. squeeze dialog width to fit on screen.
523 * 2. increase dialog height if widgets overlap.
524 * 3. center the main matte horizontally and vertically
525 * 4. position the pushbuttons
526 * 5. position the copyright
528 ***************************************************************************/
531 LayoutCB( Widget w, XtPointer client_data, XtPointer call_data )
534 Dimension width, height; /* size values returned by XtGetValues */
535 Dimension shadowThickness;/* size values returned by XtGetValues */
536 Position x, y; /* position values returned by XtGetValues */
538 struct { /* position, size of widgets (pixels) */
542 } mw, pw; /* matte, logo, drop shadow, login matte
543 and greeting widgets */
545 int width1, width2; /* general width variable */
546 int height1; /* general height variable */
547 Position x1, y1; /* general position variables */
548 int offsety; /* general offset variable */
549 int shadow_offsetx; /* offset for drop shadow (pixels) */
550 int shadow_offsety; /* offset for drop shadow (pixels) */
551 int spacing; /* spacing between login & matte bottoms */
553 Widget buttons[4]; /* pushbutton widgets */
555 XtWidgetGeometry geometry; /* geometry of a widget */
557 int max_width; /* maximum width of a set of widgets */
558 int origin; /* horizontal origin for button placement */
559 int space; /* total available space left between buttons */
560 int overlap; /* possible widget overlap */
563 vg_TRACE_EXECUTION("main: entered LayoutCB ...");
564 #endif /* VG_TRACE */
567 * - squeeze dialog to fit onto screen (if necessary)
570 XtSetArg(argt[i], XmNwidth, &width ); i++;
571 XtGetValues(matte, argt, i);
572 mw.width = ToPixel(matte, XmHORIZONTAL, (int)width );
573 #define HMARGIN 4 /* min sum horizontal margin of matte */
574 if (mw.width+HMARGIN > dpyinfo.width)
576 int delta = mw.width + HMARGIN - dpyinfo.width;
578 * Matte width greater than screen so shrink matteFrame
579 * and matte1 width to compensate.
582 XtSetArg(argt[i], XmNwidth, &width ); i++;
583 XtGetValues(matteFrame, argt, i);
585 width1 = ToPixel(matteFrame, XmHORIZONTAL, (int)width );
587 width1 = FromPixel(matteFrame, XmHORIZONTAL, width1 );
590 XtSetArg(argt[i], XmNwidth, width1 ); i++;
591 XtSetValues(matteFrame, argt, i);
593 width1 = dpyinfo.width - HMARGIN;
594 mw.width = FromPixel(matte, XmHORIZONTAL, width1 );
597 XtSetArg(argt[i], XmNwidth, mw.width ); i++;
598 XtSetValues(matte, argt, i);
602 * - Make sure the login widgets don't overlap.
606 XtSetArg(argt[i], XmNy, &y ); i++;
607 XtSetArg(argt[i], XmNheight, &height ); i++;
608 XtGetValues(greeting, argt, i);
611 XtSetArg(argt[i], XmNy, &y1 ); i++;
612 XtGetValues(login_form, argt, i);
614 overlap = y + height - y1;
618 XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
619 XtSetArg(argt[i], XmNbottomWidget, login_form); i++;
620 XtSetArg(argt[i], XmNbottomOffset, 10); i++;
621 XtSetValues(greeting, argt, i);
627 * - center the main matte horizontally and vertically...
631 XtSetArg(argt[i], XmNx, &x ); i++;
632 XtSetArg(argt[i], XmNy, &y ); i++;
633 XtSetArg(argt[i], XmNwidth, &width ); i++;
634 XtSetArg(argt[i], XmNheight, &height ); i++;
635 XtSetArg(argt[i], XmNshadowThickness, &shadowThickness ); i++;
636 XtGetValues(matte, argt, i);
638 mw.width = ToPixel(matte, XmHORIZONTAL, (int)width );
639 mw.height = ToPixel(matte, XmVERTICAL, (int)height );
641 mw.x = ( x > 0 ? ToPixel(matte, XmHORIZONTAL, (int) x)
642 : (dpyinfo.width - mw.width)/2 );
644 mw.y = ( y > 0 ? ToPixel(matte, XmVERTICAL, (int) y)
645 : (dpyinfo.height - mw.height)/2 );
647 if ( mw.x < 0 ) mw.x = 0;
648 if ( mw.y < 0 ) mw.y = 0;
650 x1 = FromPixel(matte, XmHORIZONTAL, mw.x );
651 y1 = FromPixel(matte, XmVERTICAL, mw.y );
654 XtSetArg(argt[i], XmNx, x1 ); i++;
655 XtSetArg(argt[i], XmNy, y1 ); i++;
656 XtSetValues(matte, argt, i);
660 * space the buttons horizontally. Start at the center of the matte
661 * and allow them to grow towards the edges...
665 XtSetArg(argt[i], XmNwidth, &width ); i++;
666 XtGetValues(matte1, argt, i);
671 XtSetArg(argt[i], XmNwidth, &width ); i++;
672 XtGetValues(clear_button, argt, i);
674 space = max_width - 4*width;
677 if (spacing < 12) spacing = 12;
680 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM); i++;
681 XtSetArg(argt[i], XmNleftOffset, spacing/2); i++;
682 XtSetValues(ok_button, argt, i);
685 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_WIDGET ); i++;
686 XtSetArg(argt[i], XmNleftWidget, ok_button); i++;
687 XtSetArg(argt[i], XmNleftOffset, spacing); i++;
688 XtSetValues(clear_button, argt, i);
691 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_WIDGET ); i++;
692 XtSetArg(argt[i], XmNleftWidget, clear_button); i++;
693 XtSetArg(argt[i], XmNleftOffset, spacing); i++;
694 XtSetValues(options_button, argt, i);
697 XtSetArg(argt[i], XmNleftAttachment, XmATTACH_WIDGET ); i++;
698 XtSetArg(argt[i], XmNleftWidget, options_button); i++;
699 XtSetArg(argt[i], XmNleftOffset, spacing); i++;
700 XtSetValues(help_button, argt, i);
703 * - adjust the copyright vertically to align top with login_matte...
707 XtQueryGeometry(copyright_msg, NULL, &geometry);
710 XtSetArg(argt[i], XmNshadowThickness, &width ); i++;
711 XtGetValues(copyright_msg, argt, i);
713 width1 = ToPixel(copyright_msg, XmHORIZONTAL, width);
714 width1 = (dpyinfo.width - (int) geometry.width - 2 * width1)/2;
716 x1 = FromPixel(copyright_msg, XmHORIZONTAL, width1);
717 y1 = FromPixel(copyright_msg, XmVERTICAL, mw.y);
720 XtSetArg(argt[i], XmNdefaultPosition, False ); i++;
721 XtSetArg(argt[i], XmNx, x1 ); i++;
722 XtSetArg(argt[i], XmNy, y1 ); i++;
723 XtSetValues(copyright_msg, argt, i);
730 /***************************************************************************
734 * callback for options menu items
735 ***************************************************************************/
738 MenuItemCB( Widget w, XtPointer client_data, XtPointer call_data )
744 char temp[MAXPATHLEN];
747 vg_TRACE_EXECUTION("main: entered MenuItemCB ...");
748 #endif /* VG_TRACE */
750 session_selected = True;
752 switch ( (int) client_data) {
754 case OB_RESTART_SERVER:
755 CleanupAndExit(NULL, NOTIFY_RESTART);
759 CleanupAndExit(NULL, NOTIFY_NO_WINDOWS);
763 _DtShowDialog(copyright, NULL);
772 * set the label on the dt_label widget..
775 if(w != options_last_dt) {
776 XtSetArg(argt[0], XmNlabelString, &xmstr);
777 XtGetValues(w, argt, 1);
779 XtSetArg(argt[0], XmNlabelString, xmstr);
780 XtSetValues(dt_label, argt, 1);
786 XtSetArg(argt[i], XmNuserData, &logoFile ); i++;
787 XtGetValues(w, argt, i);
790 * remove trailing spaces
792 if(strchr(logoFile,' '))
793 temp_p = strtok(logoFile," ");
797 logoName = _DtGetIconFileName(DefaultScreenOfDisplay(dpyinfo.dpy),
798 temp_p, NULL, NULL, NULL);
800 if (logoName == NULL) {
802 ReadCatalog(MC_LOG_SET,MC_LOG_NO_LOGOBIT,MC_DEF_LOG_NO_LOGOBIT),
807 XtSetArg(argt[i], XmNimageName, logoName); i++;
808 XtSetValues(logo_pixmap, argt, i);
811 * Clear Dt toggles...
816 * set the selected toggle button...
818 XtSetArg(argt[0], XmNset, True);
819 XtSetValues(w, argt, 1);
824 * return focus to name/password widgets...
827 if ( focusWidget != NULL)
828 ProcessTraversal(focusWidget, XmTRAVERSE_CURRENT);
838 /***************************************************************************
842 * callback when options menu unmaps
843 ***************************************************************************/
846 OptionsUnmapCB( Widget wd, XtPointer client_data, XtPointer call_data )
850 Dimension width, height;
856 vg_TRACE_EXECUTION("main: entered OptionsUnmapCB ...");
857 #endif /* VG_TRACE */
860 * simulate an exposure event over the Options pushbutton to make sure
861 * the pushbutton elevates. (there is a bug in the toolkit where this
862 * doesn't always happen on some servers)...
868 XtSetArg(argt[i], XmNwidth, &width ); i++;
869 XtSetArg(argt[i], XmNheight, &height ); i++;
870 XtGetValues(w, argt, i);
873 event.xexpose.serial = LastKnownRequestProcessed(XtDisplay(w));
874 event.xexpose.send_event = True;
875 event.xexpose.display = XtDisplay(w);
876 event.xexpose.window = XtWindow(w);
879 event.xexpose.width = 1; /* one pixel seems to be good enough, */
880 event.xexpose.height = 1; /* but time will tell... */
882 event.xexpose.width = ToPixel(matte, XmHORIZONTAL, (int)width );
883 event.xexpose.height = ToPixel(matte, XmVERTICAL, (int)height );
885 event.xexpose.count = 0;
887 XtDispatchEvent (&event);
892 /***************************************************************************
896 * Ping the server occasionally with an Xsync to see if it is still there.
897 * We do this here rather than in dtlogin since dtgreet has the server
900 ***************************************************************************/
902 static jmp_buf pingTime;
903 static int serverDead = FALSE;
904 static int pingInterval = 0; /* ping interval (sec.) */
905 static int pingTimeout; /* ping timeout (sec.) */
911 longjmp (pingTime, 1);
916 PingBlocked( int arg )
920 longjmp (pingTime, 1);
931 oldError = XSetIOErrorHandler ((XIOErrorHandler)PingLost);
932 oldAlarm = alarm (0);
933 oldSig = signal (SIGALRM, PingBlocked);
934 alarm (pingTimeout * 60);
935 if (!setjmp (pingTime))
937 XSync (dpyinfo.dpy, 0);
942 LogError(ReadCatalog(
943 MC_LOG_SET,MC_LOG_DEADSRV,MC_DEF_LOG_DEADSRV),
946 signal (SIGALRM, SIG_DFL);
947 XSetIOErrorHandler (oldError);
952 signal (SIGALRM, oldSig);
954 XSetIOErrorHandler (oldError);
960 PingServerCB( XtPointer call_data, XtIntervalId *id )
967 * get ping values from the environment...
970 if ( pingInterval == 0 ) {
971 pingInterval = ((t = (char *)getenv(PINGINTERVAL)) == NULL ? 0 : atoi(t));
972 pingTimeout = ((t = (char *)getenv(PINGTIMEOUT)) == NULL ? 0 : atoi(t));
977 * ping the server. If successful, set a timer for the next ping,
978 * otherwise cleanup and exit...
981 if ( pingInterval != 0 ) {
983 XtAddTimeOut((unsigned long) pingInterval * 60 * 1000,
986 exit(NOTIFY_RESTART);
992 /***************************************************************************
996 * post the option_button pop-up menu
997 ***************************************************************************/
1000 PostMenuCB( Widget w, XtPointer client_data, XtPointer call_data )
1003 XmAnyCallbackStruct *p;
1005 p = (XmAnyCallbackStruct *) call_data;
1008 vg_TRACE_EXECUTION("main: entered PostMenuCB ...");
1009 #endif /* VG_TRACE */
1012 * make options menus if they don't yet exist...
1015 if (options_menu == NULL)
1023 if (p->reason == XmCR_ARM &&
1024 p->event->type == ButtonPress) {
1026 XmMenuPosition(options_menu, p->event);
1027 XtManageChild(options_menu);
1034 /***************************************************************************
1038 * move the input focus
1039 ***************************************************************************/
1042 ProcessTraversal( Widget w, int direction )
1047 vg_TRACE_EXECUTION("main: entered ProcessTraversal ...");
1048 #endif /* VG_TRACE */
1050 i = XmProcessTraversal(w, direction);
1054 * Versions of Motif other than HP do not support the XmfocusCallback
1055 * on the TextField widget. We simulate it here by manually invoking the
1056 * callback routine...
1059 TextFocusCB(w, NULL, NULL);
1066 /***************************************************************************
1070 * cause the entire screen to refresh via exposure events
1071 ***************************************************************************/
1074 RefreshEH( Widget w, XtPointer client_data, XEvent *event,
1075 Boolean *continue_to_dispatch )
1081 vg_TRACE_EXECUTION("main: entered RefreshEH ...");
1082 #endif /* VG_TRACE */
1085 * map/unmap a window that covers the entire screen. The resultant
1086 * exposure events will refresh the screen. Note, the default
1087 * background pixmap is NONE.
1090 cover = XCreateWindow ( dpyinfo.dpy, /* display */
1091 dpyinfo.root, /* root window ID */
1094 dpyinfo.width, /* width */
1095 dpyinfo.height, /* height */
1096 0, /* border width */
1098 InputOutput, /* class */
1099 CopyFromParent, /* visual */
1101 (XSetWindowAttributes *)NULL); /* attributes */
1103 XMapWindow(dpyinfo.dpy, cover);
1104 XDestroyWindow(dpyinfo.dpy, cover);
1105 XFlush(dpyinfo.dpy);
1109 /***************************************************************************
1113 * Accept a request from client
1114 ***************************************************************************/
1118 XtPointer client_data,
1125 RequestHeader *phdr = (RequestHeader *)buf;
1128 vg_TRACE_EXECUTION("main: entered RequestCB ...");
1129 #endif /* VG_TRACE */
1132 * There's a request in the pipe. Read the header.
1134 count = read(0, buf, sizeof(*phdr));
1135 if (count != sizeof(*phdr))
1141 * Calculate amount of data after header.
1143 remainder = phdr->length - sizeof(*phdr);
1147 * Read remainder of request.
1149 count = read(0, buf+sizeof(*phdr), remainder);
1153 * Initiate response to request.
1155 switch(phdr->opcode)
1157 case REQUEST_OP_EXIT:
1159 vg_TRACE_EXECUTION("main: got REQUEST_OP_EXIT ...");
1160 #endif /* VG_TRACE */
1161 RespondExitCB(NULL, NULL, NULL);
1164 case REQUEST_OP_MESSAGE:
1166 RequestMessage *r = (RequestMessage *)phdr;
1170 vg_TRACE_EXECUTION("main: got REQUEST_OP_MESSAGE ...");
1171 #endif /* VG_TRACE */
1177 * Caller passed in MC_* message id.
1179 if (r->idMC == MC_NO_LOGIN &&
1180 (fp = fopen(NO_LOGIN_FILE,"r")) != NULL)
1183 * For MC_NO_LOGIN read message from file.
1190 while (fgets(buffer, 256, fp) != NULL)
1193 if ( buffer[j-1] == '\n' ) buffer[j-1] = '\0';
1195 string = XmStringConcat(xmstr,
1196 XmStringCreate(buffer,
1197 XmFONTLIST_DEFAULT_TAG));
1198 string = XmStringConcat(xmstr, XmStringSeparatorCreate());
1204 * Read message from message catalog.
1206 string = ReadCatalogXms(MC_ERROR_SET, r->idMC, buf+r->offMessage);
1212 * Generate message from provided string.
1215 string = multiline_xmstring(buf+r->offMessage);
1217 string = XmStringCreate(buf+r->offMessage,XmFONTLIST_DEFAULT_TAG);
1221 _DtShowDialog(error, string);
1223 XmStringFree(string);
1227 case REQUEST_OP_HOSTNAME:
1229 vg_TRACE_EXECUTION("main: got REQUEST_OP_HOSTNAME ...");
1230 #endif /* VG_TRACE */
1231 _DtShowDialog(hostname, NULL);
1234 case REQUEST_OP_EXPASSWORD:
1236 vg_TRACE_EXECUTION("main: got REQUEST_OP_EXPASSWORD ...");
1237 #endif /* VG_TRACE */
1238 _DtShowDialog(expassword, NULL);
1241 case REQUEST_OP_CHPASS:
1243 vg_TRACE_EXECUTION("main: got REQUEST_OP_CHPASS ...");
1244 #endif /* VG_TRACE */
1247 case REQUEST_OP_CHALLENGE:
1249 RequestChallenge *r = (RequestChallenge *)phdr;
1252 LoginTextPtr textdata;
1256 vg_TRACE_EXECUTION("main: got REQUEST_OP_CHALLENGE ...");
1257 #endif /* VG_TRACE */
1258 textdata = GetLoginTextPtr(login_text);
1260 change = (textdata->bEcho != r->bEcho);
1262 XtUnmapWidget(textdata->text[textdata->bEcho]);
1264 textdata->bEcho = r->bEcho;
1265 textdata->noechobuf[0] = '\0';
1267 XtAddEventHandler(textdata->text[textdata->bEcho], ExposureMask, False,
1270 XtMapWidget(textdata->text[textdata->bEcho]);
1272 XtPopup(login_shell, XtGrabNone);
1274 XGrabKeyboard (dpyinfo.dpy, XtWindow (textdata->text[textdata->bEcho]),
1275 False, GrabModeAsync, GrabModeAsync, CurrentTime);
1277 XmTextFieldSetString(
1278 textdata->text[textdata->bEcho],
1279 r->offUserNameSeed ? buf+r->offUserNameSeed : "");
1281 XmTextFieldSetSelection (
1283 0, XmTextFieldGetLastPosition(textdata->text[1]),
1289 * Read message from message catalog.
1291 string = ReadCatalogXms(MC_LABEL_SET, r->idMC, buf+r->offChallenge);
1296 * Generate message from provided string.
1298 string = XmStringCreate(buf+r->offChallenge,XmFONTLIST_DEFAULT_TAG);
1302 XtSetArg(argt[i], XmNlabelString, string ); i++;
1303 XtSetValues(login_label, argt, i);
1305 XmStringFree(string);
1312 if (textdata->bEcho)
1314 XtSetArg(argt[i], XmNlabelString, textdata->onGreeting ); i++;
1318 sprintf(buf, textdata->offGreetingFormat,
1319 textdata->offGreetingUname);
1320 string = XmStringCreate(buf, XmFONTLIST_DEFAULT_TAG);
1321 XtSetArg(argt[i], XmNlabelString, string ); i++;
1322 free(textdata->offGreetingUname);
1324 XtSetValues(greeting, argt, i);
1325 /* set the dt_label with the session that is enabled */
1326 SetDtLabelAndIcon();
1330 XtSetSensitive(ok_button, True);
1331 XtSetSensitive(clear_button, True);
1332 XtSetSensitive(options_button, True);
1333 XtSetSensitive(help_button, True);
1335 XUngrabKeyboard(dpyinfo.dpy,CurrentTime);
1339 case REQUEST_OP_FORM:
1341 RequestForm *r = (RequestForm *)buf;
1346 vg_TRACE_EXECUTION("main: got REQUEST_OP_FORM ...");
1347 #endif /* VG_TRACE */
1348 siaFormInfo.num_prompts = r->num_prompts;
1349 siaFormInfo.rendition = r->rendition;
1350 siaFormInfo.title = XtMalloc(strlen(buf + r->offTitle));
1351 strcpy(siaFormInfo.title, buf + r->offTitle);
1353 prompt_ptr = buf + r->offPrompts;
1355 for (i=0; i < siaFormInfo.num_prompts; i++)
1357 siaFormInfo.visible[i] = r->visible[i];
1358 siaFormInfo.prompts[i] = XtMalloc(strlen(prompt_ptr));
1359 siaFormInfo.answers[i] = NULL;
1360 strcpy(siaFormInfo.prompts[i], prompt_ptr);
1361 prompt_ptr += strlen(prompt_ptr) + 1;
1368 * prompt labels and answer text fields for each prompt
1370 * Add callbacks as needed. If not visible don't echo.
1371 * On OK callback, collect info and send it. Destroy widgets.
1373 SiaForm(&siaFormInfo);
1384 * Send immediate response to debug.
1388 ResponseDebug *rdebug = (ResponseDebug *)outbuf;
1390 rdebug->hdr.opcode = REQUEST_OP_DEBUG;
1391 rdebug->hdr.reserved = 0;
1392 rdebug->offString = sizeof(*rdebug);
1393 p = ((char *)(rdebug)) + rdebug->offString;
1394 strcpy(p, "This is my debug string");
1395 rdebug->hdr.length = sizeof(*rdebug) + strlen(p) + 1;
1397 TellRequester(outbuf, (size_t) rdebug->hdr.length);
1402 /***************************************************************************
1406 * Respond to an exit request from client
1407 ***************************************************************************/
1415 char buf[REQUEST_LIM_MAXLEN];
1416 ResponseExit *r = (ResponseExit *)buf;
1419 vg_TRACE_EXECUTION("main: entered RespondExitCB ...");
1420 #endif /* VG_TRACE */
1422 r->hdr.opcode = REQUEST_OP_EXIT;
1423 r->hdr.reserved = 0;
1424 r->hdr.length = sizeof(*r);
1426 TellRequester(buf, (size_t) r->hdr.length);
1428 CleanupAndExit(NULL, NOTIFY_OK);
1430 /***************************************************************************
1434 * Respond to a lang item selection from user
1435 ***************************************************************************/
1441 RespondLangCB( Widget w, XtPointer client, XtPointer call)
1443 XtSetArg(argt[0], XmNset, True);
1444 XtSetValues(w, argt, 1);
1447 vg_TRACE_EXECUTION("main: entered RespondLangCB ...");
1448 #endif /* VG_TRACE */
1451 /** this is probably not the ideal way to do this **/
1452 /** but it does work ok. **/
1453 /** notice the related code in chooser.c at the **/
1454 /** beginning of main. **/
1456 if (XmToggleButtonGadgetGetState(w)) {
1457 strcpy(buff, "LANG=");
1458 strcat(buff, client);
1460 execv(orig_argv[0], orig_argv);
1463 char buf[REQUEST_LIM_MAXLEN];
1464 ResponseLang *r = (ResponseLang *)buf;
1467 r->hdr.opcode = REQUEST_OP_LANG;
1468 r->hdr.reserved = 0;
1469 r->offLang = sizeof(*r);
1470 p = ((char *)(r)) + r->offLang;
1471 strcpy(p, XmToggleButtonGadgetGetState(w) ? client : "default");
1472 r->hdr.length = sizeof(*r) + strlen(p) + 1;
1474 TellRequester(buf, (size_t) r->hdr.length);
1476 CleanupAndExit(NULL, NOTIFY_LANG_CHANGE);
1480 /***************************************************************************
1482 * RespondChallengeCB
1484 * Respond to a challenge request from client
1485 ***************************************************************************/
1493 char buf[REQUEST_LIM_MAXLEN];
1494 ResponseChallenge *r = (ResponseChallenge *)buf;
1497 LoginTextPtr textdata;
1500 vg_TRACE_EXECUTION("main: entered RespondChallengeCB ...");
1501 #endif /* VG_TRACE */
1503 XtSetSensitive(ok_button, False);
1504 XtSetSensitive(clear_button, False);
1505 XtSetSensitive(options_button, False);
1506 XtSetSensitive(help_button, False);
1508 textdata = GetLoginTextPtr(login_text);
1511 * Get username and password. Username is obtained from widget
1512 * while password is stored in global buffer.
1514 if (textdata->bEcho)
1516 value = XmTextFieldGetString(login_text);
1517 textdata->offGreetingUname = strdup(value);
1518 userName = strdup(value);
1519 if (strlen(textdata->offGreetingUname) > (size_t) 16)
1521 textdata->offGreetingUname[16] = '\0';
1522 userName[16] = '\0';
1527 value = textdata->noechobuf;
1530 r->hdr.opcode = REQUEST_OP_CHALLENGE;
1531 r->hdr.reserved = 0;
1532 r->offResponse = sizeof(*r);
1533 p = buf + r->offResponse;
1535 r->hdr.length = r->offResponse + strlen(p) + 1;
1537 if (textdata->bEcho)
1540 XmTextFieldSetString(login_text, "");
1545 * Clean password memory to foil snoopers.
1547 bzero(textdata->noechobuf, strlen(textdata->noechobuf));
1550 TellRequester(buf, (size_t) r->hdr.length);
1553 /***************************************************************************
1557 * Respond to a request that displayed a dialog
1558 ***************************************************************************/
1564 XtPointer call_data)
1566 char buf[REQUEST_LIM_MAXLEN];
1567 XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *)call_data;
1570 vg_TRACE_EXECUTION("main: entered RespondDialogCB ...");
1571 #endif /* VG_TRACE */
1573 if (w == error_message)
1575 ResponseMessage *r= (ResponseMessage *)buf;
1577 r->hdr.opcode = REQUEST_OP_MESSAGE;
1578 r->hdr.reserved = 0;
1579 r->hdr.length = sizeof(*r);
1581 TellRequester(buf, (size_t) r->hdr.length);
1583 else if (w == passwd_message)
1585 if (reason->reason == XmCR_OK)
1587 CleanupAndExit(w, NOTIFY_PASSWD_EXPIRED);
1591 ResponseExpassword *r= (ResponseExpassword *)buf;
1593 r->hdr.opcode = REQUEST_OP_EXPASSWORD;
1594 r->hdr.reserved = 0;
1595 r->hdr.length = sizeof(*r);
1597 TellRequester(buf, (size_t) r->hdr.length);
1600 else if (w == hostname_message)
1602 if (reason->reason == XmCR_OK)
1604 CleanupAndExit(w, NOTIFY_OK);
1608 CleanupAndExit(w, NOTIFY_NO_WINDOWS);
1613 /***************************************************************************
1617 * save the default dt widget.
1618 **************************************************************************/
1620 SetDefaultDt(Widget w)
1625 /***************************************************************************
1629 * label to display in the dt_label widget and
1630 * the logo to display in logo_pixmap
1631 **************************************************************************/
1635 static XmString blanks = NULL;
1642 vg_TRACE_EXECUTION("main: entered SetDtLabelAndIcon ...");
1643 #endif /* VG_TRACE */
1646 blanks = XmStringCreateLocalized(" ");
1649 * if user is logging in, set dt_label desired. No more than
1650 * one desktop can be selected at a time ...
1653 XtSetArg(argt[0], XmNset, FALSE); i++;
1655 XtSetValues(options_failsafe, argt, i);
1656 XtSetValues(options_dtlite, argt, i);
1657 XtSetValues(options_dt, argt, i);
1658 if (options_last_dt != NULL)
1659 XtSetValues(options_last_dt, argt, i);
1661 for(i = 0; i<appInfo.altDts ; ++i)
1662 if(alt_dts[i] != NULL)
1663 XtSetValues(alt_dts[i], argt, i);
1665 if (NULL != default_dt) {
1667 XtSetArg(argt[i], XmNset, True); i++;
1668 XtSetValues(default_dt, argt, i);
1670 if(default_dt == options_last_dt)
1675 XtSetArg(argt[i], XmNlabelString, &xmstr); i++;
1676 XtGetValues(default_dt, argt, i);
1680 XtSetArg(argt[i], XmNuserData, &logoFile); i++;
1681 XtGetValues(default_dt, argt, i);
1685 logoFile = logoInfo.bitmapFile;
1688 #ifdef FIX_FOR_DEFECT_CDExc19307
1690 * This code causes the Session toggle buttons to be reset
1691 * to the default setting when the user commits a typing error.
1692 * NOT very user friendly.
1694 * As for setting the defaults after the user is done entering
1695 * the we could do the same thing by passing in an argument. For
1696 * now, I'm not convinced that it is required.
1700 * to set the defaults after the user is done
1701 * entering the login ..
1703 if (strcmp(userName,"\0") != 0)
1704 strcpy(userName,"\0");
1708 XtSetArg(argt[i], XmNlabelString, xmstr); i++;
1709 XtSetValues(dt_label, argt, i);
1712 * remove trailing spaces
1714 if(strchr(logoFile,' '))
1715 temp_p = strtok(logoFile," ");
1719 logoName = _DtGetIconFileName(
1720 DefaultScreenOfDisplay(dpyinfo.dpy),
1721 temp_p, NULL, NULL, NULL);
1723 if (logoName == NULL) {
1725 ReadCatalog(MC_LOG_SET,MC_LOG_NO_LOGOBIT,MC_DEF_LOG_NO_LOGOBIT),
1731 XtSetArg(argt[i], XmNimageName, logoName); i++;
1732 XtSetValues(logo_pixmap, argt, i);
1735 /***************************************************************************
1739 * display a dialog message box
1740 ***************************************************************************/
1743 _DtShowDialog( DialogType dtype, XmString msg)
1748 vg_TRACE_EXECUTION("main: entered _DtShowDialog ...");
1749 #endif /* VG_TRACE */
1752 case copyright: w = ©right_msg; break;
1753 case error: w = &error_message; break;
1754 case expassword: w = &passwd_message; break;
1755 case help: w = &help_message; break;
1756 case hostname: w = &hostname_message; break;
1757 case help_chooser: w = &help_message; break;
1765 if ( msg != NULL ) {
1766 XtSetArg(argt[0], XmNmessageString, msg );
1767 XtSetValues(*w, argt, 1);
1772 XSetInputFocus(XtDisplay(*w), XtWindow(*w),
1773 RevertToPointerRoot, CurrentTime);
1779 /***************************************************************************
1783 * callback to display a dialog message box
1784 ***************************************************************************/
1787 ShowDialogCB( Widget w, XtPointer dialog, XtPointer call_data )
1790 _DtShowDialog( (DialogType) dialog, NULL);
1796 /***************************************************************************
1800 * set focusWidget global variable when focus changes
1801 ***************************************************************************/
1805 TextFocusCB( Widget w, XtPointer client_data, XtPointer call_data )
1807 if ( w == login_text )
1811 /***************************************************************************
1815 * Return login text widget instance data
1816 ***************************************************************************/
1819 GetLoginTextPtr( Widget w )
1821 LoginTextPtr textdata;
1825 XtSetArg(argt[i], XmNuserData, &textdata ); i++;
1826 XtGetValues(w, argt, i);
1833 /***************************************************************************
1835 * PromptSensitivityLevel
1837 * Prompt for B1 Sensitivity Level. The password widget set is reused for
1838 * this purpose rather than creating another complete widget set. It already
1839 * has most of the proper size and alignment specifications needed. Using
1840 * the password set also allows the B1 code changes to be more localized.
1842 ***************************************************************************/
1845 PromptSensitivityLevel( void)
1849 int i, width1, width2;
1852 * Use the password widget set to prompt for the B1 Sensitivity Level.
1853 * Remember to put it back to normal if the user presses [Clear].
1856 normalPasswordWidget = False;
1858 XtRemoveAllCallbacks(_text, XmNmodifyVerifyCallback);
1859 XmTextFieldSetString(_text,"");
1863 * Change the label and resize the password form...
1867 XtSetArg(argt[i], XmNresizable, True ); i++;
1868 XtSetArg(argt[i], XmNresizePolicy, XmRESIZE_ANY ); i++;
1869 XtSetValues(_form, argt, i);
1872 xmstr = ReadCatalogXms(MC_LABEL_SET, -1, "Sensitivity Level:");
1873 XtSetArg(argt[i], XmNrecomputeSize, True ); i++;
1874 XtSetArg(argt[i], XmNlabelString, xmstr ); i++;
1875 XtSetValues(_label, argt, i);
1877 XmStringFree(xmstr);
1880 * Center the form horizontally in the login_matte...
1884 CenterForm(matte1, _form);
1886 ProcessTraversal(_text, XmTRAVERSE_CURRENT);
1894 TellRequester(char * buf, size_t nbytes)
1897 vg_TRACE_EXECUTION("main: entered TellRequester ...");
1898 #endif /* VG_TRACE */
1899 write(1, buf, nbytes);