Files
cdesktop/cde/programs/dtlogin/vgcallback.c
Lev Kujawski 356ac2f327 Purge unused Freetype dependency from CDE
config/cf/{DragonFly,OpenBSD,darwin}.cf: Remove Freetype imake settings
config/cf/darwinLib.tmpl: Do not link against Freetype
debian/control: Remove Freetype and Xft dependencies
*/Imakefile: Purge Freetype includes

lib/DtWidget/ComboBoxP.h
lib/DtWidget/SpinBoxP.h
programs/dtfile/ChangeDirP.c
programs/dtlogin/vgcallback.c
    Undefine USE_XFT so Motif 2.3 doesn't pull in Freetype

CDE included Freetype and Xft solely to satisfy builds of Motif with
Xft support enabled. However, as CDE only supports bitmap fonts, this
dependency was entirely superfluous and unnecessarily broke backwards
compatibility with older systems.
2021-06-02 19:56:26 -06:00

1950 lines
48 KiB
C

/*
* 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
*/
/* $TOG: vgcallback.c /main/16 1998/11/02 18:34:55 mgreess $ */
/* *
* (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. *
*/
/************************************<+>*************************************
****************************************************************************
**
** File: vgcallback.c
**
** Project: HP Visual User Environment (DT)
**
** Description: Callback routines Dtgreet application.
**
** These routines handle the callbacks from the widgets.
**
**
** (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company
**
**
**
****************************************************************************
************************************<+>*************************************/
/***************************************************************************
*
* Includes
*
***************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <Xm/Xm.h>
#include <Xm/MessageB.h>
#include <Xm/TextF.h>
#undef USE_XFT
#include <Xm/TextFP.h>
#include <Xm/PushBG.h>
#include <Xm/ToggleBG.h>
#include <Dt/IconFile.h>
#include <Dt/Icon.h>
#include <pwd.h>
#ifdef AUDIT
# include <sys/audit.h>
#endif
/* necessary for bzero */
#ifdef SVR4
#include <X11/Xfuncs.h>
#endif
#include "vg.h"
#include "vgmsg.h"
/***************************************************************************
*
* External declarations
*
***************************************************************************/
extern LogoInfo logoInfo; /* information about the logo */
/***************************************************************************
*
* Procedure declarations
*
***************************************************************************/
static void CenterForm( Widget w1, Widget w2);
static void PingLost( void ) ;
static SIGVAL PingBlocked( int arg ) ;
static void ProcessTraversal( Widget w, int direction) ;
static void _DtShowDialog(DialogType dtype, XmString msg);
static void TellRequester(char * buf, size_t nbytes);
# ifdef BLS
static void PromptSensitivityLevel(void); /* prompt for B1 Sen. Level */
int VerifySensitivityLevel(void); /* verify B1 Sensitivity Level */
# endif
static int session_selected = False;
static Widget default_dt = NULL;
/***************************************************************************
*
* Global variables
*
***************************************************************************/
Widget focusWidget = NULL;
char *userName = "\0";
struct passwd *user_p;
#ifdef BLS
static int normalPasswordWidget = True;
char *sensitivityLevel = NULL;
#endif
#ifndef SVR4
long groups[NGROUPS];
#endif
#ifdef SIA
#include <alloca.h>
SiaFormInfo siaFormInfo;
XmString multiline_xmstring(char *text)
{
char *start, *end;
Boolean done;
XmString string = NULL;
XmString tmp_string;
XmString separator = NULL;
char *buffer;
if (!text) return (NULL);
buffer = alloca(strlen((const char *)text) + 1);
start = text;
done = FALSE;
while ( ! done) /* loop thu local copy */
{ /* looking for \n */
end = start;
while ((*end != '\0') && (*end != '\n')) end++;
if (*end == '\0')
done = TRUE; /* we are at the end */
/* Don't convert empty string unless it's an initial newline. */
if ((start != end) || (start == text))
{
strncpy(buffer, start, end - start);
buffer[end - start] = '\0';
if (!string)
string = XmStringCreate(buffer, XmFONTLIST_DEFAULT_TAG);
else
{
tmp_string = XmStringCreate(buffer, XmFONTLIST_DEFAULT_TAG);
string = XmStringConcat(string, tmp_string);
XmStringFree(tmp_string);
}
}
/* Make a separator if this isn't the last segment. */
if (!done)
{
if (!separator)
separator = XmStringSeparatorCreate();
string = XmStringConcat(string, separator);
start = ++end; /* start at next char */
}
}
if (separator)
XmStringFree(separator);
return (string);
}
#endif /* SIA */
/***************************************************************************
*
* CenterForm
*
* Utility function to center one form horizontally within another.
***************************************************************************/
static void
CenterForm( Widget w1, Widget w2 )
{
Dimension width;
int i, width1, width2;
XtSetArg(argt[0], XmNwidth, &width);
XtGetValues(w1, argt, 1);
width1 = (int)width;
XtSetArg(argt[0], XmNwidth, &width);
XtGetValues(w2, argt, 1);
width2 = (int)width;
i = 0;
XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM ); i++;
XtSetArg(argt[i], XmNleftOffset, (width1 - width2) / 2 ); i++;
XtSetValues(w2, argt, i);
}
/***************************************************************************
*
* CleanupAndExit
*
* close things down gracefully and exit
***************************************************************************/
void
CleanupAndExit( Widget w, int exit_code )
{
int i;
Boolean toggleon; /* status of session toggle buttons */
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered CleanupAndExit ...");
#endif /* VG_TRACE */
if (w != NULL)
XtDestroyWidget(w);
/*
* if user is logging in, set type of session desired. No more than
* one session type can be selected at a time (if any) ...
*/
if ( exit_code == NOTIFY_OK ) {
XtSetArg(argt[0], XmNset, &toggleon );
XtGetValues(options_failsafe, argt, 1);
if ( toggleon ) exit_code = NOTIFY_FAILSAFE;
XtGetValues(options_dtlite, argt, 1);
if ( toggleon ) exit_code = NOTIFY_DTLITE;
XtGetValues(options_dt, argt, 1);
if ( toggleon ) exit_code = NOTIFY_DT;
if(options_last_dt != NULL) {
XtGetValues(options_last_dt, argt, 1);
if ( toggleon ) exit_code = NOTIFY_LAST_DT;
}
for(i = 0; i < appInfo.altDts ; ++i) {
if(alt_dts[i] != NULL) {
XtGetValues(alt_dts[i], argt, 1);
if ( toggleon ) exit_code = NOTIFY_ALT_DTS + i + 1; /* alt desktops start at 1 */
}
}
}
if (!session_selected)
exit_code = NOTIFY_OK;
CloseCatalog();
ChangeBell("on");
UnsecureDisplay();
XSync (dpyinfo.dpy, 0);
XtCloseDisplay(dpyinfo.dpy);
exit (exit_code);
}
/***************************************************************************
*
* ClearDtlabel
*
***************************************************************************/
static void
ClearDtlabel(void)
{
int i;
XmString xms;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("ClearDtlabel: entered ...");
#endif /* VG_TRACE */
i = 0;
xms = XmStringCreateLocalized(" ");
XtSetArg(argt[i], XmNlabelString, xms); i++;
XtSetValues(dt_label, argt, i);
XmStringFree(xms);
}
/***************************************************************************
*
* ClearDtlabel
*
***************************************************************************/
static void
ClearDtButtons(void)
{
int i;
/*
* Clear Dt toggles...
*/
XtSetArg(argt[0], XmNset, False);
for (i=0; i<appInfo.altDts; ++i)
if (alt_dts[i] != NULL)
XtSetValues(alt_dts[i], argt, 1);
if (options_failsafe) XtSetValues(options_failsafe, argt, 1);
if (options_dtlite) XtSetValues(options_dtlite, argt, 1);
if (options_dt) XtSetValues(options_dt, argt, 1);
if (options_last_dt) XtSetValues(options_last_dt, argt, 1);
}
/***************************************************************************
*
* RespondClearCB
*
* clear name/password text fields
***************************************************************************/
void
RespondClearCB( Widget w, XtPointer client, XtPointer call )
{
char buf[REQUEST_LIM_MAXLEN];
ResponseClear *r = (ResponseClear *)buf;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered RespondClearCB ...");
#endif /* VG_TRACE */
ClearDtlabel();
ClearDtButtons();
SetDefaultDt(NULL);
r->hdr.opcode = REQUEST_OP_CLEAR;
r->hdr.reserved = 0;
r->hdr.length = sizeof(*r);
TellRequester(buf, (size_t) r->hdr.length);
}
/***************************************************************************
*
* CopyrightCB
*
* move the highlight back to login or password fields AFTER the copyright
* dialog is unposted.
*
***************************************************************************/
void
CopyrightCB( Widget w, XtPointer client_data, XtPointer call_data )
{
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered CopyrightCB ...");
#endif /* VG_TRACE */
if ( focusWidget != NULL)
ProcessTraversal(focusWidget, XmTRAVERSE_CURRENT);
}
/***************************************************************************
*
* EditPasswdCB
*
* implement no-echo and no-cursor motion of the password
***************************************************************************/
void
EditPasswdCB(Widget w, XtPointer client, XtPointer call_data)
{
LoginTextPtr textdata;
XmTextVerifyPtr cbs = (XmTextVerifyPtr) call_data;
int i;
static char buffer[MAXPATHLEN];
char *s, *t;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered EditPasswdCB ...");
vg_TRACE_EXECUTION(
"currInsert=%d newInsert=%d startPos=%d endPos=%d\n",
cbs->currInsert,cbs->newInsert,cbs->startPos, cbs->endPos);
if (cbs->text->ptr) vg_TRACE_EXECUTION("text->ptr=%s\n", cbs->text->ptr);
vg_TRACE_EXECUTION("noechobuf=%s\n", textdata->noechobuf);
#endif /* VG_TRACE */
textdata = GetLoginTextPtr(w);
if (NULL == textdata || textdata->bEcho) return;
if (cbs->reason == XmCR_MOVING_INSERT_CURSOR) return;
for (i=0, s=buffer, t=textdata->noechobuf;
(*t && i<cbs->startPos);
i++, s++, t++)
*s = *t;
if (cbs->text->ptr)
{
snprintf(s, sizeof(buffer) - (s - buffer), "%s", cbs->text->ptr);
s += cbs->text->length;
}
else
*s = '\0';
if (strlen(textdata->noechobuf) >= cbs->endPos)
{
t = textdata->noechobuf+cbs->endPos;
if (strlen(t))
strcpy(s, t);
}
strcpy(textdata->noechobuf, buffer);
if (cbs->text->ptr)
for (i=0, s=cbs->text->ptr; i<cbs->text->length; i++, s++)
*s = '*';
#ifdef VG_TRACE
vg_TRACE_EXECUTION("textdata->noechobuf=%s\n", textdata->noechobuf);
#endif
}
/***************************************************************************
*
* FakeFocusIn
*
* simulate a FocusIn event to the login_shell in order to turn on
* traversal. There is a bug in the Toolkit that is normally masked by
* the window manager. Since we have no window manager, we need to simulate
* the FocusIn event it sends to the application.
*
* Also force the initial focus to the login_text widget.
***************************************************************************/
void
FakeFocusIn( Widget focus_widget, XtPointer client_data, XEvent *eventprm,
Boolean *continue_to_dispatch )
{
XEvent event;
XEvent * eventPtr = &event;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered FakeFocusIn ...");
#endif /* VG_TRACE */
/*
* set the input focus to the login text widget...
*/
XSetInputFocus( XtDisplay(focus_widget),
XtWindow(focus_widget),
RevertToNone,
CurrentTime);
/*
* create a synthetic focus-in event.
*
* Note: The above call to XSetInputFocus() was not originally included
* in this routine. A bug fix to Motif made it necessary to add
* the call. The synthetic focus-in event is probably now
* unnecessary but is left in for caution's sake. (12/08/92)
*/
/* focus_widget = login_shell; */
eventPtr->type = FocusIn;
eventPtr->xfocus.serial = LastKnownRequestProcessed(XtDisplay(focus_widget));
eventPtr->xfocus.send_event = True;
eventPtr->xfocus.display = XtDisplay(focus_widget);
eventPtr->xfocus.window = XtWindow(focus_widget);
eventPtr->xfocus.mode = NotifyNormal;
eventPtr->xfocus.detail = NotifyAncestor;
XtDispatchEvent (eventPtr);
ProcessTraversal(focus_widget, XmTRAVERSE_CURRENT);
XtRemoveEventHandler(focus_widget, ExposureMask, FALSE,
FakeFocusIn, NULL);
}
/***************************************************************************
*
* LayoutCB
*
* do final layout adjustments right before windows are mapped. This is
* necessary because the size of managers (Forms, etc) is not known until
* their window has been created (XtRealize). We want to make adjustments
* before the windows become visible
*
* 1. squeeze dialog width to fit on screen.
* 2. increase dialog height if widgets overlap.
* 3. center the main matte horizontally and vertically
* 4. position the pushbuttons
* 5. position the copyright
*
***************************************************************************/
void
LayoutCB( Widget w, XtPointer client_data, XtPointer call_data )
{
int i, j;
Dimension width, height; /* size values returned by XtGetValues */
Dimension shadowThickness;/* size values returned by XtGetValues */
Position x, y; /* position values returned by XtGetValues */
int dpwidth, dpheight; /* JET - display w/h set according to */
int xorg, yorg; /* xinerama usage */
struct { /* position, size of widgets (pixels) */
int x, y;
int width;
int height;
} mw, pw; /* matte, logo, drop shadow, login matte
and greeting widgets */
int width1, width2; /* general width variable */
int height1; /* general height variable */
Position x1, y1; /* general position variables */
int offsety; /* general offset variable */
int shadow_offsetx; /* offset for drop shadow (pixels) */
int shadow_offsety; /* offset for drop shadow (pixels) */
int spacing; /* spacing between login & matte bottoms */
Widget buttons[4]; /* pushbutton widgets */
XtWidgetGeometry geometry; /* geometry of a widget */
int max_width; /* maximum width of a set of widgets */
int origin; /* horizontal origin for button placement */
int space; /* total available space left between buttons */
int overlap; /* possible widget overlap */
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered LayoutCB ...");
#endif /* VG_TRACE */
#ifdef USE_XINERAMA
/* get info on the prefered screen */
if (!_DtXineramaGetScreen(dpyinfo.DtXineramaInfo,
appInfo.xineramaPreferredScreen,
&dpwidth, &dpheight, &xorg, &yorg))
{ /* no joy here either - setup for normal */
dpwidth = dpyinfo.width;
dpheight = dpyinfo.height;
xorg = yorg = 0;
}
#else /* no Xinerama */
dpwidth = dpyinfo.width;
dpheight = dpyinfo.height;
xorg = yorg = 0;
#endif
/*
* - squeeze dialog to fit onto screen (if necessary)
*/
i = 0;
XtSetArg(argt[i], XmNwidth, &width ); i++;
XtGetValues(matte, argt, i);
mw.width = ToPixel(matte, XmHORIZONTAL, (int)width );
#define HMARGIN 4 /* min sum horizontal margin of matte */
if (mw.width+HMARGIN > dpwidth)
{
int delta = mw.width + HMARGIN - dpwidth;
/*
* Matte width greater than screen so shrink matteFrame
* and matte1 width to compensate.
*/
i=0;
XtSetArg(argt[i], XmNwidth, &width ); i++;
XtGetValues(matteFrame, argt, i);
width1 = ToPixel(matteFrame, XmHORIZONTAL, (int)width );
width1 -= delta;
width1 = FromPixel(matteFrame, XmHORIZONTAL, width1 );
i=0;
XtSetArg(argt[i], XmNwidth, width1 ); i++;
XtSetValues(matteFrame, argt, i);
width1 = dpwidth - HMARGIN;
mw.width = FromPixel(matte, XmHORIZONTAL, width1 );
i=0;
XtSetArg(argt[i], XmNwidth, mw.width ); i++;
XtSetValues(matte, argt, i);
}
/*
* - Make sure the login widgets don't overlap.
*/
if (login_form) {
i = 0;
XtSetArg(argt[i], XmNy, &y ); i++;
XtSetArg(argt[i], XmNheight, &height ); i++;
XtGetValues(greeting, argt, i);
i = 0;
XtSetArg(argt[i], XmNy, &y1 ); i++;
XtGetValues(login_form, argt, i);
overlap = y + height - y1;
if (overlap > -10) {
i = 0;
XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
XtSetArg(argt[i], XmNbottomWidget, login_form); i++;
XtSetArg(argt[i], XmNbottomOffset, 10); i++;
XtSetValues(greeting, argt, i);
}
}
/*
* - center the main matte horizontally and vertically...
*/
i = 0;
XtSetArg(argt[i], XmNx, &x ); i++;
XtSetArg(argt[i], XmNy, &y ); i++;
XtSetArg(argt[i], XmNwidth, &width ); i++;
XtSetArg(argt[i], XmNheight, &height ); i++;
XtSetArg(argt[i], XmNshadowThickness, &shadowThickness ); i++;
XtGetValues(matte, argt, i);
mw.width = ToPixel(matte, XmHORIZONTAL, (int)width );
mw.height = ToPixel(matte, XmVERTICAL, (int)height );
mw.x = ( x > 0 ? ToPixel(matte, XmHORIZONTAL, (int) x)
: (dpwidth - mw.width)/2 );
mw.y = ( y > 0 ? ToPixel(matte, XmVERTICAL, (int) y)
: (dpheight - mw.height)/2 );
if ( mw.x < 0 ) mw.x = 0;
if ( mw.y < 0 ) mw.y = 0;
x1 = FromPixel(matte, XmHORIZONTAL, mw.x );
y1 = FromPixel(matte, XmVERTICAL, mw.y );
x1 += xorg; /* JET - adjust for xinerama */
y1 += yorg;
i = 0;
XtSetArg(argt[i], XmNx, x1 ); i++;
XtSetArg(argt[i], XmNy, y1 ); i++;
XtSetValues(matte, argt, i);
/*
* space the buttons horizontally. Start at the center of the matte
* and allow them to grow towards the edges...
*/
i = 0;
XtSetArg(argt[i], XmNwidth, &width ); i++;
XtGetValues(matte1, argt, i);
max_width = width;
i = 0;
XtSetArg(argt[i], XmNwidth, &width ); i++;
XtGetValues(clear_button, argt, i);
space = max_width - 4*width;
spacing = space/4;
if (spacing < 12) spacing = 12;
i = 0;
XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM); i++;
XtSetArg(argt[i], XmNleftOffset, spacing/2); i++;
XtSetValues(ok_button, argt, i);
i = 0;
XtSetArg(argt[i], XmNleftAttachment, XmATTACH_WIDGET ); i++;
XtSetArg(argt[i], XmNleftWidget, ok_button); i++;
XtSetArg(argt[i], XmNleftOffset, spacing); i++;
XtSetValues(clear_button, argt, i);
i = 0;
XtSetArg(argt[i], XmNleftAttachment, XmATTACH_WIDGET ); i++;
XtSetArg(argt[i], XmNleftWidget, clear_button); i++;
XtSetArg(argt[i], XmNleftOffset, spacing); i++;
XtSetValues(options_button, argt, i);
i = 0;
XtSetArg(argt[i], XmNleftAttachment, XmATTACH_WIDGET ); i++;
XtSetArg(argt[i], XmNleftWidget, options_button); i++;
XtSetArg(argt[i], XmNleftOffset, spacing); i++;
XtSetValues(help_button, argt, i);
/*
* - adjust the copyright vertically to align top with login_matte...
*/
if (copyright_msg) {
XtQueryGeometry(copyright_msg, NULL, &geometry);
i = 0;
XtSetArg(argt[i], XmNshadowThickness, &width ); i++;
XtGetValues(copyright_msg, argt, i);
width1 = ToPixel(copyright_msg, XmHORIZONTAL, width);
width1 = (dpwidth - (int) geometry.width - 2 * width1)/2;
x1 = FromPixel(copyright_msg, XmHORIZONTAL, width1);
y1 = FromPixel(copyright_msg, XmVERTICAL, mw.y);
i = 0;
XtSetArg(argt[i], XmNdefaultPosition, False ); i++;
XtSetArg(argt[i], XmNx, x1 ); i++;
XtSetArg(argt[i], XmNy, y1 ); i++;
XtSetValues(copyright_msg, argt, i);
}
}
/***************************************************************************
*
* MenuItemCB
*
* callback for options menu items
***************************************************************************/
void
MenuItemCB( Widget w, XtPointer client_data, XtPointer call_data )
{
int i;
char *logoFile;
char *logoName;
char *temp_p;
char temp[MAXPATHLEN];
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered MenuItemCB ...");
#endif /* VG_TRACE */
session_selected = True;
switch ( (long) client_data) {
case OB_RESTART_SERVER:
CleanupAndExit(NULL, NOTIFY_RESTART);
break;
case OB_NO_WINDOWS:
CleanupAndExit(NULL, NOTIFY_NO_WINDOWS);
break;
case OB_COPYRIGHT:
_DtShowDialog(copyright, NULL);
break;
case OB_ALT_DTS:
case OB_FAILSAFE:
case OB_DTLITE:
case OB_DT:
case OB_LAST_DT:
/*
* set the label on the dt_label widget..
*/
if(w != options_last_dt) {
XtSetArg(argt[0], XmNlabelString, &xmstr);
XtGetValues(w, argt, 1);
XtSetArg(argt[0], XmNlabelString, xmstr);
XtSetValues(dt_label, argt, 1);
}
else
ClearDtlabel();
i = 0;
XtSetArg(argt[i], XmNuserData, &logoFile ); i++;
XtGetValues(w, argt, i);
/*
* remove trailing spaces
*/
if(strchr(logoFile,' '))
temp_p = strtok(logoFile," ");
else
temp_p = logoFile;
logoName = _DtGetIconFileName(DefaultScreenOfDisplay(dpyinfo.dpy),
temp_p, NULL, NULL, 0);
if (logoName == NULL) {
LogError(
ReadCatalog(MC_LOG_SET,MC_LOG_NO_LOGOBIT,MC_DEF_LOG_NO_LOGOBIT),
logoFile);
logoFile = NULL;
}
i = 0;
XtSetArg(argt[i], XmNimageName, logoName); i++;
XtSetValues(logo_pixmap, argt, i);
/*
* Clear Dt toggles...
*/
ClearDtButtons();
/*
* set the selected toggle button...
*/
XtSetArg(argt[0], XmNset, True);
XtSetValues(w, argt, 1);
SetDefaultDt(w);
/*
* return focus to name/password widgets...
*/
if ( focusWidget != NULL)
ProcessTraversal(focusWidget, XmTRAVERSE_CURRENT);
break;
}
}
/***************************************************************************
*
* OptionsUnmapCB
*
* callback when options menu unmaps
***************************************************************************/
void
OptionsUnmapCB( Widget wd, XtPointer client_data, XtPointer call_data )
{
int i;
Dimension width, height;
Widget w;
XEvent event;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered OptionsUnmapCB ...");
#endif /* VG_TRACE */
/*
* simulate an exposure event over the Options pushbutton to make sure
* the pushbutton elevates. (there is a bug in the toolkit where this
* doesn't always happen on some servers)...
*/
w = options_button;
i = 0;
XtSetArg(argt[i], XmNwidth, &width ); i++;
XtSetArg(argt[i], XmNheight, &height ); i++;
XtGetValues(w, argt, i);
event.type = Expose;
event.xexpose.serial = LastKnownRequestProcessed(XtDisplay(w));
event.xexpose.send_event = True;
event.xexpose.display = XtDisplay(w);
event.xexpose.window = XtWindow(w);
event.xexpose.x = 0;
event.xexpose.y = 0;
event.xexpose.width = 1; /* one pixel seems to be good enough, */
event.xexpose.height = 1; /* but time will tell... */
#if 0
event.xexpose.width = ToPixel(matte, XmHORIZONTAL, (int)width );
event.xexpose.height = ToPixel(matte, XmVERTICAL, (int)height );
#endif
event.xexpose.count = 0;
XtDispatchEvent (&event);
}
/***************************************************************************
*
* PingServerCB
*
* Ping the server occasionally with an Xsync to see if it is still there.
* We do this here rather than in dtlogin since dtgreet has the server
* grabbed.
*
***************************************************************************/
static jmp_buf pingTime;
static int serverDead = FALSE;
static int pingInterval = 0; /* ping interval (sec.) */
static int pingTimeout; /* ping timeout (sec.) */
static void
PingLost( void )
{
serverDead = TRUE;
longjmp (pingTime, 1);
}
static SIGVAL
PingBlocked( int arg )
{
serverDead = TRUE;
longjmp (pingTime, 1);
}
int
PingServer( void )
{
int (*oldError)();
SIGVAL (*oldSig)();
int oldAlarm;
oldError = XSetIOErrorHandler ((XIOErrorHandler)PingLost);
oldAlarm = alarm (0);
oldSig = signal (SIGALRM, PingBlocked);
alarm (pingTimeout * 60);
if (!setjmp (pingTime))
{
XSync (dpyinfo.dpy, 0);
}
else
{
if ( serverDead ) {
LogError(ReadCatalog(
MC_LOG_SET,MC_LOG_DEADSRV,MC_DEF_LOG_DEADSRV),
dpyinfo.name);
alarm (0);
signal (SIGALRM, SIG_DFL);
XSetIOErrorHandler (oldError);
return 0;
}
}
alarm (0);
signal (SIGALRM, oldSig);
alarm (oldAlarm);
XSetIOErrorHandler (oldError);
return 1;
}
void
PingServerCB( XtPointer call_data, XtIntervalId *id )
{
char *t;
/*
* get ping values from the environment...
*/
if ( pingInterval == 0 ) {
pingInterval = ((t = (char *)getenv(PINGINTERVAL)) == NULL ? 0 : atoi(t));
pingTimeout = ((t = (char *)getenv(PINGTIMEOUT)) == NULL ? 0 : atoi(t));
}
/*
* ping the server. If successful, set a timer for the next ping,
* otherwise cleanup and exit...
*/
if ( pingInterval != 0 ) {
if (PingServer())
XtAddTimeOut((unsigned long) pingInterval * 60 * 1000,
PingServerCB, NULL);
else
exit(NOTIFY_RESTART);
}
}
/***************************************************************************
*
* PostMenuCB
*
* post the option_button pop-up menu
***************************************************************************/
void
PostMenuCB( Widget w, XtPointer client_data, XtPointer call_data )
{
XmAnyCallbackStruct *p;
p = (XmAnyCallbackStruct *) call_data;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered PostMenuCB ...");
#endif /* VG_TRACE */
/*
* make options menus if they don't yet exist...
*/
if (options_menu == NULL)
MakeOptionsMenu();
/*
* post menu...
*/
if (p->reason == XmCR_ARM &&
p->event->type == ButtonPress) {
XmMenuPosition(options_menu, p->event);
XtManageChild(options_menu);
}
}
/***************************************************************************
*
* ProcessTraversal
*
* move the input focus
***************************************************************************/
static void
ProcessTraversal( Widget w, int direction )
{
int i;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered ProcessTraversal ...");
#endif /* VG_TRACE */
i = XmProcessTraversal(w, direction);
#ifndef __hpux
/*
* Versions of Motif other than HP do not support the XmfocusCallback
* on the TextField widget. We simulate it here by manually invoking the
* callback routine...
*/
TextFocusCB(w, NULL, NULL);
#endif
}
/***************************************************************************
*
* RefreshEH
*
* cause the entire screen to refresh via exposure events
***************************************************************************/
void
RefreshEH( Widget w, XtPointer client_data, XEvent *event,
Boolean *continue_to_dispatch )
{
Window cover;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered RefreshEH ...");
#endif /* VG_TRACE */
/*
* map/unmap a window that covers the entire screen. The resultant
* exposure events will refresh the screen. Note, the default
* background pixmap is NONE.
*/
cover = XCreateWindow ( dpyinfo.dpy, /* display */
dpyinfo.root, /* root window ID */
0, /* x origin */
0, /* y origin */
dpyinfo.width, /* width */
dpyinfo.height, /* height */
0, /* border width */
0, /* depth */
InputOutput, /* class */
CopyFromParent, /* visual */
0, /* value mask */
(XSetWindowAttributes *)NULL); /* attributes */
XMapWindow(dpyinfo.dpy, cover);
XDestroyWindow(dpyinfo.dpy, cover);
XFlush(dpyinfo.dpy);
}
/***************************************************************************
*
* RequestCB
*
* Accept a request from client
***************************************************************************/
void
RequestCB(
XtPointer client_data,
int *source,
XtInputId *id)
{
char buf[512];
int count;
int remainder;
RequestHeader *phdr = (RequestHeader *)buf;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered RequestCB ...");
#endif /* VG_TRACE */
/*
* There's a request in the pipe. Read the header.
*/
count = read(0, buf, sizeof(*phdr));
if (count != sizeof(*phdr))
{
return;
}
/*
* Calculate amount of data after header.
*/
remainder = phdr->length - sizeof(*phdr);
if (remainder > 0)
{
/*
* Read remainder of request.
*/
count = read(0, buf+sizeof(*phdr), remainder);
}
/*
* Initiate response to request.
*/
switch(phdr->opcode)
{
case REQUEST_OP_EXIT:
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: got REQUEST_OP_EXIT ...");
#endif /* VG_TRACE */
RespondExitCB(NULL, NULL, NULL);
break;
case REQUEST_OP_MESSAGE:
{
RequestMessage *r = (RequestMessage *)phdr;
XmString string;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: got REQUEST_OP_MESSAGE ...");
#endif /* VG_TRACE */
if (r->idMC)
{
FILE *fp;
/*
* Caller passed in MC_* message id.
*/
if (r->idMC == MC_NO_LOGIN &&
(fp = fopen(NO_LOGIN_FILE,"r")) != NULL)
{
/*
* For MC_NO_LOGIN read message from file.
*/
char buffer[256];
int j;
string = NULL;
while (fgets(buffer, 256, fp) != NULL)
{
j = strlen(buffer);
if ( buffer[j-1] == '\n' ) buffer[j-1] = '\0';
string = XmStringConcat(xmstr,
XmStringCreate(buffer,
XmFONTLIST_DEFAULT_TAG));
string = XmStringConcat(xmstr, XmStringSeparatorCreate());
}
fclose(fp);
}
else
{
/*
* Read message from message catalog.
*/
string = ReadCatalogXms(MC_ERROR_SET, r->idMC, buf+r->offMessage);
}
}
else
{
/*
* Generate message from provided string.
*/
#ifdef SIA
string = multiline_xmstring(buf+r->offMessage);
#else
string = XmStringCreate(buf+r->offMessage,XmFONTLIST_DEFAULT_TAG);
#endif
}
_DtShowDialog(error, string);
XmStringFree(string);
}
break;
case REQUEST_OP_HOSTNAME:
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: got REQUEST_OP_HOSTNAME ...");
#endif /* VG_TRACE */
_DtShowDialog(hostname, NULL);
break;
case REQUEST_OP_EXPASSWORD:
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: got REQUEST_OP_EXPASSWORD ...");
#endif /* VG_TRACE */
_DtShowDialog(expassword, NULL);
break;
case REQUEST_OP_CHPASS:
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: got REQUEST_OP_CHPASS ...");
#endif /* VG_TRACE */
break;
case REQUEST_OP_CHALLENGE:
{
RequestChallenge *r = (RequestChallenge *)phdr;
XmString string;
int i;
LoginTextPtr textdata;
Boolean change;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: got REQUEST_OP_CHALLENGE ...");
#endif /* VG_TRACE */
textdata = GetLoginTextPtr(login_text);
change = (textdata->bEcho != r->bEcho);
XtUnmapWidget(textdata->text[textdata->bEcho]);
textdata->bEcho = r->bEcho;
textdata->noechobuf[0] = '\0';
XtAddEventHandler(textdata->text[textdata->bEcho], ExposureMask, False,
FakeFocusIn, NULL);
XtMapWidget(textdata->text[textdata->bEcho]);
XtPopup(login_shell, XtGrabNone);
XGrabKeyboard (dpyinfo.dpy, XtWindow (textdata->text[textdata->bEcho]),
False, GrabModeAsync, GrabModeAsync, CurrentTime);
XmTextFieldSetString(
textdata->text[textdata->bEcho],
r->offUserNameSeed ? buf+r->offUserNameSeed : "");
XmTextFieldSetSelection (
textdata->text[1],
0, XmTextFieldGetLastPosition(textdata->text[1]),
CurrentTime );
if (r->idMC)
{
/*
* Read message from message catalog.
*/
string = ReadCatalogXms(MC_LABEL_SET, r->idMC, buf+r->offChallenge);
}
else
{
/*
* Generate message from provided string.
*/
string = XmStringCreate(buf+r->offChallenge,XmFONTLIST_DEFAULT_TAG);
}
i = 0;
XtSetArg(argt[i], XmNlabelString, string ); i++;
XtSetValues(login_label, argt, i);
XmStringFree(string);
if (change)
{
char buf[256];
i = 0;
if (textdata->bEcho)
{
XtSetArg(argt[i], XmNlabelString, textdata->onGreeting ); i++;
}
else
{
sprintf(buf, textdata->offGreetingFormat,
textdata->offGreetingUname);
string = XmStringCreate(buf, XmFONTLIST_DEFAULT_TAG);
XtSetArg(argt[i], XmNlabelString, string ); i++;
free(textdata->offGreetingUname);
}
XtSetValues(greeting, argt, i);
/* set the dt_label with the session that is enabled */
SetDtLabelAndIcon();
}
XtSetSensitive(ok_button, True);
XtSetSensitive(clear_button, True);
XtSetSensitive(options_button, True);
XtSetSensitive(help_button, True);
XUngrabKeyboard(dpyinfo.dpy,CurrentTime);
}
break;
#ifdef SIA
case REQUEST_OP_FORM:
{
RequestForm *r = (RequestForm *)buf;
int i;
char *prompt_ptr;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: got REQUEST_OP_FORM ...");
#endif /* VG_TRACE */
siaFormInfo.num_prompts = r->num_prompts;
siaFormInfo.rendition = r->rendition;
siaFormInfo.title = XtMalloc(strlen(buf + r->offTitle));
strcpy(siaFormInfo.title, buf + r->offTitle);
prompt_ptr = buf + r->offPrompts;
for (i=0; i < siaFormInfo.num_prompts; i++)
{
siaFormInfo.visible[i] = r->visible[i];
siaFormInfo.prompts[i] = XtMalloc(strlen(prompt_ptr));
siaFormInfo.answers[i] = NULL;
strcpy(siaFormInfo.prompts[i], prompt_ptr);
prompt_ptr += strlen(prompt_ptr) + 1;
}
/*
* Create Widgets:
* Form
* Title
* prompt labels and answer text fields for each prompt
* OK button
* Add callbacks as needed. If not visible don't echo.
* On OK callback, collect info and send it. Destroy widgets.
*/
SiaForm(&siaFormInfo);
}
break;
#endif /* SIA */
}
#if 0
{
/*
* Send immediate response to debug.
*/
char outbuf[512];
char *p;
ResponseDebug *rdebug = (ResponseDebug *)outbuf;
rdebug->hdr.opcode = REQUEST_OP_DEBUG;
rdebug->hdr.reserved = 0;
rdebug->offString = sizeof(*rdebug);
p = ((char *)(rdebug)) + rdebug->offString;
strcpy(p, "This is my debug string");
rdebug->hdr.length = sizeof(*rdebug) + strlen(p) + 1;
TellRequester(outbuf, (size_t) rdebug->hdr.length);
}
#endif
}
/***************************************************************************
*
* RespondExitCB
*
* Respond to an exit request from client
***************************************************************************/
void
RespondExitCB(
Widget w,
XtPointer client,
XtPointer call)
{
char buf[REQUEST_LIM_MAXLEN];
ResponseExit *r = (ResponseExit *)buf;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered RespondExitCB ...");
#endif /* VG_TRACE */
r->hdr.opcode = REQUEST_OP_EXIT;
r->hdr.reserved = 0;
r->hdr.length = sizeof(*r);
TellRequester(buf, (size_t) r->hdr.length);
CleanupAndExit(NULL, NOTIFY_OK);
}
/***************************************************************************
*
* RespondLangCB
*
* Respond to a lang item selection from user
***************************************************************************/
int amChooser = 0;
int orig_argc;
char **orig_argv;
void
RespondLangCB( Widget w, XtPointer client, XtPointer call)
{
XtSetArg(argt[0], XmNset, True);
XtSetValues(w, argt, 1);
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered RespondLangCB ...");
#endif /* VG_TRACE */
if (amChooser) {
/** this is probably not the ideal way to do this **/
/** but it does work ok. **/
/** notice the related code in chooser.c at the **/
/** beginning of main. **/
char buff[128];
if (XmToggleButtonGadgetGetState(w)) {
snprintf(buff, sizeof(buff), "LANG=%s", (char *) client);
putenv(buff);
execv(orig_argv[0], orig_argv);
}
} else {
char buf[REQUEST_LIM_MAXLEN];
ResponseLang *r = (ResponseLang *)buf;
char *p;
r->hdr.opcode = REQUEST_OP_LANG;
r->hdr.reserved = 0;
r->offLang = sizeof(*r);
p = ((char *)(r)) + r->offLang;
strcpy(p, XmToggleButtonGadgetGetState(w) ? client : "default");
r->hdr.length = sizeof(*r) + strlen(p) + 1;
TellRequester(buf, (size_t) r->hdr.length);
CleanupAndExit(NULL, NOTIFY_LANG_CHANGE);
}
}
/***************************************************************************
*
* RespondChallengeCB
*
* Respond to a challenge request from client
***************************************************************************/
void
RespondChallengeCB(
Widget w,
XtPointer client,
XtPointer call)
{
char buf[REQUEST_LIM_MAXLEN];
ResponseChallenge *r = (ResponseChallenge *)buf;
char *value;
char *p;
LoginTextPtr textdata;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered RespondChallengeCB ...");
#endif /* VG_TRACE */
XtSetSensitive(ok_button, False);
XtSetSensitive(clear_button, False);
XtSetSensitive(options_button, False);
XtSetSensitive(help_button, False);
textdata = GetLoginTextPtr(login_text);
/*
* Get username and password. Username is obtained from widget
* while password is stored in global buffer.
*/
if (textdata->bEcho)
{
value = XmTextFieldGetString(login_text);
textdata->offGreetingUname = strdup(value);
userName = strdup(value);
if (strlen(textdata->offGreetingUname) > (size_t) 16)
{
textdata->offGreetingUname[16] = '\0';
userName[16] = '\0';
}
}
else
{
value = textdata->noechobuf;
}
r->hdr.opcode = REQUEST_OP_CHALLENGE;
r->hdr.reserved = 0;
r->offResponse = sizeof(*r);
p = buf + r->offResponse;
strcpy(p, value);
r->hdr.length = r->offResponse + strlen(p) + 1;
if (textdata->bEcho)
{
XtFree(value);
XmTextFieldSetString(login_text, "");
}
else
{
/*
* Clean password memory to foil snoopers.
*/
bzero(textdata->noechobuf, strlen(textdata->noechobuf));
}
TellRequester(buf, (size_t) r->hdr.length);
}
/***************************************************************************
*
* RespondDialogCB
*
* Respond to a request that displayed a dialog
***************************************************************************/
void
RespondDialogCB(
Widget w,
XtPointer client,
XtPointer call_data)
{
char buf[REQUEST_LIM_MAXLEN];
XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *)call_data;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered RespondDialogCB ...");
#endif /* VG_TRACE */
if (w == error_message)
{
ResponseMessage *r= (ResponseMessage *)buf;
r->hdr.opcode = REQUEST_OP_MESSAGE;
r->hdr.reserved = 0;
r->hdr.length = sizeof(*r);
TellRequester(buf, (size_t) r->hdr.length);
}
else if (w == passwd_message)
{
if (reason->reason == XmCR_OK)
{
CleanupAndExit(w, NOTIFY_PASSWD_EXPIRED);
}
else
{
ResponseExpassword *r= (ResponseExpassword *)buf;
r->hdr.opcode = REQUEST_OP_EXPASSWORD;
r->hdr.reserved = 0;
r->hdr.length = sizeof(*r);
TellRequester(buf, (size_t) r->hdr.length);
}
}
else if (w == hostname_message)
{
if (reason->reason == XmCR_OK)
{
CleanupAndExit(w, NOTIFY_OK);
}
else
{
CleanupAndExit(w, NOTIFY_NO_WINDOWS);
}
}
}
/***************************************************************************
*
* SetDefaultDt
*
* save the default dt widget.
**************************************************************************/
void
SetDefaultDt(Widget w)
{
default_dt = w;
}
/***************************************************************************
*
* SetDtLabelAndIcon
*
* label to display in the dt_label widget and
* the logo to display in logo_pixmap
**************************************************************************/
void
SetDtLabelAndIcon(void)
{
static XmString blanks = NULL;
int i;
char *logoFile;
char *logoName;
char *temp_p;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered SetDtLabelAndIcon ...");
#endif /* VG_TRACE */
if (NULL == blanks)
blanks = XmStringCreateLocalized(" ");
/*
* if user is logging in, set dt_label desired. No more than
* one desktop can be selected at a time ...
*/
i = 0;
XtSetArg(argt[0], XmNset, FALSE); i++;
XtSetValues(options_failsafe, argt, i);
XtSetValues(options_dtlite, argt, i);
XtSetValues(options_dt, argt, i);
if (options_last_dt != NULL)
XtSetValues(options_last_dt, argt, i);
for(i = 0; i<appInfo.altDts ; ++i)
if(alt_dts[i] != NULL)
XtSetValues(alt_dts[i], argt, i);
if (NULL != default_dt) {
i = 0;
XtSetArg(argt[i], XmNset, True); i++;
XtSetValues(default_dt, argt, i);
if(default_dt == options_last_dt)
xmstr = blanks;
else
{
i = 0;
XtSetArg(argt[i], XmNlabelString, &xmstr); i++;
XtGetValues(default_dt, argt, i);
}
i = 0;
XtSetArg(argt[i], XmNuserData, &logoFile); i++;
XtGetValues(default_dt, argt, i);
}
else {
xmstr = blanks;
logoFile = logoInfo.bitmapFile;
}
#ifdef FIX_FOR_DEFECT_CDExc19307
/*
* This code causes the Session toggle buttons to be reset
* to the default setting when the user commits a typing error.
* NOT very user friendly.
*
* As for setting the defaults after the user is done entering
* the we could do the same thing by passing in an argument. For
* now, I'm not convinced that it is required.
*/
/*
* to set the defaults after the user is done
* entering the login ..
*/
if (strcmp(userName,"\0") != 0)
strcpy(userName,"\0");
#endif
i = 0;
XtSetArg(argt[i], XmNlabelString, xmstr); i++;
XtSetValues(dt_label, argt, i);
/*
* remove trailing spaces
*/
if(strchr(logoFile,' '))
temp_p = strtok(logoFile," ");
else
temp_p = logoFile;
logoName = _DtGetIconFileName(
DefaultScreenOfDisplay(dpyinfo.dpy),
temp_p, NULL, NULL, 0);
if (logoName == NULL) {
LogError(
ReadCatalog(MC_LOG_SET,MC_LOG_NO_LOGOBIT,MC_DEF_LOG_NO_LOGOBIT),
logoFile);
logoFile = NULL;
}
i = 0;
XtSetArg(argt[i], XmNimageName, logoName); i++;
XtSetValues(logo_pixmap, argt, i);
}
/***************************************************************************
*
* _DtShowDialog
*
* display a dialog message box
***************************************************************************/
static void
_DtShowDialog( DialogType dtype, XmString msg)
{
Widget *w;
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered _DtShowDialog ...");
#endif /* VG_TRACE */
switch (dtype) {
case copyright: w = &copyright_msg; break;
case error: w = &error_message; break;
case expassword: w = &passwd_message; break;
case help: w = &help_message; break;
case hostname: w = &hostname_message; break;
case help_chooser: w = &help_message; break;
}
if (*w == NULL)
{
MakeDialog(dtype);
}
if ( msg != NULL ) {
XtSetArg(argt[0], XmNmessageString, msg );
XtSetValues(*w, argt, 1);
}
XtManageChild(*w);
XSetInputFocus(XtDisplay(*w), XtWindow(*w),
RevertToPointerRoot, CurrentTime);
}
/***************************************************************************
*
* ShowDialogCB
*
* callback to display a dialog message box
***************************************************************************/
void
ShowDialogCB( Widget w, XtPointer dialog, XtPointer call_data )
{
_DtShowDialog( (DialogType) dialog, NULL);
}
/***************************************************************************
*
* TextFocusCB
*
* set focusWidget global variable when focus changes
***************************************************************************/
void
TextFocusCB( Widget w, XtPointer client_data, XtPointer call_data )
{
if ( w == login_text )
focusWidget = w;
}
/***************************************************************************
*
* GetLoginTextPtr
*
* Return login text widget instance data
***************************************************************************/
LoginTextPtr
GetLoginTextPtr( Widget w )
{
LoginTextPtr textdata;
int i;
i = 0;
XtSetArg(argt[i], XmNuserData, &textdata ); i++;
XtGetValues(w, argt, i);
return(textdata);
}
#ifdef BLS
/***************************************************************************
*
* PromptSensitivityLevel
*
* Prompt for B1 Sensitivity Level. The password widget set is reused for
* this purpose rather than creating another complete widget set. It already
* has most of the proper size and alignment specifications needed. Using
* the password set also allows the B1 code changes to be more localized.
*
***************************************************************************/
static void
PromptSensitivityLevel( void)
{
Dimension width;
int i, width1, width2;
/*
* Use the password widget set to prompt for the B1 Sensitivity Level.
* Remember to put it back to normal if the user presses [Clear].
*/
normalPasswordWidget = False;
XtRemoveAllCallbacks(_text, XmNmodifyVerifyCallback);
XmTextFieldSetString(_text,"");
/*
* Change the label and resize the password form...
*/
i = 0;
XtSetArg(argt[i], XmNresizable, True ); i++;
XtSetArg(argt[i], XmNresizePolicy, XmRESIZE_ANY ); i++;
XtSetValues(_form, argt, i);
i = 0;
xmstr = ReadCatalogXms(MC_LABEL_SET, -1, "Sensitivity Level:");
XtSetArg(argt[i], XmNrecomputeSize, True ); i++;
XtSetArg(argt[i], XmNlabelString, xmstr ); i++;
XtSetValues(_label, argt, i);
XmStringFree(xmstr);
/*
* Center the form horizontally in the login_matte...
*
*/
CenterForm(matte1, _form);
ProcessTraversal(_text, XmTRAVERSE_CURRENT);
}
#endif /* BLS */
static void
TellRequester(char * buf, size_t nbytes)
{
#ifdef VG_TRACE
vg_TRACE_EXECUTION("main: entered TellRequester ...");
#endif /* VG_TRACE */
if(-1 == write(1, buf, nbytes)) {
perror(strerror(errno));
}
}