source: trunk/athena/etc/xdm/xdm/Login.c @ 6052

Revision 6052, 24.8 KB checked in by lwvanels, 33 years ago (diff)
Initial revision
Line 
1/*
2 * xdm - display manager daemon
3 *
4 * $XConsortium: Login.c,v 1.35 91/07/18 19:31:10 rws Exp $
5 *
6 * Copyright 1988 Massachusetts Institute of Technology
7 *
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose and without fee is hereby granted, provided
10 * that the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission.  M.I.T. makes no representations about the
15 * suitability of this software for any purpose.  It is provided "as is"
16 * without express or implied warranty.
17 *
18 * Author:  Keith Packard, MIT X Consortium
19 */
20
21/*
22 * Login.c
23 */
24
25# include <X11/IntrinsicP.h>
26# include <X11/StringDefs.h>
27# include <X11/keysym.h>
28/* # include <X11/Xfuncs.h> */
29
30# include <stdio.h>
31
32# include "LoginP.h"
33
34#define offset(field) XtOffsetOf(LoginRec, login.field)
35#define goffset(field) XtOffsetOf(WidgetRec, core.field)
36
37static XtResource resources[] = {
38    {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
39        goffset(width), XtRImmediate,   (XtPointer) 0},
40    {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
41        goffset(height), XtRImmediate,  (XtPointer) 0},
42    {XtNx, XtCX, XtRPosition, sizeof (Position),
43        goffset(x), XtRImmediate,       (XtPointer) -1},
44    {XtNy, XtCY, XtRPosition, sizeof (Position),
45        goffset(y), XtRImmediate,       (XtPointer) -1},
46    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
47        offset(textpixel), XtRString,   XtDefaultForeground},
48    {XtNpromptColor, XtCForeground, XtRPixel, sizeof(Pixel),
49        offset(promptpixel), XtRString, XtDefaultForeground},
50    {XtNgreetColor, XtCForeground, XtRPixel, sizeof(Pixel),
51        offset(greetpixel), XtRString,  XtDefaultForeground},
52    {XtNfailColor, XtCForeground, XtRPixel, sizeof (Pixel),
53        offset(failpixel), XtRString,   XtDefaultForeground},
54    {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
55        offset (font), XtRString,       "*-new century schoolbook-medium-r-normal-*-180-*"},
56    {XtNpromptFont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
57        offset (promptFont), XtRString, "*-new century schoolbook-bold-r-normal-*-180-*"},
58    {XtNgreetFont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
59        offset (greetFont), XtRString,  "*-new century schoolbook-bold-i-normal-*-240-*"},
60    {XtNfailFont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
61        offset (failFont), XtRString,   "*-new century schoolbook-bold-r-normal-*-180-*"},
62    {XtNgreeting, XtCGreeting, XtRString, sizeof (char *),
63        offset(greeting), XtRString, "X Window System"},
64    {XtNunsecureGreeting, XtCGreeting, XtRString, sizeof (char *),
65        offset(unsecure_greet), XtRString, "This is an unsecure session"},
66    {XtNnamePrompt, XtCNamePrompt, XtRString, sizeof (char *),
67        offset(namePrompt), XtRString, "Login:  "},
68    {XtNpasswdPrompt, XtCNamePrompt, XtRString, sizeof (char *),
69        offset(passwdPrompt), XtRString, "Password:  "},
70    {XtNfail, XtCFail, XtRString, sizeof (char *),
71        offset(fail), XtRString, "Login incorrect"},
72    {XtNfailTimeout, XtCFailTimeout, XtRInt, sizeof (int),
73        offset(failTimeout), XtRImmediate, (XtPointer) 10},
74    {XtNnotifyDone, XtCCallback, XtRFunction, sizeof (XtPointer),
75        offset(notify_done), XtRFunction, (XtPointer) 0},
76    {XtNsessionArgument, XtCSessionArgument, XtRString, sizeof (char *),
77        offset(sessionArg), XtRString, (XtPointer) 0 },
78    {XtNsecureSession, XtCSecureSession, XtRBoolean, sizeof (Boolean),
79        offset(secure_session), XtRImmediate, False },
80    {XtNallowAccess, XtCAllowAccess, XtRBoolean, sizeof (Boolean),
81        offset(allow_access), XtRImmediate, False }
82};
83
84#undef offset
85#undef goffset
86
87# define TEXT_X_INC(w)  ((w)->login.font->max_bounds.width)
88# define TEXT_Y_INC(w)  ((w)->login.font->max_bounds.ascent +\
89                         (w)->login.font->max_bounds.descent)
90# define PROMPT_X_INC(w)        ((w)->login.promptFont->max_bounds.width)
91# define PROMPT_Y_INC(w)        ((w)->login.promptFont->max_bounds.ascent +\
92                         (w)->login.promptFont->max_bounds.descent)
93# define GREET_X_INC(w) ((w)->login.greetFont->max_bounds.width)
94# define GREET_Y_INC(w) ((w)->login.greetFont->max_bounds.ascent +\
95                         (w)->login.greetFont->max_bounds.descent)
96# define FAIL_X_INC(w)  ((w)->login.failFont->max_bounds.width)
97# define FAIL_Y_INC(w)  ((w)->login.failFont->max_bounds.ascent +\
98                         (w)->login.failFont->max_bounds.descent)
99
100# define Y_INC(w)       max (TEXT_Y_INC(w), PROMPT_Y_INC(w))
101
102# define LOGIN_PROMPT_W(w) (XTextWidth (w->login.promptFont,\
103                                 w->login.namePrompt,\
104                                 strlen (w->login.namePrompt)))
105# define PASS_PROMPT_W(w) (XTextWidth (w->login.promptFont,\
106                                 w->login.passwdPrompt,\
107                                 strlen (w->login.passwdPrompt)))
108# define PROMPT_W(w)    (max(LOGIN_PROMPT_W(w), PASS_PROMPT_W(w)))
109# define GREETING(w)    ((w)->login.secure_session  && !(w)->login.allow_access ?\
110                                (w)->login.greeting : (w)->login.unsecure_greet)
111# define GREET_X(w)     ((int)(w->core.width - XTextWidth (w->login.greetFont,\
112                          GREETING(w), strlen (GREETING(w)))) / 2)
113# define GREET_Y(w)     (GREETING(w)[0] ? 2 * GREET_Y_INC (w) : 0)
114# define GREET_W(w)     (max (XTextWidth (w->login.greetFont,\
115                              w->login.greeting, strlen (w->login.greeting)), \
116                              XTextWidth (w->login.greetFont,\
117                              w->login.unsecure_greet, strlen (w->login.unsecure_greet))))
118# define LOGIN_X(w)     (2 * PROMPT_X_INC(w))
119# define LOGIN_Y(w)     (GREET_Y(w) + GREET_Y_INC(w) +\
120                         w->login.greetFont->max_bounds.ascent + Y_INC(w))
121# define LOGIN_W(w)     (w->core.width - 6 * TEXT_X_INC(w))
122# define LOGIN_H(w)     (3 * Y_INC(w) / 2)
123# define LOGIN_TEXT_X(w)(LOGIN_X(w) + PROMPT_W(w))
124# define PASS_X(w)      (LOGIN_X(w))
125# define PASS_Y(w)      (LOGIN_Y(w) + 8 * Y_INC(w) / 5)
126# define PASS_W(w)      (LOGIN_W(w))
127# define PASS_H(w)      (LOGIN_H(w))
128# define PASS_TEXT_X(w) (PASS_X(w) + PROMPT_W(w))
129# define FAIL_X(w)      ((int)(w->core.width - XTextWidth (w->login.failFont,\
130                                w->login.fail, strlen (w->login.fail))) / 2)
131# define FAIL_Y(w)      (PASS_Y(w) + 2 * FAIL_Y_INC (w) +\
132                        w->login.failFont->max_bounds.ascent)
133# define FAIL_W(w)      (XTextWidth (w->login.failFont,\
134                         w->login.fail, strlen (w->login.fail)))
135
136# define PAD_X(w)       (2 * (LOGIN_X(w) + max (GREET_X_INC(w), FAIL_X_INC(w))))
137
138# define PAD_Y(w)       (max (max (Y_INC(w), GREET_Y_INC(w)),\
139                             FAIL_Y_INC(w)))
140       
141static void Initialize(), Realize(), Destroy(), Redisplay();
142static Boolean SetValues();
143static void draw_it ();
144
145static void ClassInitialize();
146
147static int max (a,b) { return a > b ? a : b; }
148
149static void
150EraseName (w, cursor)
151    LoginWidget w;
152    int         cursor;
153{
154    int x;
155
156    x = LOGIN_TEXT_X (w);
157    if (cursor > 0)
158        x += XTextWidth (w->login.font, w->login.data.name, cursor);
159    XDrawString (XtDisplay(w), XtWindow (w), w->login.bgGC, x, LOGIN_Y(w),
160                w->login.data.name + cursor, strlen (w->login.data.name + cursor));
161}
162
163static void
164DrawName (w, cursor)
165    LoginWidget w;
166    int         cursor;
167{
168    int x;
169
170    x = LOGIN_TEXT_X (w);
171    if (cursor > 0)
172        x += XTextWidth (w->login.font, w->login.data.name, cursor);
173    XDrawString (XtDisplay(w), XtWindow (w), w->login.textGC, x, LOGIN_Y(w),
174                w->login.data.name + cursor, strlen (w->login.data.name + cursor));
175}
176
177static void
178realizeCursor (w, gc)
179    LoginWidget w;
180    GC          gc;
181{
182    int x, y;
183    int height, width;
184
185    switch (w->login.state) {
186    case GET_NAME:
187        x = LOGIN_TEXT_X (w);
188        y = LOGIN_Y (w);
189        height = w->login.font->max_bounds.ascent + w->login.font->max_bounds.descent;
190        width = 1;
191        if (w->login.cursor > 0)
192            x += XTextWidth (w->login.font, w->login.data.name, w->login.cursor);
193        break;
194    case GET_PASSWD:
195        x = PASS_TEXT_X (w);
196        y = PASS_Y (w);
197        height = w->login.font->max_bounds.ascent + w->login.font->max_bounds.descent;
198        width = 1;
199        break;
200    default:
201        return;
202    }
203    XFillRectangle (XtDisplay (w), XtWindow (w), gc,
204                    x, y - w->login.font->max_bounds.ascent, width, height);
205}
206
207static void
208EraseFail (w)
209    LoginWidget w;
210{
211    int x = FAIL_X(w);
212    int y = FAIL_Y(w);
213
214    XSetForeground (XtDisplay (w), w->login.failGC,
215                        w->core.background_pixel);
216    XDrawString (XtDisplay (w), XtWindow (w), w->login.failGC,
217                x, y,
218                w->login.fail, strlen (w->login.fail));
219    w->login.failUp = 0;
220    XSetForeground (XtDisplay (w), w->login.failGC,
221                        w->login.failpixel);
222}
223
224static void
225XorCursor (w)
226    LoginWidget w;
227{
228    realizeCursor (w, w->login.xorGC);
229}
230
231static void
232RemoveFail (w)
233    LoginWidget w;
234{
235    if (w->login.failUp)
236        EraseFail (w);
237}
238
239static void
240EraseCursor (w)
241    LoginWidget (w);
242{
243    realizeCursor (w, w->login.bgGC);
244}
245
246/*ARGSUSED*/
247void failTimeout (client_data, id)
248    XtPointer   client_data;
249    XtIntervalId *      id;
250{
251    LoginWidget w = (LoginWidget)client_data;
252
253    Debug ("failTimeout\n");
254    EraseFail (w);
255}
256
257DrawFail (ctx)
258    Widget      ctx;
259{
260    LoginWidget w;
261
262    w = (LoginWidget) ctx;
263    XorCursor (w);
264    ResetLogin (w);
265    XorCursor (w);
266    w->login.failUp = 1;
267    RedrawFail (w);
268    if (w->login.failTimeout > 0) {
269        Debug ("failTimeout: %d\n", w->login.failTimeout);
270        XtAppAddTimeOut(XtWidgetToApplicationContext ((Widget)w),
271                        w->login.failTimeout * 1000,
272                        failTimeout, (XtPointer) w);
273    }
274}
275
276RedrawFail (w)
277    LoginWidget w;
278{
279    int x = FAIL_X(w);
280    int y = FAIL_Y(w);
281
282    if (w->login.failUp)
283        XDrawString (XtDisplay (w), XtWindow (w), w->login.failGC,
284                    x, y,
285                    w->login.fail, strlen (w->login.fail));
286}
287
288static void
289draw_it (w)
290    LoginWidget w;
291{
292    EraseCursor (w);
293    if (GREETING(w)[0])
294            XDrawString (XtDisplay (w), XtWindow (w), w->login.greetGC,
295                        GREET_X(w), GREET_Y(w),
296                        GREETING(w), strlen (GREETING(w)));
297    XDrawString (XtDisplay (w), XtWindow (w), w->login.promptGC,
298                LOGIN_X(w), LOGIN_Y(w),
299                w->login.namePrompt, strlen (w->login.namePrompt));
300    XDrawString (XtDisplay (w), XtWindow (w), w->login.promptGC,
301                PASS_X(w), PASS_Y(w),
302                w->login.passwdPrompt, strlen (w->login.passwdPrompt));
303    RedrawFail (w);
304    DrawName (w, 0);
305    XorCursor (w);
306    /*
307     * The GrabKeyboard here is needed only because of
308     * a bug in the R3 server -- the keyboard is grabbed on
309     * the root window, and the server won't dispatch events
310     * to the focus window unless the focus window is a ancestor
311     * of the grab window.  Bug in server already found and fixed,
312     * compatibility until at least R4.
313     */
314    if (XGrabKeyboard (XtDisplay (w), XtWindow (w), False, GrabModeAsync,
315                       GrabModeAsync, CurrentTime) != GrabSuccess)
316    {
317        XSetInputFocus (XtDisplay (w), XtWindow (w),
318                        RevertToPointerRoot, CurrentTime);
319    }
320}
321
322/*ARGSUSED*/
323static void
324DeleteBackwardChar (ctxw, event, params, num_params)
325    Widget ctxw;
326    XEvent      *event;
327    String      *params;
328    Cardinal    *num_params;
329{
330    LoginWidget ctx = (LoginWidget)ctxw;
331
332    XorCursor (ctx);
333    RemoveFail (ctx);
334    if (ctx->login.cursor > 0) {
335        ctx->login.cursor--;
336        switch (ctx->login.state) {
337        case GET_NAME:
338            EraseName (ctx, ctx->login.cursor);
339            strcpy (ctx->login.data.name + ctx->login.cursor,
340                    ctx->login.data.name + ctx->login.cursor + 1);
341            DrawName (ctx, ctx->login.cursor);
342            break;
343        case GET_PASSWD:
344            strcpy (ctx->login.data.passwd + ctx->login.cursor,
345                    ctx->login.data.passwd + ctx->login.cursor + 1);
346            break;
347        }
348    }
349    XorCursor (ctx);   
350}
351
352/*ARGSUSED*/
353static void
354DeleteForwardChar (ctxw, event, params, num_params)
355    Widget      ctxw;
356    XEvent      *event;
357    String      *params;
358    Cardinal    *num_params;
359{
360    LoginWidget ctx = (LoginWidget)ctxw;
361
362    XorCursor (ctx);
363    RemoveFail (ctx);
364    switch (ctx->login.state) {
365    case GET_NAME:
366        if (ctx->login.cursor < (int)strlen (ctx->login.data.name)) {
367            EraseName (ctx, ctx->login.cursor);
368            strcpy (ctx->login.data.name + ctx->login.cursor,
369                    ctx->login.data.name + ctx->login.cursor + 1);
370            DrawName (ctx, ctx->login.cursor);
371        }
372        break;
373    case GET_PASSWD:
374        if (ctx->login.cursor < (int)strlen (ctx->login.data.passwd)) {
375            strcpy (ctx->login.data.passwd + ctx->login.cursor,
376                    ctx->login.data.passwd + ctx->login.cursor + 1);
377        }
378        break;
379    }
380    XorCursor (ctx);   
381}
382
383/*ARGSUSED*/
384static void
385MoveBackwardChar (ctxw, event, params, num_params)
386    Widget      ctxw;
387    XEvent      *event;
388    String      *params;
389    Cardinal    *num_params;
390{
391    LoginWidget ctx = (LoginWidget)ctxw;
392
393    XorCursor (ctx);
394    RemoveFail (ctx);
395    if (ctx->login.cursor > 0)
396        ctx->login.cursor--;
397    XorCursor (ctx);
398}
399
400/*ARGSUSED*/
401static void
402MoveForwardChar (ctxw, event, params, num_params)
403    Widget      ctxw;
404    XEvent      *event;
405    String      *params;
406    Cardinal    *num_params;
407{
408    LoginWidget ctx = (LoginWidget)ctxw;
409
410    XorCursor (ctx);
411    RemoveFail (ctx);
412    switch (ctx->login.state) {
413    case GET_NAME:
414        if (ctx->login.cursor < (int)strlen(ctx->login.data.name))
415            ++ctx->login.cursor;
416        break;
417    case GET_PASSWD:
418        if (ctx->login.cursor < (int)strlen(ctx->login.data.passwd))
419            ++ctx->login.cursor;
420        break;
421    }
422    XorCursor (ctx);
423}
424
425/*ARGSUSED*/
426static void
427MoveToBegining (ctxw, event, params, num_params)
428    Widget      ctxw;
429    XEvent      *event;
430    String      *params;
431    Cardinal    *num_params;
432{
433    LoginWidget ctx = (LoginWidget)ctxw;
434
435    XorCursor (ctx);
436    RemoveFail (ctx);
437    ctx->login.cursor = 0;
438    XorCursor (ctx);
439}
440
441/*ARGSUSED*/
442static void
443MoveToEnd (ctxw, event, params, num_params)
444    Widget      ctxw;
445    XEvent      *event;
446    String      *params;
447    Cardinal    *num_params;
448{
449    LoginWidget ctx = (LoginWidget)ctxw;
450
451    XorCursor (ctx);
452    RemoveFail (ctx);
453    switch (ctx->login.state) {
454    case GET_NAME:
455        ctx->login.cursor = strlen (ctx->login.data.name);
456        break;
457    case GET_PASSWD:
458        ctx->login.cursor = strlen (ctx->login.data.passwd);
459        break;
460    }
461    XorCursor (ctx);
462}
463
464/*ARGSUSED*/
465static void
466EraseToEndOfLine (ctxw, event, params, num_params)
467    Widget      ctxw;
468    XEvent      *event;
469    String      *params;
470    Cardinal    *num_params;
471{
472    LoginWidget ctx = (LoginWidget)ctxw;
473
474    XorCursor (ctx);
475    RemoveFail (ctx);
476    switch (ctx->login.state) {
477    case GET_NAME:
478        EraseName (ctx, ctx->login.cursor);
479        ctx->login.data.name[ctx->login.cursor] = '\0';
480        break;
481    case GET_PASSWD:
482        ctx->login.data.passwd[ctx->login.cursor] = '\0';
483        break;
484    }
485    XorCursor (ctx);
486}
487
488/*ARGSUSED*/
489static void
490EraseLine (ctxw, event, params, num_params)
491    Widget      ctxw;
492    XEvent      *event;
493    String      *params;
494    Cardinal    *num_params;
495{
496    MoveToBegining (ctxw, event, params, num_params);
497    EraseToEndOfLine (ctxw, event, params, num_params);
498}
499
500/*ARGSUSED*/
501static void
502FinishField (ctxw, event, params, num_params)
503    Widget      ctxw;
504    XEvent      *event;
505    String      *params;
506    Cardinal    *num_params;
507{
508    LoginWidget ctx = (LoginWidget)ctxw;
509
510    XorCursor (ctx);
511    RemoveFail (ctx);
512    switch (ctx->login.state) {
513    case GET_NAME:
514        ctx->login.state = GET_PASSWD;
515        ctx->login.cursor = 0;
516        break;
517    case GET_PASSWD:
518        ctx->login.state = DONE;
519        ctx->login.cursor = 0;
520        (*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_OK);
521        break;
522    }
523    XorCursor (ctx);
524}
525
526/*ARGSUSED*/
527static void
528AllowAccess (ctxw, event, params, num_params)
529    Widget      ctxw;
530    XEvent      *event;
531    String      *params;
532    Cardinal    *num_params;
533{
534    LoginWidget ctx = (LoginWidget)ctxw;
535    Arg arglist[1];
536    Boolean allow;
537
538    RemoveFail (ctx);
539    XtSetArg (arglist[0], XtNallowAccess, (char *) &allow);
540    XtGetValues ((Widget) ctx, arglist, 1);
541    XtSetArg (arglist[0], XtNallowAccess, !allow);
542    XtSetValues ((Widget) ctx, arglist, 1);
543}
544
545/*ARGSUSED*/
546static void
547SetSessionArgument (ctxw, event, params, num_params)
548    Widget      ctxw;
549    XEvent      *event;
550    String      *params;
551    Cardinal    *num_params;
552{
553    LoginWidget ctx = (LoginWidget)ctxw;
554
555    RemoveFail (ctx);
556    if (ctx->login.sessionArg)
557        XtFree (ctx->login.sessionArg);
558    ctx->login.sessionArg = 0;
559    if (*num_params > 0) {
560        ctx->login.sessionArg = XtMalloc (strlen (params[0]) + 1);
561        if (ctx->login.sessionArg)
562            strcpy (ctx->login.sessionArg, params[0]);
563        else
564            LogOutOfMem ("set session argument");
565    }
566}
567
568/*ARGSUSED*/
569static void
570RestartSession (ctxw, event, params, num_params)
571    Widget      ctxw;
572    XEvent      *event;
573    String      *params;
574    Cardinal    *num_params;
575{
576    LoginWidget ctx = (LoginWidget)ctxw;
577
578    XorCursor (ctx);
579    RemoveFail (ctx);
580    ctx->login.state = DONE;
581    ctx->login.cursor = 0;
582    (*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_RESTART);
583    XorCursor (ctx);
584}
585
586/*ARGSUSED*/
587static void
588AbortSession (ctxw, event, params, num_params)
589    Widget      ctxw;
590    XEvent      *event;
591    String      *params;
592    Cardinal    *num_params;
593{
594    LoginWidget ctx = (LoginWidget)ctxw;
595
596    XorCursor (ctx);
597    RemoveFail (ctx);
598    ctx->login.state = DONE;
599    ctx->login.cursor = 0;
600    (*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_ABORT);
601    XorCursor (ctx);
602}
603
604/*ARGSUSED*/
605static void
606AbortDisplay (ctxw, event, params, num_params)
607    Widget      ctxw;
608    XEvent      *event;
609    String      *params;
610    Cardinal    *num_params;
611{
612    LoginWidget ctx = (LoginWidget)ctxw;
613
614    XorCursor (ctx);
615    RemoveFail (ctx);
616    ctx->login.state = DONE;
617    ctx->login.cursor = 0;
618    (*ctx->login.notify_done) (ctx, &ctx->login.data, NOTIFY_ABORT_DISPLAY);
619    XorCursor (ctx);
620}
621
622ResetLogin (w)
623    LoginWidget w;
624{
625    EraseName (w, 0);
626    w->login.cursor = 0;
627    w->login.data.name[0] = '\0';
628    w->login.data.passwd[0] = '\0';
629    w->login.state = GET_NAME;
630}
631
632/* ARGSUSED */
633static void
634InsertChar (ctxw, event, params, num_params)
635    Widget      ctxw;
636    XEvent      *event;
637    String      *params;
638    Cardinal    *num_params;
639{
640    LoginWidget ctx = (LoginWidget)ctxw;
641
642    char strbuf[128];
643    int  len;
644
645    len = XLookupString (&event->xkey, strbuf, sizeof (strbuf), 0, 0);
646    strbuf[len] = '\0';
647    if (len + (int)strlen(ctx->login.data.name) >= NAME_LEN - 1)
648        len = NAME_LEN - strlen(ctx->login.data.name) - 2;
649    if (len == 0)
650        return;
651    XorCursor (ctx);
652    RemoveFail (ctx);
653    switch (ctx->login.state) {
654    case GET_NAME:
655        EraseName (ctx, ctx->login.cursor);
656        bcopy (ctx->login.data.name + ctx->login.cursor,
657               ctx->login.data.name + ctx->login.cursor + len,
658               strlen (ctx->login.data.name + ctx->login.cursor) + 1);
659        bcopy (strbuf, ctx->login.data.name + ctx->login.cursor, len);
660        DrawName (ctx, ctx->login.cursor);
661        ctx->login.cursor += len;
662        break;
663    case GET_PASSWD:
664        bcopy (ctx->login.data.passwd + ctx->login.cursor,
665               ctx->login.data.passwd + ctx->login.cursor + len,
666               strlen (ctx->login.data.passwd + ctx->login.cursor) + 1);
667        bcopy (strbuf, ctx->login.data.passwd + ctx->login.cursor, len);
668        ctx->login.cursor += len;
669        break;
670    }
671    XorCursor (ctx);
672}
673
674/*ARGSUSED*/
675static void FetchDisplayArg(widget, size, value)
676    Widget widget;
677    Cardinal *size;
678    XrmValue* value;
679{
680    value->size = sizeof(Display*);
681    value->addr = (caddr_t)&DisplayOfScreen(XtScreenOfObject(widget));
682}
683
684static XtConvertArgRec displayConvertArg[] = {
685    {XtProcedureArg, (XtPointer)FetchDisplayArg, 0},
686};
687
688/* ARGSUSED */
689static void Initialize (greq, gnew, args, num_args)
690    Widget greq, gnew;
691    ArgList args;
692    Cardinal *num_args;
693{
694    LoginWidget w = (LoginWidget)gnew;
695    XtGCMask    valuemask, xvaluemask;
696    XGCValues   myXGCV;
697    Arg         position[2];
698    Position    x, y;
699
700    myXGCV.foreground = w->login.textpixel;
701    myXGCV.background = w->core.background_pixel;
702    valuemask = GCForeground | GCBackground;
703    if (w->login.font) {
704        myXGCV.font = w->login.font->fid;
705        valuemask |= GCFont;
706    }
707    w->login.textGC = XtGetGC(gnew, valuemask, &myXGCV);
708    myXGCV.foreground = w->core.background_pixel;
709    w->login.bgGC = XtGetGC(gnew, valuemask, &myXGCV);
710
711    myXGCV.foreground = w->login.textpixel ^ w->core.background_pixel;
712    myXGCV.function = GXxor;
713    xvaluemask = valuemask | GCFunction;
714    w->login.xorGC = XtGetGC (gnew, xvaluemask, &myXGCV);
715
716    /*
717     * Note that the second argument is a GCid -- QueryFont accepts a GCid and
718     * returns the curently contained font.
719     */
720
721    if (w->login.font == NULL)
722        w->login.font = XQueryFont (XtDisplay (w),
723                XGContextFromGC (DefaultGCOfScreen (XtScreen (w))));
724
725    xvaluemask = valuemask;
726    if (w->login.promptFont == NULL)
727        w->login.promptFont = w->login.font;
728    else
729        xvaluemask |= GCFont;
730
731    myXGCV.foreground = w->login.promptpixel;
732    myXGCV.font = w->login.promptFont->fid;
733    w->login.promptGC = XtGetGC (gnew, xvaluemask, &myXGCV);
734
735    xvaluemask = valuemask;
736    if (w->login.greetFont == NULL)
737        w->login.greetFont = w->login.font;
738    else
739        xvaluemask |= GCFont;
740
741    myXGCV.foreground = w->login.greetpixel;
742    myXGCV.font = w->login.greetFont->fid;
743    w->login.greetGC = XtGetGC (gnew, xvaluemask, &myXGCV);
744
745    xvaluemask = valuemask;
746    if (w->login.failFont == NULL)
747        w->login.failFont = w->login.font;
748    else
749        xvaluemask |= GCFont;
750
751    myXGCV.foreground = w->login.failpixel;
752    myXGCV.font = w->login.failFont->fid;
753    w->login.failGC = XtGetGC (gnew, xvaluemask, &myXGCV);
754
755    w->login.data.name[0] = '\0';
756    w->login.data.passwd[0] = '\0';
757    w->login.state = GET_NAME;
758    w->login.cursor = 0;
759    w->login.failUp = 0;
760    if (w->core.width == 0)
761        w->core.width = max (GREET_W(w), FAIL_W(w)) + PAD_X(w);
762    if (w->core.height == 0) {
763        int fy = FAIL_Y(w);
764        int pady = PAD_Y(w);
765
766        w->core.height = fy + pady;     /* for stupid compilers */
767    }
768    if ((x = w->core.x) == -1)
769        x = (int)(WidthOfScreen (XtScreen (w)) - w->core.width) / 2;
770    if ((y = w->core.y) == -1)
771        y = (int)(HeightOfScreen (XtScreen (w)) - w->core.height) / 3;
772    XtSetArg (position[0], XtNx, x);
773    XtSetArg (position[1], XtNy, y);
774    XtSetValues (XtParent (w), position, (Cardinal) 2);
775}
776
777 
778static void Realize (gw, valueMask, attrs)
779     Widget gw;
780     XtValueMask *valueMask;
781     XSetWindowAttributes *attrs;
782{
783    XtCreateWindow( gw, (unsigned)InputOutput, (Visual *)CopyFromParent,
784                     *valueMask, attrs );
785}
786
787static void Destroy (gw)
788     Widget gw;
789{
790    LoginWidget w = (LoginWidget)gw;
791    bzero (w->login.data.name, NAME_LEN);
792    bzero (w->login.data.passwd, NAME_LEN);
793    XtReleaseGC(gw, w->login.textGC);
794    XtReleaseGC(gw, w->login.bgGC);
795    XtReleaseGC(gw, w->login.xorGC);
796    XtReleaseGC(gw, w->login.promptGC);
797    XtReleaseGC(gw, w->login.greetGC);
798    XtReleaseGC(gw, w->login.failGC);
799}
800
801/* ARGSUSED */
802static void Redisplay(gw, event, region)
803     Widget gw;
804     XEvent *event;
805     Region region;
806{
807    draw_it ((LoginWidget) gw);
808}
809
810/*ARGSUSED*/
811static Boolean SetValues (current, request, new, args, num_args)
812    Widget  current, request, new;
813    ArgList args;
814    Cardinal *num_args;
815{
816    LoginWidget currentL, newL;
817   
818    currentL = (LoginWidget) current;
819    newL = (LoginWidget) new;
820    if (GREETING (currentL) != GREETING (newL))
821        return True;
822    return False;
823}
824
825char defaultLoginTranslations [] =
826"\
827Ctrl<Key>H:     delete-previous-character() \n\
828Ctrl<Key>D:     delete-character() \n\
829Ctrl<Key>B:     move-backward-character() \n\
830Ctrl<Key>F:     move-forward-character() \n\
831Ctrl<Key>A:     move-to-begining() \n\
832Ctrl<Key>E:     move-to-end() \n\
833Ctrl<Key>K:     erase-to-end-of-line() \n\
834Ctrl<Key>U:     erase-line() \n\
835Ctrl<Key>X:     erase-line() \n\
836Ctrl<Key>C:     restart-session() \n\
837Ctrl<Key>\\\\:  abort-session() \n\
838:Ctrl<Key>plus: allow-all-access() \n\
839<Key>BackSpace: delete-previous-character() \n\
840<Key>Delete:    delete-previous-character() \n\
841<Key>Return:    finish-field() \n\
842<Key>:          insert-char() \
843";
844
845XtActionsRec loginActionsTable [] = {
846  {"delete-previous-character", DeleteBackwardChar},
847  {"delete-character",          DeleteForwardChar},
848  {"move-backward-character",   MoveBackwardChar},
849  {"move-forward-character",    MoveForwardChar},
850  {"move-to-begining",          MoveToBegining},
851  {"move-to-end",               MoveToEnd},
852  {"erase-to-end-of-line",      EraseToEndOfLine},
853  {"erase-line",                EraseLine},
854  {"finish-field",              FinishField},
855  {"abort-session",             AbortSession},
856  {"abort-display",             AbortDisplay},
857  {"restart-session",           RestartSession},
858  {"insert-char",               InsertChar},
859  {"set-session-argument",      SetSessionArgument},
860  {"allow-all-access",          AllowAccess},
861};
862
863LoginClassRec loginClassRec = {
864    { /* core fields */
865    /* superclass               */      &widgetClassRec,
866    /* class_name               */      "Login",
867    /* size                     */      sizeof(LoginRec),
868    /* class_initialize         */      NULL,
869    /* class_part_initialize    */      NULL,
870    /* class_inited             */      FALSE,
871    /* initialize               */      Initialize,
872    /* initialize_hook          */      NULL,
873    /* realize                  */      Realize,
874    /* actions                  */      loginActionsTable,
875    /* num_actions              */      XtNumber (loginActionsTable),
876    /* resources                */      resources,
877    /* num_resources            */      XtNumber(resources),
878    /* xrm_class                */      NULLQUARK,
879    /* compress_motion          */      TRUE,
880    /* compress_exposure        */      TRUE,
881    /* compress_enterleave      */      TRUE,
882    /* visible_interest         */      FALSE,
883    /* destroy                  */      Destroy,
884    /* resize                   */      NULL,
885    /* expose                   */      Redisplay,
886    /* set_values               */      SetValues,
887    /* set_values_hook          */      NULL,
888    /* set_values_almost        */      NULL,
889    /* get_values_hook          */      NULL,
890    /* accept_focus             */      NULL,
891    /* version                  */      XtVersion,
892    /* callback_private         */      NULL,
893    /* tm_table                 */      defaultLoginTranslations,
894    /* query_geometry           */      XtInheritQueryGeometry,
895    /* display_accelerator      */      XtInheritDisplayAccelerator,
896    /* extension                */      NULL
897    }
898};
899
900WidgetClass loginWidgetClass = (WidgetClass) &loginClassRec;
Note: See TracBrowser for help on using the repository browser.