diff options
author | Alan Coopersmith <alan.coopersmith@sun.com> | 2006-08-14 13:48:19 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@sun.com> | 2006-08-14 13:48:19 -0700 |
commit | 3349ab7b6c2b9ff6ad39da6d29b6aa1250f96cd9 (patch) | |
tree | c5279caff128f2a2d47456e2fc9020fc3ea24a53 | |
parent | 0e47586fe5c76d7804368c4536e66ec610978e38 (diff) |
Draw text with Xft in greeter window
(Includes portions copied from Keith Packard's Xft conversion of xclock)
-rw-r--r-- | config/Xresources.cpp | 8 | ||||
-rw-r--r-- | configure.ac | 15 | ||||
-rw-r--r-- | greeter/Login.c | 466 | ||||
-rw-r--r-- | greeter/Login.h | 8 | ||||
-rw-r--r-- | greeter/LoginP.h | 22 |
5 files changed, 427 insertions, 92 deletions
diff --git a/config/Xresources.cpp b/config/Xresources.cpp index b666c58..033491c 100644 --- a/config/Xresources.cpp +++ b/config/Xresources.cpp @@ -33,11 +33,19 @@ xlogin*greetFont: -adobe-helvetica-bold-o-normal--24-240-75-75-p-138-iso8859-1 xlogin*font: -adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1 xlogin*promptFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1 xlogin*failFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1 +xlogin*greetFace: Serif-24:bold:italic +xlogin*face: Helvetica-18 +xlogin*promptFace: Helvetica-18:bold +xlogin*failFace: Helvetica-18:bold XHASHelse xlogin*greetFont: -adobe-helvetica-bold-o-normal--17-120-100-100-p-92-iso8859-1 xlogin*font: -adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1 xlogin*promptFont: -adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1 xlogin*failFont: -adobe-helvetica-bold-o-normal--14-140-75-75-p-82-iso8859-1 +xlogin*greetFace: Serif-18:bold:italic +xlogin*face: Helvetica-12 +xlogin*promptFace: Helvetica-12:bold +xlogin*failFace: Helvetica-14:bold XHASHendif #endif /* XPM */ XHASHifdef COLOR diff --git a/configure.ac b/configure.ac index 186ea2d..1150541 100644 --- a/configure.ac +++ b/configure.ac @@ -253,6 +253,21 @@ PKG_CHECK_EXISTS(xinerama, [ GREETER_LIBS="$GREETER_LIBS $XINERAMA_LIBS" ]) +# Xft text drawing for the greeter screen +AC_ARG_WITH(xft, + AC_HELP_STRING([--with-xft], + [Use Xft to draw text (default is YES if installed)]), + [USE_XFT="$withval"], + PKG_CHECK_EXISTS(xft, [USE_XFT="yes"], [USE_XFT="no"])) + +if test "x$USE_XFT" = "xyes" ; then + PKG_CHECK_MODULES(XFT, xft) + GREETER_CFLAGS="$GREETER_CFLAGS $XFT_CFLAGS" + GREETER_LIBS="$GREETER_LIBS $XFT_LIBS" + AC_DEFINE([USE_XFT], 1, + [Define to 1 to use Xft for text on greeter screen]) +fi + # XPM logos for the greeter screen AC_ARG_ENABLE(xpm-logos, AC_HELP_STRING([--enable-xpm-logos], diff --git a/greeter/Login.c b/greeter/Login.c index a9dbeb7..21fe5f9 100644 --- a/greeter/Login.c +++ b/greeter/Login.c @@ -124,6 +124,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), @@ -132,6 +133,7 @@ static XtResource resources[] = { offset(greetpixel), XtRString, XtDefaultForeground}, {XtNfailColor, XtCForeground, XtRPixel, sizeof (Pixel), offset(failpixel), XtRString, XtDefaultForeground}, +#endif #ifdef XPM /* added by Caolan McNamara */ @@ -163,14 +165,33 @@ static XtResource resources[] = { /* 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 *), @@ -209,18 +230,27 @@ 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)) @@ -239,12 +269,39 @@ static XtResource resources[] = { # 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 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)) + + #ifndef XPM -# define TEXT_PROMPT_W(w, m) (XTextWidth (w->login.promptFont,\ - m, strlen (m))) +# define TEXT_PROMPT_W(w, m) STRING_WIDTH(prompt, m) #else -# define TEXT_PROMPT_W(w, m) (XTextWidth (w->login.promptFont,\ - m, strlen (m)) + w->login.inframeswidth) +# define TEXT_PROMPT_W(w, m) (STRING_WIDTH(prompt, m) + w->login.inframeswidth) #endif /* XPM */ # define DEF_PROMPT_W(w,n) TEXT_PROMPT_W(w, w->login.prompts[n].defaultPrompt) @@ -255,25 +312,22 @@ static XtResource resources[] = { # 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)))) +# define GREET_W(w) (max (STRING_WIDTH (greet, w->login.greeting), \ + STRING_WIDTH (greet, 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) +# 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) +\ - w->login.greetFont->max_bounds.ascent + Y_INC(w)) + \ + F_ASCENT(greet) + Y_INC(w)) + \ (n * PROMPT_SPACE_Y(w))) -# define PROMPT_W(w) (w->core.width - 6 * TEXT_X_INC(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)) #ifndef XPM @@ -281,15 +335,14 @@ static XtResource resources[] = { #else # define PROMPT_SPACE_Y(w) (10 * Y_INC(w) / 5) #endif /* XPM */ -# define ERROR_X(w,m) ((int)(w->core.width - XTextWidth (w->login.failFont,\ - m, strlen (m))) / 2) +# 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) +\ - w->login.failFont->max_bounds.ascent) +# define FAIL_Y(w) (PROMPT_Y(w,1) + 2 * FAIL_Y_INC (w) + F_ASCENT(fail)) + #ifndef XPM -# define ERROR_W(w,m) (XTextWidth (w->login.failFont, m, strlen(m))) +# define ERROR_W(w,m) STRING_WIDTH (fail, m) #else -# define ERROR_W(w,m) (XTextWidth (w->login.failFont, m, strlen(m))\ +# define ERROR_W(w,m) (STRING_WIDTH (fail, m) \ + w->login.logoWidth + (2*w->login.logoPadding)) #endif /* XPM */ @@ -326,7 +379,7 @@ realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) (w->login.logoWidth + 2*(w->login.logoPadding)); #endif if (cursor > VALUE_SHOW_START(w, promptNum)) - curoff = XTextWidth (w->login.font, text, cursor); + curoff = TEXT_WIDTH (text, text, cursor); else curoff = 0; @@ -342,7 +395,7 @@ realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) int offset = max(cursor, VALUE_SHOW_START(w, promptNum)); int textlen = strlen (text + offset); - textwidth = XTextWidth (w->login.font, text + offset, textlen); + textwidth = TEXT_WIDTH (text, text + offset, textlen); if (textwidth > (width - curoff)) { /* Recalculate amount of text that can fit in field */ @@ -355,7 +408,7 @@ realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) offset++; } textlen--; - textwidth = XTextWidth (w->login.font, text + offset, textlen); + textwidth = TEXT_WIDTH (text, text + offset, textlen); } while ((textlen > 0) && (textwidth > width)); VALUE_SHOW_START(w, promptNum) = offset; @@ -365,11 +418,9 @@ realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) XFillRectangle (XtDisplay (w), XtWindow (w), w->login.bgGC, x, y - TEXT_Y_INC(w), width, height); - XDrawString (XtDisplay(w), XtWindow (w), gc, - x, y, text + offset, textlen); + DRAW_STRING(text, x, y, text + offset, textlen); } else { - XDrawString (XtDisplay(w), XtWindow (w), gc, - x + curoff, y, text + offset, textlen); + DRAW_STRING(text, x + curoff, y, text + offset, textlen); } } } @@ -408,7 +459,7 @@ realizeCursor (LoginWidget w, GC gc) x = VALUE_X (w, w->login.activePrompt); y = PROMPT_Y (w, w->login.activePrompt); - height = w->login.font->max_bounds.ascent + w->login.font->max_bounds.descent; + height = (F_ASCENT(text) + F_DESCENT(text)); width = 1; switch (PROMPT_STATE(w, w->login.activePrompt)) { @@ -417,7 +468,7 @@ realizeCursor (LoginWidget w, GC gc) return; case LOGIN_PROMPT_ECHO_ON: if (CUR_PROMPT_CURSOR(w) > 0) { - x += XTextWidth (w->login.font, + x += TEXT_WIDTH (text, VALUE_TEXT(w, w->login.activePrompt) + VALUE_SHOW_START(w, w->login.activePrompt), PROMPT_CURSOR(w, w->login.activePrompt) @@ -431,26 +482,26 @@ realizeCursor (LoginWidget w, GC gc) #ifndef XPM XFillRectangle (XtDisplay (w), XtWindow (w), gc, - x, y - w->login.font->max_bounds.ascent, width, height); + x, y - F_ASCENT(text), width, height); #else XFillRectangle (XtDisplay (w), XtWindow (w), gc, - 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); + x+2 , y - F_ASCENT(text)+height); #endif /* XPM */ @@ -485,12 +536,17 @@ realizeCursor (LoginWidget w, GC gc) static void EraseFail (LoginWidget w) { +#ifdef USE_XFT + w->login.failUp = 0; + RedrawFail(w); +#else XSetForeground (XtDisplay (w), w->login.failGC, w->core.background_pixel); RedrawFail(w); w->login.failUp = 0; XSetForeground (XtDisplay (w), w->login.failGC, - w->login.failpixel); + TEXT_COLOR(fail)); +#endif } static void @@ -542,9 +598,11 @@ RedrawFail (LoginWidget w) int y = FAIL_Y(w); int maxw = w->core.width - PAD_X(w); - if (w->login.failUp) { - Debug("RedrawFail('%s')\n", w->login.fail); - +#ifndef USE_XFT + if (w->login.failUp) +#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); @@ -575,8 +633,13 @@ RedrawFail (LoginWidget w) } while ((next != NULL) && ERROR_W(w, start) < maxw); x = ERROR_X(w, start); - XDrawString (XtDisplay (w), XtWindow (w), w->login.failGC, - x, y, start, strlen(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++; @@ -591,9 +654,13 @@ RedrawFail (LoginWidget w) LogOutOfMem("RedrawFail"); } - XDrawString (XtDisplay (w), XtWindow (w), w->login.failGC, - x, y, - w->login.fail, strlen (w->login.fail)); +#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)); } } @@ -719,20 +786,19 @@ draw_it (LoginWidget w) } #endif /* XPM */ - if (GREETING(w)[0]) - XDrawString (XtDisplay (w), XtWindow (w), w->login.greetGC, -#ifndef XPM - GREET_X(w), GREET_Y(w), + if (GREETING(w)[0]) { + int gx; + +#ifdef XPM + gx = GREET_X(w) - ((w->login.logoWidth/2) + w->login.logoPadding); #else - GREET_X(w) - - ((w->login.logoWidth/2) + w->login.logoPadding), - GREET_Y(w), -#endif /* XPM */ - GREETING(w), strlen (GREETING(w))); + gx = GREET_X(w); +#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) { - XDrawString (XtDisplay (w), XtWindow (w), w->login.promptGC, - PROMPT_X(w), PROMPT_Y(w,p), + 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); } @@ -1410,6 +1476,207 @@ InsertChar ( 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, @@ -1429,7 +1696,6 @@ static void Initialize ( #ifdef XPM int rv = 0; - XRectangle cliprect[1]; myXGCV.foreground = w->login.hipixel; myXGCV.background = w->core.background_pixel; @@ -1442,60 +1708,63 @@ static void Initialize ( 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; @@ -1617,8 +1886,6 @@ SkipXpmLoad: XtSetArg (position[1], XtNy, y); XtSetValues (XtParent (w), position, (Cardinal) 2); - - w->login.state = PROMPTING; } @@ -1635,6 +1902,14 @@ static void Realize ( XtCreateWindow( gw, (unsigned)InputOutput, (Visual *)CopyFromParent, *valueMask, attrs ); InitI18N(gw); + +#ifdef USE_XFT + w->login.draw = XftDrawCreate (XtDisplay (w), XtWindow(w), + DefaultVisual (XtDisplay (w), DefaultScreen(XtDisplay (w))), + w->core.colormap); + +#endif + #ifdef XPM cursor = XCreateFontCursor(XtDisplay(gw), XC_left_ptr); XDefineCursor(XtDisplay(gw), XtWindow(gw), cursor); @@ -1697,12 +1972,21 @@ static void Destroy (Widget gw) 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); +#endif #ifdef XPM XtReleaseGC(gw, w->login.hiGC); XtReleaseGC(gw, w->login.shdGC); @@ -1794,7 +2078,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, diff --git a/greeter/Login.h b/greeter/Login.h index 0002895..10121d9 100644 --- a/greeter/Login.h +++ b/greeter/Login.h @@ -99,6 +99,9 @@ from The Open Group. # define XtNpromptFont "promptFont" # define XtNgreetFont "greetFont" # define XtNfailFont "failFont" +# define XtNpromptFace "promptFace" +# define XtNgreetFace "greetFace" +# define XtNfailFace "failFace" # define XtNfailTimeout "failTimeout" # define XtNsessionArgument "sessionArgument" # define XtNsecureSession "secureSession" @@ -106,6 +109,11 @@ from The Open Group. # define XtNallowNullPasswd "allowNullPasswd" # define XtNallowRootLogin "allowRootLogin" +# define XtNface "face" +# define XtCFace "Face" +# define XtRXftFont "XftFont" +# define XtRXftColor "XftColor" + #ifdef XPM /* added by Amit Margalit Oct 1996 */ # define XtNhiColor "hiColor" diff --git a/greeter/LoginP.h b/greeter/LoginP.h index 0c63f89..fda41d3 100644 --- a/greeter/LoginP.h +++ b/greeter/LoginP.h @@ -70,6 +70,9 @@ from The Open Group. #ifdef XPM #include <X11/Xlib.h> #endif /* XPM */ +#ifdef USE_XFT +# include <X11/Xft/Xft.h> +#endif #define INITIALIZING 0 #define PROMPTING 1 @@ -94,10 +97,12 @@ typedef struct { /* New fields for the login widget instance record */ typedef struct { +#ifndef USE_XFT Pixel textpixel; /* foreground pixel */ Pixel promptpixel; /* prompt pixel */ Pixel greetpixel; /* greeting pixel */ Pixel failpixel; /* failure pixel */ +#endif #ifdef XPM Pixel hipixel; /* frame hilite pixel */ Pixel shdpixel; /* shadow frame pixel */ @@ -105,9 +110,11 @@ typedef struct { GC textGC; /* pointer to GraphicsContext */ GC bgGC; /* pointer to GraphicsContext */ GC xorGC; /* pointer to GraphicsContext */ +#ifndef USE_XFT GC promptGC; GC greetGC; GC failGC; +#endif #ifdef XPM GC hiGC; /* for hilight part of frame */ GC shdGC; /* for shaded part of frame */ @@ -119,10 +126,12 @@ typedef struct { char *failMsg; /* failure message */ char *fail; /* current error message */ char *passwdChangeMsg; /* message when passwd expires */ - XFontStruct *font; /* font for text */ +#ifndef USE_XFT + XFontStruct *textFont; /* font for text */ XFontStruct *promptFont; /* font for prompts */ XFontStruct *greetFont; /* font for greeting */ XFontStruct *failFont; /* font for failure message */ +#endif /* USE_XFT */ int state; /* state */ int activePrompt; /* which prompt is active */ int failUp; /* failure message displayed */ @@ -153,6 +162,17 @@ typedef struct { Boolean useShape, logoValid; Pixmap logoPixmap, logoMask; #endif /* XPM */ +#ifdef USE_XFT + XftDraw *draw; + XftFont *textFace; /* font for text */ + XftFont *promptFace; /* font for prompts */ + XftFont *greetFace; /* font for greeting */ + XftFont *failFace; /* font for failure message */ + XftColor textcolor; /* foreground color */ + XftColor promptcolor; /* prompt color */ + XftColor greetcolor; /* greeting color */ + XftColor failcolor; /* failure color */ +#endif } LoginPart; /* Full instance record declaration */ |