summaryrefslogtreecommitdiff
path: root/app/xdm
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2008-01-01 21:26:58 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2008-01-01 21:26:58 +0000
commite1d88289ecb729e48f867e5b8f3780596102a23b (patch)
treed8866955cd2e77a0a5b7963ad94cc0a8b0917cd7 /app/xdm
parent067a5c9d101a8cde740ef123573e77ab1576ef2a (diff)
Fix the computed width of the rectangle to clear when no
error message is present and Xft is used.
Diffstat (limited to 'app/xdm')
-rw-r--r--app/xdm/greeter/Login.c1488
1 files changed, 1088 insertions, 400 deletions
diff --git a/app/xdm/greeter/Login.c b/app/xdm/greeter/Login.c
index 603bcb365..9b7562c7b 100644
--- a/app/xdm/greeter/Login.c
+++ b/app/xdm/greeter/Login.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: app/xdm/greeter/Login.c,v 1.5 2006/04/14 02:52:02 alanc Exp $ */
+/* $XdotOrg: app/xdm/greeter/Login.c,v 1.6 2006/06/03 00:05:24 alanc Exp $ */
/* $Xorg: Login.c,v 1.4 2001/02/09 02:05:41 xorgcvs Exp $ */
/*
@@ -27,6 +27,34 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
+/* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ */
+
/* $XFree86: xc/programs/xdm/greeter/Login.c,v 3.17tsi Exp $ */
/*
@@ -43,9 +71,8 @@ from The Open Group.
# include <X11/Xfuncs.h>
# include <stdio.h>
-#ifdef XPM
+# include <ctype.h>
# include <time.h>
-#endif /* XPM */
# include "dm.h"
# include "dm_error.h"
@@ -58,16 +85,32 @@ from The Open Group.
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
-#include <X11/cursorfont.h>
#endif /* XPM */
+#include <X11/cursorfont.h>
+
#ifdef USE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
+#ifndef DEBUG
+# define XDM_ASSERT(a) /* do nothing */
+#else
+# if defined(__STDC__) && __STDC_VERSION__ - 0 >= 199901L
+# define XDM_ASSERT(a) if (!(a)) { \
+ Debug("Assertion failed in %s() at file %s line %d\n", \
+ __func__, __FILE__, __LINE__); }
+# else
+# define XDM_ASSERT(a) if (!(a)) { \
+ Debug("Assertion failed at file %s line %d\n", __FILE__, __LINE__); }
+# endif
+#endif
+
static void RedrawFail (LoginWidget w);
static void ResetLogin (LoginWidget w);
static void failTimeout (XtPointer client_data, XtIntervalId * id);
+static void EraseCursor (LoginWidget w);
+static void XorCursor (LoginWidget w);
#define offset(field) XtOffsetOf(LoginRec, login.field)
#define goffset(field) XtOffsetOf(WidgetRec, core.field)
@@ -82,6 +125,7 @@ static XtResource resources[] = {
goffset(x), XtRImmediate, (XtPointer) -1},
{XtNy, XtCY, XtRPosition, sizeof (Position),
goffset(y), XtRImmediate, (XtPointer) -1},
+#ifndef USE_XFT
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
offset(textpixel), XtRString, XtDefaultForeground},
{XtNpromptColor, XtCForeground, XtRPixel, sizeof(Pixel),
@@ -90,13 +134,16 @@ static XtResource resources[] = {
offset(greetpixel), XtRString, XtDefaultForeground},
{XtNfailColor, XtCForeground, XtRPixel, sizeof (Pixel),
offset(failpixel), XtRString, XtDefaultForeground},
+#endif
-#ifdef XPM
+#ifdef DANCING
/* added by Caolan McNamara */
{XtNlastEventTime, XtCLastEventTime, XtRInt , sizeof (int),
offset(lastEventTime), XtRImmediate, (XtPointer)0},
/* end (caolan) */
+#endif /* DANCING */
+#ifdef XPM
/* added by Ivan Griffin (ivan.griffin@ul.ie) */
{XtNlogoFileName, XtCLogoFileName, XtRString, sizeof(char*),
offset(logoFileName), XtRImmediate, (XtPointer)0},
@@ -105,7 +152,7 @@ static XtResource resources[] = {
{XtNlogoPadding, XtCLogoPadding, XtRInt, sizeof(int),
offset(logoPadding), XtRImmediate, (XtPointer) 5},
/* end (ivan) */
-
+#endif /* XPM */
/* added by Amit Margalit */
{XtNhiColor, XtCForeground, XtRPixel, sizeof (Pixel),
@@ -119,16 +166,34 @@ static XtResource resources[] = {
{XtNsepWidth, XtCFrameWidth, XtRInt, sizeof(int),
offset(sepwidth), XtRImmediate, (XtPointer) 1},
/* end (amit) */
-#endif /* XPM */
+#ifndef USE_XFT
{XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
- offset (font), XtRString, "*-new century schoolbook-medium-r-normal-*-180-*"},
+ offset (textFont), XtRString, "*-new century schoolbook-medium-r-normal-*-180-*"},
{XtNpromptFont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
offset (promptFont), XtRString, "*-new century schoolbook-bold-r-normal-*-180-*"},
{XtNgreetFont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
offset (greetFont), XtRString, "*-new century schoolbook-bold-i-normal-*-240-*"},
{XtNfailFont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
offset (failFont), XtRString, "*-new century schoolbook-bold-r-normal-*-180-*"},
+#else /* USE_XFT */
+ {XtNface, XtCFace, XtRXftFont, sizeof (XftFont *),
+ offset (textFace), XtRString, "Serif-18"},
+ {XtNpromptFace, XtCFace, XtRXftFont, sizeof (XftFont *),
+ offset (promptFace), XtRString, "Serif-18:bold"},
+ {XtNgreetFace, XtCFace, XtRXftFont, sizeof (XftFont *),
+ offset (greetFace), XtRString, "Serif-24:italic"},
+ {XtNfailFace, XtCFace, XtRXftFont, sizeof (XftFont *),
+ offset (failFace), XtRString, "Serif-18:bold"},
+ {XtNforeground, XtCForeground, XtRXftColor, sizeof(XftColor),
+ offset(textcolor), XtRString, XtDefaultForeground},
+ {XtNpromptColor, XtCForeground, XtRXftColor, sizeof(XftColor),
+ offset(promptcolor), XtRString, XtDefaultForeground},
+ {XtNgreetColor, XtCForeground, XtRXftColor, sizeof(XftColor),
+ offset(greetcolor), XtRString, XtDefaultForeground},
+ {XtNfailColor, XtCForeground, XtRXftColor, sizeof (XftColor),
+ offset(failcolor), XtRString, XtDefaultForeground},
+#endif
{XtNgreeting, XtCGreeting, XtRString, sizeof (char *),
offset(greeting), XtRString, "X Window System"},
{XtNunsecureGreeting, XtCGreeting, XtRString, sizeof (char *),
@@ -138,12 +203,16 @@ static XtResource resources[] = {
{XtNpasswdPrompt, XtCPasswdPrompt, XtRString, sizeof (char *),
offset(passwdPrompt), XtRString, "Password: "},
{XtNfail, XtCFail, XtRString, sizeof (char *),
- offset(fail), XtRString,
+ offset(failMsg), XtRString,
#if defined(sun) && defined(SVR4)
- "Login incorrect or not on system console if root"},
+ "Login incorrect or not on system console if root"
#else
- "Login incorrect"},
+ "Login incorrect"
#endif
+ },
+ {XtNchangePasswdMessage, XtCChangePasswdMessage, XtRString,
+ sizeof (char *), offset(passwdChangeMsg), XtRString,
+ (XtPointer) "Password Change Required" },
{XtNfailTimeout, XtCFailTimeout, XtRInt, sizeof (int),
offset(failTimeout), XtRImmediate, (XtPointer) 10},
{XtNnotifyDone, XtCCallback, XtRFunction, sizeof (XtPointer),
@@ -151,11 +220,11 @@ static XtResource resources[] = {
{XtNsessionArgument, XtCSessionArgument, XtRString, sizeof (char *),
offset(sessionArg), XtRString, (XtPointer) 0 },
{XtNsecureSession, XtCSecureSession, XtRBoolean, sizeof (Boolean),
- offset(secure_session), XtRImmediate, False },
+ offset(secure_session), XtRImmediate, (XtPointer) False },
{XtNallowAccess, XtCAllowAccess, XtRBoolean, sizeof (Boolean),
- offset(allow_access), XtRImmediate, False },
+ offset(allow_access), XtRImmediate, (XtPointer) False },
{XtNallowNullPasswd, XtCAllowNullPasswd, XtRBoolean, sizeof (Boolean),
- offset(allow_null_passwd), XtRImmediate, False},
+ offset(allow_null_passwd), XtRImmediate, (XtPointer) False},
{XtNallowRootLogin, XtCAllowRootLogin, XtRBoolean, sizeof(Boolean),
offset(allow_root_login), XtRImmediate, (XtPointer) True}
};
@@ -163,86 +232,115 @@ static XtResource resources[] = {
#undef offset
#undef goffset
-# define TEXT_X_INC(w) ((w)->login.font->max_bounds.width)
-# define TEXT_Y_INC(w) ((w)->login.font->max_bounds.ascent +\
- (w)->login.font->max_bounds.descent)
-# define PROMPT_X_INC(w) ((w)->login.promptFont->max_bounds.width)
-# define PROMPT_Y_INC(w) ((w)->login.promptFont->max_bounds.ascent +\
- (w)->login.promptFont->max_bounds.descent)
-# define GREET_X_INC(w) ((w)->login.greetFont->max_bounds.width)
-# define GREET_Y_INC(w) ((w)->login.greetFont->max_bounds.ascent +\
- (w)->login.greetFont->max_bounds.descent)
-# define FAIL_X_INC(w) ((w)->login.failFont->max_bounds.width)
-# define FAIL_Y_INC(w) ((w)->login.failFont->max_bounds.ascent +\
- (w)->login.failFont->max_bounds.descent)
+#ifdef USE_XFT
+# define F_MAX_WIDTH(f) ((w)->login.f##Face->max_advance_width)
+# define F_ASCENT(f) ((w)->login.f##Face->ascent)
+# define F_DESCENT(f) ((w)->login.f##Face->descent)
+#else
+# define F_MAX_WIDTH(f) ((w)->login.f##Font->max_bounds.width)
+# define F_ASCENT(f) ((w)->login.f##Font->max_bounds.ascent)
+# define F_DESCENT(f) ((w)->login.f##Font->max_bounds.descent)
+#endif
+
+# define TEXT_X_INC(w) F_MAX_WIDTH(text)
+# define TEXT_Y_INC(w) (F_ASCENT(text) + F_DESCENT(text))
+
+# define PROMPT_X_INC(w) F_MAX_WIDTH(prompt)
+# define PROMPT_Y_INC(w) (F_ASCENT(prompt) + F_DESCENT(prompt))
+
+# define GREET_X_INC(w) F_MAX_WIDTH(greet)
+# define GREET_Y_INC(w) (F_ASCENT(greet) + F_DESCENT(greet))
+
+# define FAIL_X_INC(w) F_MAX_WIDTH(fail)
+# define FAIL_Y_INC(w) (F_ASCENT(fail) + F_DESCENT(fail))
# define Y_INC(w) max (TEXT_Y_INC(w), PROMPT_Y_INC(w))
-#ifndef XPM
-# define LOGIN_PROMPT_W(w) (XTextWidth (w->login.promptFont,\
- w->login.namePrompt,\
- strlen (w->login.namePrompt)))
-#else
-# define LOGIN_PROMPT_W(w) (XTextWidth (w->login.promptFont,\
- w->login.namePrompt,\
- strlen (w->login.namePrompt)) + \
- w->login.inframeswidth)
-#endif /* XPM */
-#ifndef XPM
-# define PASS_PROMPT_W(w) (XTextWidth (w->login.promptFont,\
- w->login.passwdPrompt,\
- strlen (w->login.passwdPrompt)))
+
+# define PROMPT_TEXT(w,n) ((w)->login.prompts[n].promptText)
+# define DEF_PROMPT_TEXT(w,n) ((w)->login.prompts[n].defaultPrompt)
+# define VALUE_TEXT(w,n) ((w)->login.prompts[n].valueText)
+# define VALUE_TEXT_MAX(w,n) ((w)->login.prompts[n].valueTextMax)
+# define VALUE_SHOW_START(w,n) ((w)->login.prompts[n].valueShownStart)
+# define VALUE_SHOW_END(w,n) ((w)->login.prompts[n].valueShownEnd)
+# define PROMPT_STATE(w,n) ((w)->login.prompts[n].state)
+# define PROMPT_CURSOR(w,n) ((w)->login.prompts[n].cursor)
+
+# define CUR_PROMPT_CURSOR(w) PROMPT_CURSOR(w,w->login.activePrompt)
+
+# define CUR_PROMPT_TEXT(w, n) (PROMPT_TEXT(w,n) != NULL ? \
+ PROMPT_TEXT(w,n) : DEF_PROMPT_TEXT(w,n))
+
+#ifdef USE_XFT
+
+# define TEXT_COLOR(f) (w->login.f##color.pixel)
+
+# define TEXT_WIDTH(f, m, l) XmuXftTextWidth(XtDisplay (w), \
+ w->login.f##Face, (FcChar8 *) m, l)
+static int
+XmuXftTextWidth(Display *dpy, XftFont *font, FcChar8 *string, int len);
+
+# define DRAW_STRING(f, x, y, m, l) \
+ /* Debug("DRAW_STRING(%s, %d, %d, %s, %d)\n", #f, x, y, m, l); */ \
+ XftDrawString8 (w->login.draw, &w->login.f##color, w->login.f##Face, \
+ x, y, (FcChar8 *) m, l)
+
#else
-# define PASS_PROMPT_W(w) (XTextWidth (w->login.promptFont,\
- w->login.passwdPrompt,\
- strlen (w->login.passwdPrompt)) + \
- w->login.inframeswidth)
-#endif /* XPM */
-# define PROMPT_W(w) (max(LOGIN_PROMPT_W(w), PASS_PROMPT_W(w)))
+
+# define TEXT_COLOR(f) (w->login.f##pixel)
+
+# define TEXT_WIDTH(f, m, l) (XTextWidth (w->login.f##Font, m, l))
+
+# define DRAW_STRING(f, x, y, m, l) \
+ XDrawString (XtDisplay (w), XtWindow (w), w->login.f##GC, x, y, m, l)
+
+#endif
+
+
+# define STRING_WIDTH(f, s) TEXT_WIDTH (f, s, strlen(s))
+
+
+
+# define TEXT_PROMPT_W(w, m) (STRING_WIDTH(prompt, m) + w->login.inframeswidth)
+
+# define DEF_PROMPT_W(w,n) TEXT_PROMPT_W(w, w->login.prompts[n].defaultPrompt)
+# define CUR_PROMPT_W(w,n) (max(MAX_DEF_PROMPT_W(w), PROMPT_TEXT(w,n) ? \
+ TEXT_PROMPT_W(w, PROMPT_TEXT(w,n)) : 0))
+
+# define MAX_DEF_PROMPT_W(w) (max(DEF_PROMPT_W(w,0), DEF_PROMPT_W(w,1)))
+
# define GREETING(w) ((w)->login.secure_session && !(w)->login.allow_access ?\
(w)->login.greeting : (w)->login.unsecure_greet)
-# define GREET_X(w) ((int)(w->core.width - XTextWidth (w->login.greetFont,\
- GREETING(w), strlen (GREETING(w)))) / 2)
+# define GREET_X(w) ((int)((w->core.width - \
+ STRING_WIDTH (greet, GREETING(w))) / 2))
# define GREET_Y(w) (GREETING(w)[0] ? 2 * GREET_Y_INC (w) : 0)
#ifndef XPM
-# define GREET_W(w) (max (XTextWidth (w->login.greetFont,\
- w->login.greeting, strlen (w->login.greeting)), \
- XTextWidth (w->login.greetFont,\
- w->login.unsecure_greet, strlen (w->login.unsecure_greet))))
-#else
-# define GREET_W(w) (max (XTextWidth (w->login.greetFont,\
- w->login.greeting, strlen (w->login.greeting)), \
- XTextWidth (w->login.greetFont,\
- w->login.unsecure_greet, strlen (w->login.unsecure_greet)))) + w->login.logoWidth + (2*w->login.logoPadding)
-#endif /* XPM */
-# define LOGIN_X(w) (2 * PROMPT_X_INC(w))
-# define LOGIN_Y(w) (GREET_Y(w) + GREET_Y_INC(w) +\
- w->login.greetFont->max_bounds.ascent + Y_INC(w))
-# define LOGIN_W(w) (w->core.width - 6 * TEXT_X_INC(w))
-# define LOGIN_H(w) (3 * Y_INC(w) / 2)
-# define LOGIN_TEXT_X(w)(LOGIN_X(w) + PROMPT_W(w))
-# define PASS_X(w) (LOGIN_X(w))
-#ifndef XPM
-# define PASS_Y(w) (LOGIN_Y(w) + 8 * Y_INC(w) / 5)
+# define GREET_W(w) (max (STRING_WIDTH (greet, w->login.greeting), \
+ STRING_WIDTH (greet, w->login.unsecure_greet)))
#else
-# define PASS_Y(w) (LOGIN_Y(w) + 10 * Y_INC(w) / 5)
-#endif /* XPM */
-# define PASS_W(w) (LOGIN_W(w))
-# define PASS_H(w) (LOGIN_H(w))
-# define PASS_TEXT_X(w) (PASS_X(w) + PROMPT_W(w))
-# define FAIL_X(w) ((int)(w->core.width - XTextWidth (w->login.failFont,\
- w->login.fail, strlen (w->login.fail))) / 2)
-# define FAIL_Y(w) (PASS_Y(w) + 2 * FAIL_Y_INC (w) +\
- w->login.failFont->max_bounds.ascent)
-#ifndef XPM
-# define FAIL_W(w) (XTextWidth (w->login.failFont,\
- w->login.fail, strlen (w->login.fail)))
-#else
-# define FAIL_W(w) (XTextWidth (w->login.failFont,\
- w->login.fail, strlen (w->login.fail))) + w->login.logoWidth + (2*w->login.logoPadding)
+# define GREET_W(w) (max (STRING_WIDTH (greet, w->login.greeting), \
+ STRING_WIDTH (greet, w->login.unsecure_greet)) \
+ + w->login.logoWidth + (2*w->login.logoPadding))
#endif /* XPM */
+# define PROMPT_X(w) (2 * PROMPT_X_INC(w))
+# define PROMPT_Y(w,n) ((GREET_Y(w) + GREET_Y_INC(w) +\
+ F_ASCENT(greet) + Y_INC(w)) + \
+ (n * PROMPT_SPACE_Y(w)))
+# define PROMPT_W(w) (w->core.width - (2 * TEXT_X_INC(w)))
+# define PROMPT_H(w) (3 * Y_INC(w) / 2)
+# define VALUE_X(w,n) (PROMPT_X(w) + CUR_PROMPT_W(w,n))
+# define PROMPT_SPACE_Y(w) (10 * Y_INC(w) / 5)
+
+# define ERROR_X(w,m) ((int)(w->core.width - STRING_WIDTH (fail, m)) / 2)
+# define FAIL_X(w) ERROR_X(w, w->login.fail)
+# define FAIL_Y(w) (PROMPT_Y(w,1) + 2 * FAIL_Y_INC (w) + F_ASCENT(fail))
-# define PAD_X(w) (2 * (LOGIN_X(w) + max (GREET_X_INC(w), FAIL_X_INC(w))))
+# define ERROR_W(w,m) STRING_WIDTH (fail, m)
+
+# define FAIL_W(w) max(ERROR_W(w, w->login.failMsg), \
+ ERROR_W(w, w->login.passwdChangeMsg))
+
+# define PAD_X(w) (2 * (PROMPT_X(w) + max (GREET_X_INC(w), FAIL_X_INC(w))))
# define PAD_Y(w) (max (max (Y_INC(w), GREET_Y_INC(w)),\
FAIL_Y_INC(w)))
@@ -252,33 +350,87 @@ static inline int max (int a, int b) { return a > b ? a : b; }
#endif
static void
-EraseName (LoginWidget w, int cursor)
+realizeValue (LoginWidget w, int cursor, int promptNum, GC gc)
{
- int x;
+ loginPromptState state = w->login.prompts[promptNum].state;
+ char *text = VALUE_TEXT(w, promptNum);
+ int x, y, height, width, curoff;
+
+ XDM_ASSERT(promptNum >= 0 && promptNum <= LAST_PROMPT);
+
+ x = VALUE_X (w,promptNum);
+ y = PROMPT_Y (w,promptNum);
+
+ height = PROMPT_H(w);
+ width = PROMPT_W(w) - x - 3;
+
+ height -= (w->login.inframeswidth * 2);
+ width -= (w->login.inframeswidth * 2);
+#ifdef XPM
+ width -= (w->login.logoWidth + 2*(w->login.logoPadding));
+#endif
+ if (cursor > VALUE_SHOW_START(w, promptNum))
+ curoff = TEXT_WIDTH (text, text, cursor);
+ else
+ curoff = 0;
+
- x = LOGIN_TEXT_X (w);
- if (cursor > 0)
- x += XTextWidth (w->login.font, w->login.data.name, cursor);
- XDrawString (XtDisplay(w), XtWindow (w), w->login.bgGC, x, LOGIN_Y(w),
- w->login.data.name + cursor, strlen (w->login.data.name + cursor));
+ if (gc == w->login.bgGC) {
+ if (curoff < width) {
+ XFillRectangle (XtDisplay (w), XtWindow (w), gc,
+ x + curoff, y - TEXT_Y_INC(w),
+ width - curoff, height);
+ }
+ } else if ((state == LOGIN_PROMPT_ECHO_ON) || (state == LOGIN_TEXT_INFO)) {
+ int textwidth;
+ int offset = max(cursor, VALUE_SHOW_START(w, promptNum));
+ int textlen = strlen (text + offset);
+
+ textwidth = TEXT_WIDTH (text, text + offset, textlen);
+
+ if (textwidth > (width - curoff)) {
+ /* Recalculate amount of text that can fit in field */
+ offset = VALUE_SHOW_START(w, promptNum);
+ textlen = strlen (text + offset);
+
+ while ((textlen > 0) && (textwidth > width))
+ {
+ if (offset < PROMPT_CURSOR(w, promptNum)) {
+ offset++;
+ }
+ textlen--;
+ textwidth = TEXT_WIDTH (text, text + offset, textlen);
+ }
+
+ VALUE_SHOW_START(w, promptNum) = offset;
+ VALUE_SHOW_END(w, promptNum) = offset + textlen;
+
+ /* Erase old string */
+ XFillRectangle (XtDisplay (w), XtWindow (w), w->login.bgGC,
+ x, y - TEXT_Y_INC(w), width, height);
+
+ DRAW_STRING(text, x, y, text + offset, textlen);
+ } else {
+ DRAW_STRING(text, x + curoff, y, text + offset, textlen);
+ }
+ }
}
static void
-DrawName (LoginWidget w, int cursor)
+EraseValue (LoginWidget w, int cursor, int promptNum)
{
- int x;
-
- x = LOGIN_TEXT_X (w);
- if (cursor > 0)
- x += XTextWidth (w->login.font, w->login.data.name, cursor);
- XDrawString (XtDisplay(w), XtWindow (w), w->login.textGC, x, LOGIN_Y(w),
- w->login.data.name + cursor, strlen (w->login.data.name + cursor));
+ realizeValue(w, cursor, promptNum, w->login.bgGC);
+}
-#ifdef XPM
- /*as good a place as any Caolan begin*/
- w->login.lastEventTime = time(NULL);
- /*as good a place as any Caolan end*/
-#endif /* XPM */
+static void
+DrawValue (LoginWidget w, int cursor, int promptNum)
+{
+ realizeValue(w, cursor, promptNum, w->login.textGC);
+#ifdef DANCING
+ /*as good a place as any Caolan begin*/
+ w->login.lastEventTime = time(NULL);
+ /*as good a place as any Caolan end*/
+#endif /* DANCING */
}
static void
@@ -287,62 +439,103 @@ realizeCursor (LoginWidget w, GC gc)
int x, y;
int height, width;
- switch (w->login.state) {
- case GET_NAME:
- x = LOGIN_TEXT_X (w);
- y = LOGIN_Y (w);
- height = w->login.font->max_bounds.ascent + w->login.font->max_bounds.descent;
- width = 1;
- if (w->login.cursor > 0)
- x += XTextWidth (w->login.font, w->login.data.name, w->login.cursor);
+#ifdef FORCE_CURSOR_FLASH
+ static int lastx, lasty;
+ static struct timeval lastFlash;
+ struct timeval now, timeout;
+ int sinceLastFlash;
+#endif
+
+ if (w->login.state != PROMPTING) {
+ return;
+ }
+
+ x = VALUE_X (w, w->login.activePrompt);
+ y = PROMPT_Y (w, w->login.activePrompt);
+ height = (F_ASCENT(text) + F_DESCENT(text));
+ width = 1;
+
+ switch (PROMPT_STATE(w, w->login.activePrompt)) {
+ case LOGIN_PROMPT_NOT_SHOWN:
+ case LOGIN_TEXT_INFO:
+ return;
+ case LOGIN_PROMPT_ECHO_ON:
+ if (CUR_PROMPT_CURSOR(w) > 0) {
+ x += TEXT_WIDTH (text,
+ VALUE_TEXT(w, w->login.activePrompt)
+ + VALUE_SHOW_START(w, w->login.activePrompt),
+ PROMPT_CURSOR(w, w->login.activePrompt)
+ - VALUE_SHOW_START(w, w->login.activePrompt) );
+ }
break;
- case GET_PASSWD:
- x = PASS_TEXT_X (w);
- y = PASS_Y (w);
- height = w->login.font->max_bounds.ascent + w->login.font->max_bounds.descent;
- width = 1;
+ case LOGIN_PROMPT_ECHO_OFF:
+ /* Nothing special needed */
break;
- default:
- return;
}
+
XFillRectangle (XtDisplay (w), XtWindow (w), gc,
-#ifndef XPM
- x, y - w->login.font->max_bounds.ascent, width, height);
-#else
- x, y+1 - w->login.font->max_bounds.ascent, width, height-1);
+ x, y+1 - F_ASCENT(text), width, height-1);
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x-1 , y - w->login.font->max_bounds.ascent);
+ x-1 , y - F_ASCENT(text));
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x+1 , y - w->login.font->max_bounds.ascent);
+ x+1 , y - F_ASCENT(text));
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x-1 , y - w->login.font->max_bounds.ascent+height);
+ x-1 , y - F_ASCENT(text)+height);
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x+1 , y - w->login.font->max_bounds.ascent+height);
+ x+1 , y - F_ASCENT(text)+height);
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x-2 , y - w->login.font->max_bounds.ascent);
+ x-2 , y - F_ASCENT(text));
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x+2 , y - w->login.font->max_bounds.ascent);
+ x+2 , y - F_ASCENT(text));
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x-2 , y - w->login.font->max_bounds.ascent+height);
+ x-2 , y - F_ASCENT(text)+height);
XDrawPoint (XtDisplay (w), XtWindow (w), gc,
- x+2 , y - w->login.font->max_bounds.ascent+height);
-#endif /* XPM */
+ x+2 , y - F_ASCENT(text)+height);
+
+#ifdef FORCE_CURSOR_FLASH
+ /* Force cursor to flash briefly to give user feedback */
+#define FLASH_MILLIS 100000 /* 0.10 seconds */
+#define MILLIS_PER_SEC 1000000
+ X_GETTIMEOFDAY (&now);
+
+ if ((lastx == x) && (lasty == y)) {
+ if (lastFlash.tv_sec == 0)
+ sinceLastFlash = 0;
+ else if ((lastFlash.tv_sec + 1) == now.tv_sec)
+ sinceLastFlash =
+ (now.tv_usec + MILLIS_PER_SEC) - lastFlash.tv_usec;
+ else if (lastFlash.tv_sec == now.tv_sec)
+ sinceLastFlash = now.tv_usec - lastFlash.tv_usec;
+ else
+ sinceLastFlash = (now.tv_sec - lastFlash.tv_sec) * MILLIS_PER_SEC;
+
+ if (sinceLastFlash < FLASH_MILLIS) {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = FLASH_MILLIS - sinceLastFlash;
+ select(0, NULL, NULL, NULL, &timeout);
+ }
+ } else {
+ lastx = x; lasty = y;
+ }
+ X_GETTIMEOFDAY (&lastFlash);
+#endif /* FORCE_CURSOR_FLASH */
+ XFlush (XtDisplay(w));
}
static void
EraseFail (LoginWidget w)
{
- int x = FAIL_X(w);
- int y = FAIL_Y(w);
-
+#ifdef USE_XFT
+ w->login.failUp = 0;
+ RedrawFail(w);
+#else
XSetForeground (XtDisplay (w), w->login.failGC,
w->core.background_pixel);
- XDrawString (XtDisplay (w), XtWindow (w), w->login.failGC,
- x, y,
- w->login.fail, strlen (w->login.fail));
+ RedrawFail(w);
w->login.failUp = 0;
XSetForeground (XtDisplay (w), w->login.failGC,
- w->login.failpixel);
+ TEXT_COLOR(fail));
+#endif
}
static void
@@ -370,9 +563,11 @@ static void failTimeout (XtPointer client_data, XtIntervalId * id)
LoginWidget w = (LoginWidget)client_data;
Debug ("failTimeout\n");
+ w->login.interval_id = 0;
EraseFail (w);
}
+_X_INTERNAL
void
DrawFail (Widget ctx)
{
@@ -382,14 +577,7 @@ DrawFail (Widget ctx)
XorCursor (w);
ResetLogin (w);
XorCursor (w);
- w->login.failUp = 1;
- RedrawFail (w);
- if (w->login.failTimeout > 0) {
- Debug ("failTimeout: %d\n", w->login.failTimeout);
- XtAppAddTimeOut(XtWidgetToApplicationContext ((Widget)w),
- w->login.failTimeout * 1000,
- failTimeout, (XtPointer) w);
- }
+ ErrorMessage(ctx, w->login.failMsg, True);
}
static void
@@ -397,24 +585,120 @@ RedrawFail (LoginWidget w)
{
int x = FAIL_X(w);
int y = FAIL_Y(w);
+ int maxw = w->core.width - PAD_X(w);
+#ifndef USE_XFT
if (w->login.failUp)
- XDrawString (XtDisplay (w), XtWindow (w), w->login.failGC,
- x, y,
- w->login.fail, strlen (w->login.fail));
+#endif
+ {
+ Debug("RedrawFail('%s', %d)\n", w->login.fail, w->login.failUp);
+ if (ERROR_W(w, w->login.fail) > maxw) {
+ /* Too long to fit on one line, break into multiple lines */
+ char *tempCopy = strdup(w->login.fail);
+ if (tempCopy != NULL) {
+ char *start, *next;
+ char lastspace;
+
+ y = PROMPT_Y(w,LAST_PROMPT) + (2 * PROMPT_Y_INC(w));
+
+ for (start = next = tempCopy; start != NULL ; start = next) {
+ /* search for longest string broken by whitespace that
+ will fit on a single line */
+ do {
+ if (next != start) {
+ *next = lastspace;
+ }
+ for (next = next + 1;
+ (*next != '\0') && !isspace(*next) ; next++)
+ {
+ /* this loop intentionally left blank */
+ }
+ if (*next != '\0') {
+ lastspace = *next;
+ *next = '\0';
+ } else {
+ next = NULL;
+ }
+ } while ((next != NULL) && ERROR_W(w, start) < maxw);
+
+ x = ERROR_X(w, start);
+#ifdef USE_XFT
+ if (w->login.failUp == 0) {
+ XClearArea(XtDisplay(w), XtWindow(w), x, y,
+ ERROR_W(w, start), FAIL_Y_INC(w), False);
+ } else
+#endif
+ DRAW_STRING (fail, x, y, start, strlen(start));
+
+ if (next != NULL) {
+ next++;
+ y += FAIL_Y_INC(w);
+ }
+ }
+ free(tempCopy);
+ return;
+ }
+ /* if strdup failed, fall through to draw all at once, even
+ though we know it can't all fit */
+ LogOutOfMem("RedrawFail");
+ }
+
+#ifdef USE_XFT
+ if (w->login.failUp == 0) {
+ XClearArea(XtDisplay(w), XtWindow(w), x, y,
+ ERROR_W(w, w->login.fail), FAIL_Y_INC(w), False);
+ } else
+#endif
+ DRAW_STRING (fail, x, y, w->login.fail, strlen (w->login.fail));
+ }
+}
+
+_X_INTERNAL
+void
+ErrorMessage(Widget ctx, const char *message, Bool timeout)
+{
+ LoginWidget w = (LoginWidget) ctx;
+
+/* Debug("ErrorMessage: %s\n", message); */
+ if (w->login.interval_id != 0) {
+ XtRemoveTimeOut(w->login.interval_id);
+ w->login.interval_id = 0;
+ }
+ RemoveFail(w);
+ if (w->login.fail != w->login.failMsg)
+ free(w->login.fail);
+ w->login.fail = strdup(message);
+ if (w->login.fail == NULL)
+ w->login.fail = (char *) w->login.failMsg;
+ w->login.failUp = 1;
+ RedrawFail (w);
+ if (timeout && (w->login.failTimeout > 0)) {
+ Debug ("failTimeout: %d\n", w->login.failTimeout);
+ w->login.interval_id =
+ XtAppAddTimeOut(XtWidgetToApplicationContext ((Widget)w),
+ w->login.failTimeout * 1000,
+ failTimeout, (XtPointer) w);
+ }
+}
+
+_X_INTERNAL
+void
+ShowChangePasswdMessage(Widget ctx)
+{
+ LoginWidget w = (LoginWidget) ctx;
+
+ ErrorMessage(ctx, w->login.passwdChangeMsg, False);
}
static void
draw_it (LoginWidget w)
{
-#ifdef XPM
- int i,in_frame_x,in_login_y,in_pass_y,in_width,in_height;
+ int p;
+ int i;
int gr_line_x, gr_line_y, gr_line_w;
-#endif /* XPM */
EraseCursor (w);
-#ifdef XPM
if( (w->login.outframewidth) < 1 )
w->login.outframewidth = 1;
for(i=1;i<=(w->login.outframewidth);i++)
@@ -430,11 +714,15 @@ draw_it (LoginWidget w)
}
/* make separator line */
- gr_line_x = w->login.outframewidth + w->login.logoPadding;
+ gr_line_x = w->login.outframewidth;
gr_line_y = GREET_Y(w) + GREET_Y_INC(w);
- gr_line_w = w->core.width - 2*(w->login.outframewidth) -
- (w->login.logoWidth + 3*(w->login.logoPadding));
-
+ gr_line_w = w->core.width - 2*(w->login.outframewidth);
+
+#ifdef XPM
+ gr_line_x += w->login.logoPadding;
+ gr_line_w -= w->login.logoWidth + (3 * (w->login.logoPadding));
+#endif /* XPM */
+
for(i=1;i<=(w->login.sepwidth);i++)
{
XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC,
@@ -444,71 +732,68 @@ draw_it (LoginWidget w)
gr_line_x, gr_line_y + 2*(w->login.inframeswidth) -i,
gr_line_x+gr_line_w, gr_line_y + 2*(w->login.inframeswidth) -i);
}
-
- in_frame_x = LOGIN_TEXT_X(w) - w->login.inframeswidth - 3;
- in_login_y = LOGIN_Y(w) - w->login.inframeswidth - 1 - TEXT_Y_INC(w);
- in_pass_y = PASS_Y(w) - w->login.inframeswidth - 1 - TEXT_Y_INC(w);
-
- in_width = LOGIN_W(w) - PROMPT_W(w) -
- (w->login.logoWidth + 2*(w->login.logoPadding));
- in_height = LOGIN_H(w) + w->login.inframeswidth + 2;
- for(i=1;i<=(w->login.inframeswidth);i++)
+ for (p = 0; p < NUM_PROMPTS ; p++)
{
- /* Make top/left sides */
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC,
- in_frame_x + i-1, in_login_y + i-1,
- in_frame_x + in_width-i, in_login_y + i-1);
-
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC,
- in_frame_x + i-1, in_login_y + i-1,
- in_frame_x + i-1, in_login_y + in_height-i);
+ int in_frame_x = VALUE_X(w,p) - w->login.inframeswidth - 3;
+ int in_frame_y
+ = PROMPT_Y(w,p) - w->login.inframeswidth - 1 - TEXT_Y_INC(w);
+
+ int in_width = PROMPT_W(w) - VALUE_X(w,p);
+ int in_height = PROMPT_H(w) + w->login.inframeswidth + 2;
+
+ GC topLeftGC, botRightGC;
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC,
- in_frame_x + in_width-i, in_login_y + i-1,
- in_frame_x + in_width-i, in_login_y + in_height-i);
-
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC,
- in_frame_x + i-1, in_login_y + in_height-i,
- in_frame_x + in_width-i, in_login_y + in_height-i);
+#ifdef XPM
+ in_width -= (w->login.logoWidth + 2*(w->login.logoPadding));
+#endif /* XPM */
+
+ if ((PROMPT_STATE(w, p) == LOGIN_PROMPT_ECHO_ON) ||
+ (PROMPT_STATE(w, p) == LOGIN_PROMPT_ECHO_OFF)) {
+ topLeftGC = w->login.shdGC;
+ botRightGC = w->login.hiGC;
+ } else {
+ topLeftGC = botRightGC = w->login.bgGC;
+ }
- /* Make bottom/right sides */
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC,
- in_frame_x + i-1, in_pass_y + i-1,
- in_frame_x + in_width-i, in_pass_y + i-1);
+ for (i=1; i<=(w->login.inframeswidth); i++)
+ {
+ /* Make top/left sides */
+ XDrawLine(XtDisplay (w), XtWindow (w), topLeftGC,
+ in_frame_x + i-1, in_frame_y + i-1,
+ in_frame_x + in_width-i, in_frame_y + i-1);
+
+ XDrawLine(XtDisplay (w), XtWindow (w), topLeftGC,
+ in_frame_x + i-1, in_frame_y + i-1,
+ in_frame_x + i-1, in_frame_y + in_height-i);
+
+ /* Make bottom/right sides */
+ XDrawLine(XtDisplay (w), XtWindow (w), botRightGC,
+ in_frame_x + in_width-i, in_frame_y + i-1,
+ in_frame_x + in_width-i, in_frame_y + in_height-i);
+
+ XDrawLine(XtDisplay (w), XtWindow (w), botRightGC,
+ in_frame_x + i-1, in_frame_y + in_height-i,
+ in_frame_x + in_width-i, in_frame_y + in_height-i);
+ }
+ }
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC,
- in_frame_x + i-1, in_pass_y + i-1,
- in_frame_x + i-1, in_pass_y + in_height-i);
+ if (GREETING(w)[0]) {
+ int gx = GREET_X(w);
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC,
- in_frame_x + in_width-i, in_pass_y + i-1,
- in_frame_x + in_width-i, in_pass_y + in_height-i);
-
- XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC,
- in_frame_x + i-1, in_pass_y + in_height-i,
- in_frame_x + in_width-i, in_pass_y + in_height-i);
+#ifdef XPM
+ gx -= ((w->login.logoWidth/2) + w->login.logoPadding);
+#endif
+ DRAW_STRING (greet, gx, GREET_Y(w), GREETING(w), strlen (GREETING(w)));
+ }
+ for (p = 0; p < NUM_PROMPTS ; p++) {
+ if (PROMPT_STATE(w, p) != LOGIN_PROMPT_NOT_SHOWN) {
+ DRAW_STRING (prompt, PROMPT_X(w), PROMPT_Y(w,p),
+ CUR_PROMPT_TEXT(w,p), strlen (CUR_PROMPT_TEXT(w,p)));
+ DrawValue (w, 0, p);
+ }
}
-#endif /* XPM */
-
- if (GREETING(w)[0])
- XDrawString (XtDisplay (w), XtWindow (w), w->login.greetGC,
-#ifndef XPM
- GREET_X(w), GREET_Y(w),
-#else
- GREET_X(w) -
- ((w->login.logoWidth/2) + w->login.logoPadding),
- GREET_Y(w),
-#endif /* XPM */
- GREETING(w), strlen (GREETING(w)));
- XDrawString (XtDisplay (w), XtWindow (w), w->login.promptGC,
- LOGIN_X(w), LOGIN_Y(w),
- w->login.namePrompt, strlen (w->login.namePrompt));
- XDrawString (XtDisplay (w), XtWindow (w), w->login.promptGC,
- PASS_X(w), PASS_Y(w),
- w->login.passwdPrompt, strlen (w->login.passwdPrompt));
RedrawFail (w);
- DrawName (w, 0);
XorCursor (w);
/*
* The GrabKeyboard here is needed only because of
@@ -526,28 +811,194 @@ draw_it (LoginWidget w)
}
}
+/* Returns 0 on success, -1 on failure */
+_X_INTERNAL
+int
+SetPrompt (Widget ctx, int promptNum, const char *message,
+ loginPromptState state, Boolean minimumTime)
+{
+ LoginWidget w = (LoginWidget) ctx;
+ char *prompt;
+ int messageLen, e;
+ const char *stateNames[4] = {
+ "LOGIN_PROMPT_NOT_SHOWN", "LOGIN_PROMPT_ECHO_ON",
+ "LOGIN_PROMPT_ECHO_OFF", "LOGIN_TEXT_INFO" };
+ loginPromptState priorState;
+
+ Debug("SetPrompt(%d, %s, %s(%d))\n", promptNum,
+ message ? message : "<NULL>", stateNames[state], state);
+
+ XDM_ASSERT(promptNum >= 0 && promptNum <= LAST_PROMPT);
+
+ if (PROMPT_TEXT(w, promptNum) != NULL) {
+ XtFree(PROMPT_TEXT(w, promptNum));
+ PROMPT_TEXT(w, promptNum) = NULL;
+ }
+
+ priorState = PROMPT_STATE(w, promptNum);
+ PROMPT_STATE(w, promptNum) = state;
+
+ if (state == LOGIN_PROMPT_NOT_SHOWN) {
+ return 0;
+ }
+
+ if (message == NULL) {
+ message = DEF_PROMPT_TEXT(w, promptNum);
+ }
+
+ messageLen = strlen(message);
+
+ prompt = XtMalloc(messageLen + 3);
+ if (prompt == NULL) {
+ LogOutOfMem ("SetPrompt");
+ return -1;
+ }
+
+ strncpy(prompt, message, messageLen);
+
+ /* Make sure text prompts have at least two spaces at end */
+ e = messageLen;
+
+ if (!isspace(message[messageLen - 2])) {
+ prompt[e] = ' ';
+ e++;
+ }
+ if (!isspace(message[messageLen - 1])) {
+ prompt[e] = ' ';
+ e++;
+ }
+ prompt[e] = '\0';
+
+ PROMPT_TEXT(w, promptNum) = prompt;
+
+ if (w->login.state == INITIALIZING) {
+ return 0;
+ }
+
+ if ((priorState == LOGIN_TEXT_INFO) && (w->login.msgTimeout != 0)) {
+ time_t now = time(NULL);
+ int timeleft = w->login.msgTimeout - now;
+
+ if (timeleft > 0) {
+ sleep(timeleft);
+ }
+ w->login.msgTimeout = 0;
+ }
+
+ if (state == LOGIN_TEXT_INFO) {
+ if (minimumTime) {
+ time_t now = time(NULL);
+ w->login.msgTimeout = now + w->login.failTimeout;
+ }
+ w->login.state = SHOW_MESSAGE;
+ } else {
+ w->login.activePrompt = promptNum;
+ w->login.state = PROMPTING;
+ }
+
+ PROMPT_CURSOR(w, promptNum) = 0;
+ XClearArea (XtDisplay(w), XtWindow(w), 0, 0, 0, 0, FALSE);
+ draw_it(w);
+ return 0;
+}
+
+_X_INTERNAL
+const char *
+GetPrompt(Widget ctx, int promptNum)
+{
+ LoginWidget w = (LoginWidget) ctx;
+
+ XDM_ASSERT(promptNum >= 0 && promptNum <= LAST_PROMPT);
+
+ return CUR_PROMPT_TEXT(w,promptNum);
+}
+
+_X_INTERNAL
+int
+SetValue(Widget ctx, int promptNum, char *value)
+{
+ LoginWidget w = (LoginWidget) ctx;
+
+ XDM_ASSERT(promptNum >= 0 && promptNum <= LAST_PROMPT);
+
+ if ((promptNum < 0) || (promptNum > LAST_PROMPT))
+ return -1;
+
+ XDM_ASSERT(VALUE_TEXT(w, promptNum) != NULL);
+
+ if (VALUE_TEXT(w, promptNum) == NULL)
+ return -1;
+
+ if (value == NULL) {
+ bzero(VALUE_TEXT(w, promptNum), VALUE_TEXT_MAX(w, promptNum));
+ } else {
+ strncpy(VALUE_TEXT(w, promptNum), value, VALUE_TEXT_MAX(w, promptNum));
+ VALUE_TEXT(w, promptNum)[VALUE_TEXT_MAX(w, promptNum)] = '\0';
+ }
+
+ VALUE_SHOW_START(w, promptNum) = 0;
+ VALUE_SHOW_END(w, promptNum) = 0;
+ PROMPT_CURSOR(w, promptNum) = 0;
+
+ return 0;
+}
+
+_X_INTERNAL
+const char *
+GetValue(Widget ctx, int promptNum)
+{
+ LoginWidget w = (LoginWidget) ctx;
+
+ XDM_ASSERT(promptNum >= 0 && promptNum <= LAST_PROMPT);
+
+ if ((promptNum < 0) || (promptNum > LAST_PROMPT))
+ return NULL;
+
+ XDM_ASSERT(VALUE_TEXT(w, promptNum) != NULL);
+
+ return VALUE_TEXT(w, promptNum);
+}
+
+
+static void
+realizeDeleteChar (LoginWidget ctx)
+{
+ if (ctx->login.state == PROMPTING) {
+ int promptNum = ctx->login.activePrompt;
+ int redrawFrom = PROMPT_CURSOR(ctx, promptNum);
+
+ if (PROMPT_CURSOR(ctx,promptNum) < (int)strlen(VALUE_TEXT(ctx,promptNum))) {
+ if (redrawFrom < VALUE_SHOW_START(ctx, ctx->login.activePrompt)) {
+ redrawFrom = 0;
+ EraseValue (ctx, redrawFrom, promptNum);
+ VALUE_SHOW_START(ctx, ctx->login.activePrompt)
+ = PROMPT_CURSOR(ctx,promptNum);
+ } else {
+ EraseValue (ctx, redrawFrom, promptNum);
+ }
+ strcpy(VALUE_TEXT(ctx, promptNum) + PROMPT_CURSOR(ctx, promptNum),
+ VALUE_TEXT(ctx, promptNum) + PROMPT_CURSOR(ctx, promptNum) + 1);
+ DrawValue (ctx, redrawFrom, promptNum);
+ }
+ }
+}
+
/*ARGSUSED*/
static void
DeleteBackwardChar (Widget ctxw, XEvent *event, String *params, Cardinal *num_params)
{
LoginWidget ctx = (LoginWidget)ctxw;
- XorCursor (ctx);
RemoveFail (ctx);
- if (ctx->login.cursor > 0) {
- ctx->login.cursor--;
- switch (ctx->login.state) {
- case GET_NAME:
- EraseName (ctx, ctx->login.cursor);
- strcpy (ctx->login.data.name + ctx->login.cursor,
- ctx->login.data.name + ctx->login.cursor + 1);
- DrawName (ctx, ctx->login.cursor);
- break;
- case GET_PASSWD:
- strcpy (ctx->login.data.passwd + ctx->login.cursor,
- ctx->login.data.passwd + ctx->login.cursor + 1);
- break;
- }
+
+ if (ctx->login.state != PROMPTING) {
+ return;
+ }
+
+ XorCursor (ctx);
+ if (CUR_PROMPT_CURSOR(ctx) > 0) {
+ CUR_PROMPT_CURSOR(ctx) -= 1;
+ realizeDeleteChar(ctx);
}
XorCursor (ctx);
}
@@ -558,24 +1009,14 @@ DeleteForwardChar (Widget ctxw, XEvent *event, String *params, Cardinal *num_par
{
LoginWidget ctx = (LoginWidget)ctxw;
- XorCursor (ctx);
RemoveFail (ctx);
- switch (ctx->login.state) {
- case GET_NAME:
- if (ctx->login.cursor < (int)strlen (ctx->login.data.name)) {
- EraseName (ctx, ctx->login.cursor);
- strcpy (ctx->login.data.name + ctx->login.cursor,
- ctx->login.data.name + ctx->login.cursor + 1);
- DrawName (ctx, ctx->login.cursor);
- }
- break;
- case GET_PASSWD:
- if (ctx->login.cursor < (int)strlen (ctx->login.data.passwd)) {
- strcpy (ctx->login.data.passwd + ctx->login.cursor,
- ctx->login.data.passwd + ctx->login.cursor + 1);
- }
- break;
+
+ if (ctx->login.state != PROMPTING) {
+ return;
}
+
+ XorCursor (ctx);
+ realizeDeleteChar(ctx);
XorCursor (ctx);
}
@@ -589,10 +1030,21 @@ MoveBackwardChar (
{
LoginWidget ctx = (LoginWidget)ctxw;
- XorCursor (ctx);
RemoveFail (ctx);
- if (ctx->login.cursor > 0)
- ctx->login.cursor--;
+
+ if (ctx->login.state != PROMPTING) {
+ return;
+ }
+
+ XorCursor (ctx);
+ if (CUR_PROMPT_CURSOR(ctx) > 0)
+ CUR_PROMPT_CURSOR(ctx) -= 1;
+ if (CUR_PROMPT_CURSOR(ctx) < VALUE_SHOW_START(ctx, ctx->login.activePrompt)) {
+ EraseValue(ctx, 0, ctx->login.activePrompt);
+ VALUE_SHOW_START(ctx, ctx->login.activePrompt)
+ = CUR_PROMPT_CURSOR(ctx);
+ DrawValue(ctx, 0, ctx->login.activePrompt);
+ }
XorCursor (ctx);
}
@@ -606,17 +1058,21 @@ MoveForwardChar (
{
LoginWidget ctx = (LoginWidget)ctxw;
- XorCursor (ctx);
RemoveFail (ctx);
- switch (ctx->login.state) {
- case GET_NAME:
- if (ctx->login.cursor < (int)strlen(ctx->login.data.name))
- ++ctx->login.cursor;
- break;
- case GET_PASSWD:
- if (ctx->login.cursor < (int)strlen(ctx->login.data.passwd))
- ++ctx->login.cursor;
- break;
+
+ if (ctx->login.state != PROMPTING) {
+ return;
+ }
+
+ XorCursor (ctx);
+ if (CUR_PROMPT_CURSOR(ctx) <
+ (int)strlen(VALUE_TEXT(ctx,ctx->login.activePrompt))) {
+ CUR_PROMPT_CURSOR(ctx) += 1;
+ if (VALUE_SHOW_END(ctx, ctx->login.activePrompt)
+ < CUR_PROMPT_CURSOR(ctx)) {
+ EraseValue(ctx, 0, ctx->login.activePrompt);
+ DrawValue(ctx, 0, ctx->login.activePrompt);
+ }
}
XorCursor (ctx);
}
@@ -631,9 +1087,19 @@ MoveToBegining (
{
LoginWidget ctx = (LoginWidget)ctxw;
- XorCursor (ctx);
RemoveFail (ctx);
- ctx->login.cursor = 0;
+
+ if (ctx->login.state != PROMPTING) {
+ return;
+ }
+
+ XorCursor (ctx);
+ CUR_PROMPT_CURSOR(ctx) = 0;
+ if (VALUE_SHOW_START(ctx, ctx->login.activePrompt) > 0) {
+ EraseValue(ctx, 0, ctx->login.activePrompt);
+ VALUE_SHOW_START(ctx, ctx->login.activePrompt) = 0;
+ DrawValue(ctx, 0, ctx->login.activePrompt);
+ }
XorCursor (ctx);
}
@@ -647,15 +1113,17 @@ MoveToEnd (
{
LoginWidget ctx = (LoginWidget)ctxw;
- XorCursor (ctx);
RemoveFail (ctx);
- switch (ctx->login.state) {
- case GET_NAME:
- ctx->login.cursor = strlen (ctx->login.data.name);
- break;
- case GET_PASSWD:
- ctx->login.cursor = strlen (ctx->login.data.passwd);
- break;
+
+ if (ctx->login.state != PROMPTING) {
+ return;
+ }
+
+ XorCursor (ctx);
+ CUR_PROMPT_CURSOR(ctx) = strlen (VALUE_TEXT(ctx, ctx->login.activePrompt));
+ if (VALUE_SHOW_END(ctx, ctx->login.activePrompt) < CUR_PROMPT_CURSOR(ctx)) {
+ EraseValue(ctx, 0, ctx->login.activePrompt);
+ DrawValue(ctx, 0, ctx->login.activePrompt);
}
XorCursor (ctx);
}
@@ -670,17 +1138,18 @@ EraseToEndOfLine (
{
LoginWidget ctx = (LoginWidget)ctxw;
- XorCursor (ctx);
RemoveFail (ctx);
- switch (ctx->login.state) {
- case GET_NAME:
- EraseName (ctx, ctx->login.cursor);
- bzero (ctx->login.data.name, NAME_LEN);
- break;
- case GET_PASSWD:
- bzero (ctx->login.data.passwd, PASSWORD_LEN);
- break;
+
+ if (ctx->login.state != PROMPTING) {
+ return;
}
+
+ XorCursor (ctx);
+ EraseValue (ctx, CUR_PROMPT_CURSOR(ctx), ctx->login.activePrompt);
+ bzero(VALUE_TEXT(ctx, ctx->login.activePrompt) +
+ CUR_PROMPT_CURSOR(ctx),
+ VALUE_TEXT_MAX(ctx, ctx->login.activePrompt) -
+ CUR_PROMPT_CURSOR(ctx));
XorCursor (ctx);
}
@@ -705,45 +1174,64 @@ FinishField (
Cardinal *num_params)
{
LoginWidget ctx = (LoginWidget)ctxw;
+ int promptNum = ctx->login.activePrompt;
+ int nextPrompt;
- XorCursor (ctx);
RemoveFail (ctx);
- switch (ctx->login.state) {
- case GET_NAME:
- ctx->login.state = GET_PASSWD;
- ctx->login.cursor = 0;
- break;
- case GET_PASSWD:
+
+ if (ctx->login.state != PROMPTING) {
+ return;
+ }
+
+ XorCursor (ctx);
+
+ for (nextPrompt = promptNum + 1; nextPrompt <= LAST_PROMPT; nextPrompt++) {
+ if ((PROMPT_STATE(ctx, nextPrompt) == LOGIN_PROMPT_ECHO_ON) ||
+ (PROMPT_STATE(ctx, nextPrompt) == LOGIN_PROMPT_ECHO_OFF)) {
+ ctx->login.activePrompt = nextPrompt;
+ break;
+ }
+ }
+ if (nextPrompt > LAST_PROMPT) {
ctx->login.state = DONE;
- ctx->login.cursor = 0;
(*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_OK);
- break;
+ Debug("FinishField #%d: now DONE\n", promptNum);
+ } else {
+ Debug("FinishField #%d: %d next\n", promptNum, nextPrompt);
}
+
XorCursor (ctx);
}
-#ifdef XPM
/*ARGSUSED*/
static void
TabField(Widget ctxw, XEvent *event, String *params, Cardinal *num_params)
{
LoginWidget ctx = (LoginWidget)ctxw;
+ int promptNum = ctx->login.activePrompt;
+ int nextPrompt;
- XorCursor (ctx);
RemoveFail (ctx);
- switch (ctx->login.state) {
- case GET_NAME:
- ctx->login.state = GET_PASSWD;
- ctx->login.cursor = 0;
- break;
- case GET_PASSWD:
- ctx->login.state = GET_NAME;
- ctx->login.cursor = 0;
- break;
+
+ if (ctx->login.state != PROMPTING) {
+ return;
+ }
+
+ XorCursor (ctx);
+
+ for (nextPrompt = promptNum + 1; nextPrompt != promptNum; nextPrompt++) {
+ if (nextPrompt > LAST_PROMPT) {
+ nextPrompt = 0;
+ }
+
+ if ((PROMPT_STATE(ctx, nextPrompt) == LOGIN_PROMPT_ECHO_ON) ||
+ (PROMPT_STATE(ctx, nextPrompt) == LOGIN_PROMPT_ECHO_OFF)) {
+ ctx->login.activePrompt = nextPrompt;
+ break;
+ }
}
XorCursor (ctx);
}
-#endif /* XPM */
/*ARGSUSED*/
static void
@@ -777,7 +1265,7 @@ SetSessionArgument (
RemoveFail (ctx);
if (ctx->login.sessionArg)
XtFree (ctx->login.sessionArg);
- ctx->login.sessionArg = 0;
+ ctx->login.sessionArg = NULL;
if (*num_params > 0) {
ctx->login.sessionArg = XtMalloc (strlen (params[0]) + 1);
if (ctx->login.sessionArg)
@@ -800,7 +1288,6 @@ RestartSession (
XorCursor (ctx);
RemoveFail (ctx);
ctx->login.state = DONE;
- ctx->login.cursor = 0;
(*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_RESTART);
XorCursor (ctx);
}
@@ -818,7 +1305,6 @@ AbortSession (
XorCursor (ctx);
RemoveFail (ctx);
ctx->login.state = DONE;
- ctx->login.cursor = 0;
(*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_ABORT);
XorCursor (ctx);
}
@@ -836,7 +1322,6 @@ AbortDisplay (
XorCursor (ctx);
RemoveFail (ctx);
ctx->login.state = DONE;
- ctx->login.cursor = 0;
(*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_ABORT_DISPLAY);
XorCursor (ctx);
}
@@ -844,11 +1329,16 @@ AbortDisplay (
static void
ResetLogin (LoginWidget w)
{
- EraseName (w, 0);
- w->login.cursor = 0;
- bzero (w->login.data.name, NAME_LEN);
- bzero (w->login.data.passwd, PASSWORD_LEN);
- w->login.state = GET_NAME;
+ int i;
+
+ for (i = 0; i < NUM_PROMPTS ; i++) {
+ EraseValue(w, 0, i);
+ bzero(VALUE_TEXT(w, i), VALUE_TEXT_MAX(w, i));
+ VALUE_SHOW_START(w, i) = 0;
+ PROMPT_CURSOR(w, i) = 0;
+ }
+ w->login.state = PROMPTING;
+ w->login.activePrompt = 0;
}
static void
@@ -891,11 +1381,7 @@ InsertChar (
LoginWidget ctx = (LoginWidget)ctxw;
char strbuf[128];
-#ifndef XPM
- int len;
-#else
- int len,pixels;
-#endif /* XPM */
+ int len, promptNum = ctx->login.activePrompt;
KeySym keysym = 0;
if (ctx->login.xic) {
@@ -909,14 +1395,6 @@ InsertChar (
}
strbuf[len] = '\0';
-#ifdef XPM
- pixels = 3 + ctx->login.font->max_bounds.width * len +
- XTextWidth(ctx->login.font,
- ctx->login.data.name,
- strlen(ctx->login.data.name));
- /* pixels to be added */
-#endif /* XPM */
-
/*
* Note: You can override this default key handling
* by the settings in the translation table
@@ -963,56 +1441,232 @@ InsertChar (
break;
}
- switch (ctx->login.state) {
- case GET_NAME:
-#ifndef XPM
- if (len + (int)strlen(ctx->login.data.name) >= NAME_LEN - 1)
-#else
- if (
- (len + (int)strlen(ctx->login.data.name) >= NAME_LEN - 1)/* &&
- (pixels <= LOGIN_W(ctx) - PROMPT_W(ctx))*/
- )
-#endif /* XPM */
- len = NAME_LEN - strlen(ctx->login.data.name) - 2;
- case GET_PASSWD:
- if (len + (int)strlen(ctx->login.data.passwd) >= PASSWORD_LEN - 1)
- len = PASSWORD_LEN - strlen(ctx->login.data.passwd) - 2;
+ if (ctx->login.state == PROMPTING) {
+ if ((len + (int)strlen(VALUE_TEXT(ctx, promptNum)) >=
+ (VALUE_TEXT_MAX(ctx,promptNum) - 1))) {
+ len = VALUE_TEXT_MAX(ctx,promptNum) -
+ strlen(VALUE_TEXT(ctx, promptNum)) - 2;
+ }
}
-#ifndef XPM
- if (len == 0)
-#else
- if (len == 0 || pixels >= LOGIN_W(ctx) - PROMPT_W(ctx))
-#endif /* XPM */
- return;
- XorCursor (ctx);
+ EraseCursor (ctx);
RemoveFail (ctx);
- switch (ctx->login.state) {
- case GET_NAME:
- EraseName (ctx, ctx->login.cursor);
- memmove( ctx->login.data.name + ctx->login.cursor + len,
- ctx->login.data.name + ctx->login.cursor,
- strlen (ctx->login.data.name + ctx->login.cursor) + 1);
- memmove( ctx->login.data.name + ctx->login.cursor, strbuf, len);
- DrawName (ctx, ctx->login.cursor);
- ctx->login.cursor += len;
- break;
- case GET_PASSWD:
- memmove( ctx->login.data.passwd + ctx->login.cursor + len,
- ctx->login.data.passwd + ctx->login.cursor,
- strlen (ctx->login.data.passwd + ctx->login.cursor) + 1);
- memmove( ctx->login.data.passwd + ctx->login.cursor, strbuf, len);
- ctx->login.cursor += len;
-
-#ifdef XPM
- /*as good a place as any Caolan begin*/
- ctx->login.lastEventTime = time(NULL);
- /*as good a place as any Caolan end*/
-#endif /* XPM */
- break;
+ if (len != 0)
+ {
+ if (ctx->login.state == PROMPTING) {
+ EraseValue (ctx, PROMPT_CURSOR(ctx, promptNum), promptNum);
+ memmove(VALUE_TEXT(ctx, promptNum) + PROMPT_CURSOR(ctx, promptNum) + len,
+ VALUE_TEXT(ctx, promptNum) + PROMPT_CURSOR(ctx, promptNum),
+ strlen (VALUE_TEXT(ctx, promptNum) + PROMPT_CURSOR(ctx, promptNum))+1);
+ memmove(VALUE_TEXT(ctx, promptNum) + PROMPT_CURSOR(ctx, promptNum),
+ strbuf, len);
+ DrawValue (ctx, PROMPT_CURSOR(ctx, promptNum), promptNum);
+ PROMPT_CURSOR(ctx, promptNum) += len;
+ }
}
XorCursor (ctx);
}
+
+/**** Copied from xclock.c - original author: Keith Packard ****/
+#ifdef USE_XFT
+static XtConvertArgRec xftColorConvertArgs[] = {
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
+ sizeof(Screen *)},
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
+ sizeof(Colormap)}
+};
+
+#define donestr(type, value, tstr) \
+ { \
+ if (toVal->addr != NULL) { \
+ if (toVal->size < sizeof(type)) { \
+ toVal->size = sizeof(type); \
+ XtDisplayStringConversionWarning(dpy, \
+ (char*) fromVal->addr, tstr); \
+ return False; \
+ } \
+ *(type*)(toVal->addr) = (value); \
+ } \
+ else { \
+ static type static_val; \
+ static_val = (value); \
+ toVal->addr = (XPointer)&static_val; \
+ } \
+ toVal->size = sizeof(type); \
+ return True; \
+ }
+
+static void
+XmuFreeXftColor (XtAppContext app, XrmValuePtr toVal, XtPointer closure,
+ XrmValuePtr args, Cardinal *num_args)
+{
+ Screen *screen;
+ Colormap colormap;
+ XftColor *color;
+
+ if (*num_args != 2)
+ {
+ XtAppErrorMsg (app,
+ "freeXftColor", "wrongParameters",
+ "XtToolkitError",
+ "Freeing an XftColor requires screen and colormap arguments",
+ (String *) NULL, (Cardinal *)NULL);
+ return;
+ }
+
+ screen = *((Screen **) args[0].addr);
+ colormap = *((Colormap *) args[1].addr);
+ color = (XftColor *) toVal->addr;
+ XftColorFree (DisplayOfScreen (screen),
+ DefaultVisual (DisplayOfScreen (screen),
+ XScreenNumberOfScreen (screen)),
+ colormap, color);
+}
+
+static Boolean
+XmuCvtStringToXftColor(Display *dpy,
+ XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ char *spec;
+ XRenderColor renderColor;
+ XftColor xftColor;
+ Screen *screen;
+ Colormap colormap;
+
+ if (*num_args != 2)
+ {
+ XtAppErrorMsg (XtDisplayToApplicationContext (dpy),
+ "cvtStringToXftColor", "wrongParameters",
+ "XtToolkitError",
+ "String to render color conversion needs screen and colormap arguments",
+ (String *) NULL, (Cardinal *)NULL);
+ return False;
+ }
+
+ screen = *((Screen **) args[0].addr);
+ colormap = *((Colormap *) args[1].addr);
+
+ spec = (char *) fromVal->addr;
+ if (strcasecmp (spec, XtDefaultForeground) == 0)
+ {
+ renderColor.red = 0;
+ renderColor.green = 0;
+ renderColor.blue = 0;
+ renderColor.alpha = 0xffff;
+ }
+ else if (strcasecmp (spec, XtDefaultBackground) == 0)
+ {
+ renderColor.red = 0xffff;
+ renderColor.green = 0xffff;
+ renderColor.blue = 0xffff;
+ renderColor.alpha = 0xffff;
+ }
+ else if (!XRenderParseColor (dpy, spec, &renderColor))
+ return False;
+ if (!XftColorAllocValue (dpy,
+ DefaultVisual (dpy,
+ XScreenNumberOfScreen (screen)),
+ colormap,
+ &renderColor,
+ &xftColor))
+ return False;
+
+ donestr (XftColor, xftColor, XtRXftColor);
+}
+
+static void
+XmuFreeXftFont (XtAppContext app, XrmValuePtr toVal, XtPointer closure,
+ XrmValuePtr args, Cardinal *num_args)
+{
+ Screen *screen;
+ XftFont *font;
+
+ if (*num_args != 1)
+ {
+ XtAppErrorMsg (app,
+ "freeXftFont", "wrongParameters",
+ "XtToolkitError",
+ "Freeing an XftFont requires screen argument",
+ (String *) NULL, (Cardinal *)NULL);
+ return;
+ }
+
+ screen = *((Screen **) args[0].addr);
+ font = *((XftFont **) toVal->addr);
+ if (font)
+ XftFontClose (DisplayOfScreen (screen), font);
+}
+
+static Boolean
+XmuCvtStringToXftFont(Display *dpy,
+ XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ char *name;
+ XftFont *font;
+ Screen *screen;
+
+ if (*num_args != 1)
+ {
+ XtAppErrorMsg (XtDisplayToApplicationContext (dpy),
+ "cvtStringToXftFont", "wrongParameters",
+ "XtToolkitError",
+ "String to XftFont conversion needs screen argument",
+ (String *) NULL, (Cardinal *)NULL);
+ return False;
+ }
+
+ screen = *((Screen **) args[0].addr);
+ name = (char *) fromVal->addr;
+
+ font = XftFontOpenName (dpy,
+ XScreenNumberOfScreen (screen),
+ name);
+ if (font)
+ {
+ donestr (XftFont *, font, XtRXftFont);
+ }
+ XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRXftFont);
+ return False;
+}
+
+static XtConvertArgRec xftFontConvertArgs[] = {
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
+ sizeof(Screen *)},
+};
+
+
+static int
+XmuXftTextWidth(Display *dpy, XftFont *font, FcChar8 *string, int len)
+{
+ XGlyphInfo extents;
+
+ XftTextExtents8 (dpy, font, string, len, &extents);
+
+ return extents.xOff;
+}
+
+#endif /* USE_XFT */
+
+static void
+ClassInitialize(void)
+{
+#ifdef USE_XFT
+ XtSetTypeConverter (XtRString, XtRXftColor,
+ XmuCvtStringToXftColor,
+ xftColorConvertArgs, XtNumber(xftColorConvertArgs),
+ XtCacheByDisplay, XmuFreeXftColor);
+ XtSetTypeConverter (XtRString, XtRXftFont,
+ XmuCvtStringToXftFont,
+ xftFontConvertArgs, XtNumber(xftFontConvertArgs),
+ XtCacheByDisplay, XmuFreeXftFont);
+#endif /* USE_XFT */
+}
+/**** End of portion borrowed from xclock ****/
+
/* ARGSUSED */
static void Initialize (
Widget greq,
@@ -1029,8 +1683,6 @@ static void Initialize (
XineramaScreenInfo *screens;
int s_num;
#endif
-
-#ifdef XPM
int rv = 0;
myXGCV.foreground = w->login.hipixel;
@@ -1042,62 +1694,64 @@ static void Initialize (
myXGCV.background = w->core.background_pixel;
valuemask = GCForeground | GCBackground;
w->login.shdGC = XtGetGC(gnew, valuemask, &myXGCV);
-#endif /* XPM */
- myXGCV.foreground = w->login.textpixel;
+ myXGCV.foreground = TEXT_COLOR(text);
myXGCV.background = w->core.background_pixel;
valuemask = GCForeground | GCBackground;
- if (w->login.font) {
- myXGCV.font = w->login.font->fid;
+#ifndef USE_XFT
+ if (w->login.textFont) {
+ myXGCV.font = w->login.textFont->fid;
valuemask |= GCFont;
}
+#endif
w->login.textGC = XtGetGC(gnew, valuemask, &myXGCV);
myXGCV.foreground = w->core.background_pixel;
w->login.bgGC = XtGetGC(gnew, valuemask, &myXGCV);
- myXGCV.foreground = w->login.textpixel ^ w->core.background_pixel;
+ myXGCV.foreground = TEXT_COLOR(text) ^ w->core.background_pixel;
myXGCV.function = GXxor;
xvaluemask = valuemask | GCFunction;
w->login.xorGC = XtGetGC (gnew, xvaluemask, &myXGCV);
+#ifndef USE_XFT
/*
* Note that the second argument is a GCid -- QueryFont accepts a GCid and
* returns the curently contained font.
*/
- if (w->login.font == NULL)
- w->login.font = XQueryFont (XtDisplay (w),
+ if (w->login.textFont == NULL)
+ w->login.textFont = XQueryFont (XtDisplay (w),
XGContextFromGC (XDefaultGCOfScreen (XtScreen (w))));
xvaluemask = valuemask;
if (w->login.promptFont == NULL)
- w->login.promptFont = w->login.font;
+ w->login.promptFont = w->login.textFont;
else
xvaluemask |= GCFont;
- myXGCV.foreground = w->login.promptpixel;
+ myXGCV.foreground = TEXT_COLOR(prompt);
myXGCV.font = w->login.promptFont->fid;
w->login.promptGC = XtGetGC (gnew, xvaluemask, &myXGCV);
xvaluemask = valuemask;
if (w->login.greetFont == NULL)
- w->login.greetFont = w->login.font;
+ w->login.greetFont = w->login.textFont;
else
xvaluemask |= GCFont;
- myXGCV.foreground = w->login.greetpixel;
+ myXGCV.foreground = TEXT_COLOR(greet);
myXGCV.font = w->login.greetFont->fid;
w->login.greetGC = XtGetGC (gnew, xvaluemask, &myXGCV);
xvaluemask = valuemask;
if (w->login.failFont == NULL)
- w->login.failFont = w->login.font;
+ w->login.failFont = w->login.textFont;
else
xvaluemask |= GCFont;
-
- myXGCV.foreground = w->login.failpixel;
+ myXGCV.foreground = TEXT_COLOR(fail);
myXGCV.font = w->login.failFont->fid;
w->login.failGC = XtGetGC (gnew, xvaluemask, &myXGCV);
+#endif /* USE_XFT */
#ifdef XPM
w->login.logoValid = False;
@@ -1155,11 +1809,29 @@ static void Initialize (
SkipXpmLoad:
#endif /* XPM */
- bzero (w->login.data.name, NAME_LEN);
- bzero (w->login.data.passwd, PASSWORD_LEN);
- w->login.state = GET_NAME;
- w->login.cursor = 0;
+ w->login.data.name[0] = '\0';
+ w->login.data.passwd[0] = '\0';
+ w->login.state = INITIALIZING;
+ w->login.activePrompt = LOGIN_PROMPT_USERNAME;
w->login.failUp = 0;
+ w->login.fail = (char *) w->login.failMsg;
+
+ /* Set prompt defaults */
+ PROMPT_TEXT(w, LOGIN_PROMPT_USERNAME) = NULL;
+ DEF_PROMPT_TEXT(w, LOGIN_PROMPT_USERNAME) = w->login.namePrompt;
+ VALUE_TEXT(w, LOGIN_PROMPT_USERNAME) = w->login.data.name;
+ VALUE_TEXT_MAX(w, LOGIN_PROMPT_USERNAME) = sizeof(w->login.data.name);
+ VALUE_SHOW_START(w, LOGIN_PROMPT_USERNAME) = 0;
+
+ PROMPT_TEXT(w, LOGIN_PROMPT_PASSWORD) = NULL;
+ DEF_PROMPT_TEXT(w, LOGIN_PROMPT_PASSWORD) = w->login.passwdPrompt;
+ VALUE_TEXT(w, LOGIN_PROMPT_PASSWORD) = w->login.data.passwd;
+ VALUE_TEXT_MAX(w, LOGIN_PROMPT_PASSWORD) = sizeof(w->login.data.passwd);
+ VALUE_SHOW_START(w, LOGIN_PROMPT_PASSWORD) = 0;
+
+ SetPrompt(gnew, LOGIN_PROMPT_PASSWORD, NULL, LOGIN_PROMPT_ECHO_OFF, False);
+ SetPrompt(gnew, LOGIN_PROMPT_USERNAME, NULL, LOGIN_PROMPT_ECHO_ON, False);
+
if (w->core.width == 0)
w->core.width = max (GREET_W(w), FAIL_W(w)) + PAD_X(w);
if (w->core.height == 0) {
@@ -1200,6 +1872,8 @@ SkipXpmLoad:
XtSetArg (position[0], XtNx, x);
XtSetArg (position[1], XtNy, y);
XtSetValues (XtParent (w), position, (Cardinal) 2);
+
+ w->login.state = PROMPTING;
}
@@ -1208,17 +1882,24 @@ static void Realize (
XtValueMask *valueMask,
XSetWindowAttributes *attrs)
{
-#ifdef XPM
LoginWidget w = (LoginWidget) gw;
Cursor cursor;
-#endif /* XPM */
+
XtCreateWindow( gw, (unsigned)InputOutput, (Visual *)CopyFromParent,
*valueMask, attrs );
InitI18N(gw);
-#ifdef XPM
+
+#ifdef USE_XFT
+ w->login.draw = XftDrawCreate (XtDisplay (w), XtWindow(w),
+ DefaultVisual (XtDisplay (w), DefaultScreen(XtDisplay (w))),
+ w->core.colormap);
+
+#endif
+
cursor = XCreateFontCursor(XtDisplay(gw), XC_left_ptr);
- XDefineCursor(XtDisplay(gw), XtWindow(gw), cursor);
+ XDefineCursor(XtDisplay(gw), DefaultRootWindow(XtDisplay(gw)), cursor);
+#ifdef XPM
/*
* Check if Pixmap was valid
*/
@@ -1271,16 +1952,31 @@ static void Destroy (Widget gw)
LoginWidget w = (LoginWidget)gw;
bzero (w->login.data.name, NAME_LEN);
bzero (w->login.data.passwd, PASSWORD_LEN);
+
+ if (PROMPT_TEXT(w,0) != NULL)
+ XtFree(PROMPT_TEXT(w,0));
+ if (PROMPT_TEXT(w,1) != NULL)
+ XtFree(PROMPT_TEXT(w,1));
+
+#ifdef USE_XFT
+ if (w->login.draw) {
+ XftDrawDestroy(w->login.draw);
+ w->login.draw = NULL;
+ }
+#endif
+
XtReleaseGC(gw, w->login.textGC);
XtReleaseGC(gw, w->login.bgGC);
XtReleaseGC(gw, w->login.xorGC);
+#ifndef USE_XFT
XtReleaseGC(gw, w->login.promptGC);
XtReleaseGC(gw, w->login.greetGC);
XtReleaseGC(gw, w->login.failGC);
-#ifdef XPM
+#endif
XtReleaseGC(gw, w->login.hiGC);
XtReleaseGC(gw, w->login.shdGC);
+#ifdef XPM
if (True == w->login.logoValid)
{
if (w->login.logoPixmap != 0)
@@ -1318,6 +2014,7 @@ static Boolean SetValues (
return False;
}
+static
char defaultLoginTranslations [] =
"Ctrl<Key>H: delete-previous-character() \n"
"Ctrl<Key>D: delete-character() \n"
@@ -1338,14 +2035,11 @@ char defaultLoginTranslations [] =
"<Key>Delete: delete-previous-character() \n"
#endif
"<Key>Return: finish-field() \n"
-#ifndef XPM
-"<KeyPress>: insert-char()"
-#else
"<Key>Tab: tab-field() \n"
"<KeyPress>: insert-char()"
-#endif /* XPM */
;
+static
XtActionsRec loginActionsTable [] = {
{"delete-previous-character", DeleteBackwardChar},
{"delete-character", DeleteForwardChar},
@@ -1356,9 +2050,7 @@ XtActionsRec loginActionsTable [] = {
{"erase-to-end-of-line", EraseToEndOfLine},
{"erase-line", EraseLine},
{"finish-field", FinishField},
-#ifdef XPM
{"tab-field", TabField},
-#endif /* XPM */
{"abort-session", AbortSession},
{"abort-display", AbortDisplay},
{"restart-session", RestartSession},
@@ -1372,7 +2064,7 @@ LoginClassRec loginClassRec = {
/* superclass */ &widgetClassRec,
/* class_name */ "Login",
/* size */ sizeof(LoginRec),
- /* class_initialize */ NULL,
+ /* class_initialize */ ClassInitialize,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ Initialize,
@@ -1392,11 +2084,7 @@ LoginClassRec loginClassRec = {
/* expose */ Redisplay,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
-#ifndef XPM
- /* set_values_almost */ NULL,
-#else
/* set_values_almost */ XtInheritSetValuesAlmost,
-#endif /* XPM */
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,