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 | |
---|
37 | static 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 | |
---|
141 | static void Initialize(), Realize(), Destroy(), Redisplay(); |
---|
142 | static Boolean SetValues(); |
---|
143 | static void draw_it (); |
---|
144 | |
---|
145 | static void ClassInitialize(); |
---|
146 | |
---|
147 | static int max (a,b) { return a > b ? a : b; } |
---|
148 | |
---|
149 | static void |
---|
150 | EraseName (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 | |
---|
163 | static void |
---|
164 | DrawName (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 | |
---|
177 | static void |
---|
178 | realizeCursor (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 | |
---|
207 | static void |
---|
208 | EraseFail (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 | |
---|
224 | static void |
---|
225 | XorCursor (w) |
---|
226 | LoginWidget w; |
---|
227 | { |
---|
228 | realizeCursor (w, w->login.xorGC); |
---|
229 | } |
---|
230 | |
---|
231 | static void |
---|
232 | RemoveFail (w) |
---|
233 | LoginWidget w; |
---|
234 | { |
---|
235 | if (w->login.failUp) |
---|
236 | EraseFail (w); |
---|
237 | } |
---|
238 | |
---|
239 | static void |
---|
240 | EraseCursor (w) |
---|
241 | LoginWidget (w); |
---|
242 | { |
---|
243 | realizeCursor (w, w->login.bgGC); |
---|
244 | } |
---|
245 | |
---|
246 | /*ARGSUSED*/ |
---|
247 | void 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 | |
---|
257 | DrawFail (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 | |
---|
276 | RedrawFail (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 | |
---|
288 | static void |
---|
289 | draw_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*/ |
---|
323 | static void |
---|
324 | DeleteBackwardChar (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*/ |
---|
353 | static void |
---|
354 | DeleteForwardChar (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*/ |
---|
384 | static void |
---|
385 | MoveBackwardChar (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*/ |
---|
401 | static void |
---|
402 | MoveForwardChar (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*/ |
---|
426 | static void |
---|
427 | MoveToBegining (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*/ |
---|
442 | static void |
---|
443 | MoveToEnd (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*/ |
---|
465 | static void |
---|
466 | EraseToEndOfLine (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*/ |
---|
489 | static void |
---|
490 | EraseLine (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*/ |
---|
501 | static void |
---|
502 | FinishField (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*/ |
---|
527 | static void |
---|
528 | AllowAccess (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*/ |
---|
546 | static void |
---|
547 | SetSessionArgument (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*/ |
---|
569 | static void |
---|
570 | RestartSession (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*/ |
---|
587 | static void |
---|
588 | AbortSession (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*/ |
---|
605 | static void |
---|
606 | AbortDisplay (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 | |
---|
622 | ResetLogin (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 */ |
---|
633 | static void |
---|
634 | InsertChar (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*/ |
---|
675 | static 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 | |
---|
684 | static XtConvertArgRec displayConvertArg[] = { |
---|
685 | {XtProcedureArg, (XtPointer)FetchDisplayArg, 0}, |
---|
686 | }; |
---|
687 | |
---|
688 | /* ARGSUSED */ |
---|
689 | static 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 | |
---|
778 | static 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 | |
---|
787 | static 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 */ |
---|
802 | static void Redisplay(gw, event, region) |
---|
803 | Widget gw; |
---|
804 | XEvent *event; |
---|
805 | Region region; |
---|
806 | { |
---|
807 | draw_it ((LoginWidget) gw); |
---|
808 | } |
---|
809 | |
---|
810 | /*ARGSUSED*/ |
---|
811 | static 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 | |
---|
825 | char defaultLoginTranslations [] = |
---|
826 | "\ |
---|
827 | Ctrl<Key>H: delete-previous-character() \n\ |
---|
828 | Ctrl<Key>D: delete-character() \n\ |
---|
829 | Ctrl<Key>B: move-backward-character() \n\ |
---|
830 | Ctrl<Key>F: move-forward-character() \n\ |
---|
831 | Ctrl<Key>A: move-to-begining() \n\ |
---|
832 | Ctrl<Key>E: move-to-end() \n\ |
---|
833 | Ctrl<Key>K: erase-to-end-of-line() \n\ |
---|
834 | Ctrl<Key>U: erase-line() \n\ |
---|
835 | Ctrl<Key>X: erase-line() \n\ |
---|
836 | Ctrl<Key>C: restart-session() \n\ |
---|
837 | Ctrl<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 | |
---|
845 | XtActionsRec 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 | |
---|
863 | LoginClassRec 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 | |
---|
900 | WidgetClass loginWidgetClass = (WidgetClass) &loginClassRec; |
---|