home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-06-14 | 4.8 KB | 142 lines | [TEXT/R*ch] |
- // (C) 1992 Stuart Cheshire <cheshire@cs.stanford.edu>
- //
- // This is the user-entry dialog box code, with a special custom FilterProc to
- // do the 'blobby' password field because Apple provides no standard dialog item
- // to give that behaviour. More re-inventing the wheel. It also checks whether
- // any of the password is typed with Caps Lock pressed -- so that the user can
- // be given a hint about the probable reason if their password is rejected.
-
- #define USERNAME_RESOURCE_ID 128
- #define CAPS_LOCK 0x39
- static Boolean caps_pressed = FALSE;
-
- // Dialogs in program
- enum { dialog_password = 128 };
-
- // Buttons in the password dialog
- enum { dlog_OK = 1, dlog_Cancel, dlog_useritem, dlog_username, dlog_password };
-
- static void DeleteRange(unsigned char *buffer, short start, short end)
- {
- unsigned char *last = buffer + buffer[0];
- unsigned char *src = buffer + 1 + end;
- unsigned char *dest = buffer + 1 + start;
- while (src <= last) *dest++ = *src++; // Close up gap in string
- buffer[0] -= (end-start); // Adjust the buffer's length
- }
-
- static void InsertChar(unsigned char *buffer, short pos, char c)
- {
- unsigned char km[16];
- register short i = buffer[0];
- if (i == 0xFF) return; // return if string already full
- while (i > pos) { buffer[i+1] = buffer[i]; i--; }
- buffer[pos+1] = c; // Fill in the new character
- buffer[0]++; // Add one to the length of the string
- GetKeys((long *)km);
- if (km[CAPS_LOCK>>3] & 1 << (CAPS_LOCK & 7)) caps_pressed = TRUE;
- }
-
- static pascal Boolean FilterProc(DialogPtr dlog, EventRecord *event, short *itemHit)
- {
- char key = event->message & charCodeMask;
- Boolean editing_password = (((DialogPeek)dlog)->editField == dlog_password-1);
-
- // Only do special processing for keyboard events
- if (event->what != keyDown && event->what != autoKey) return(false);
-
- // if in password field, Return & Enter are equivalent to hitting the OK button
- // otherwise they are equivalent to a TAB, to move us into the password field.
- // This is because Unix users often press return after entering their user name
- // instead of TAB -- no need to make there lives any harder
- if (key==3 || key==13)
- {
- if (editing_password) { *itemHit = 1; return(true); }
- else { event->message = '\t'; return(false); }
- }
-
- // Escape hits cancel
- if (key==27) { *itemHit = 2; return(true); }
-
- // Ignore command keys
- if (event->modifiers & cmdKey) { event->what = nullEvent; return(false); }
-
- // All keys except Tab and cursor keys get our special treatment
- if (editing_password && key!='\t' && (key<28 || key>31))
- {
- unsigned char *buffer = (unsigned char*)GetWRefCon(dlog); // Get buffer's address
- short start = (*((DialogPeek)dlog)->textH)->selStart; // Get current selection
- short end = (*((DialogPeek)dlog)->textH)->selEnd;
- if (start > buffer[0]) start = buffer[0]; // Sanity checks,
- if (end > buffer[0]) end = buffer[0]; // just in case
-
- if (start != end) DeleteRange(buffer,start,end); // If there's a selection, delete it
-
- // If not delete key then stash the key and change code to a blob, else
- // see if we have to delete a single character (when there is no selection)
- if (key != 8) { InsertChar(buffer,start,key); event->message = 'Ä'; }
- else if (start == end && start > 0) DeleteRange(buffer,start-1,start);
- }
- return(false); // Let ModalDialog insert the fake char
- }
-
- static pascal void OutlineOK(DialogPtr dlg, short item)
- {
- int i;
- short di_type;
- Handle di_handle;
- Rect di_box;
- PenSize(3,3);
- GetDItem(dlg, dlog_OK, &di_type, &di_handle, &di_box);
- InsetRect(&di_box,-4,-4);
- FrameRoundRect(&di_box,16,16);
- PenNormal();
- }
-
- static void do_dialog(void)
- {
- Handle username = GetResource('STR ', USERNAME_RESOURCE_ID);
- Str255 user, pass;
- short di_type, item;
- Handle di_handle;
- Rect di_box;
- DialogPtr modal = GetNewDialog(dialog_password, NULL, (WindowPtr)(-1));
-
- GetDItem(modal, dlog_useritem, &di_type, &di_handle, &di_box);
- SetDItem(modal, dlog_useritem, di_type, (Handle)OutlineOK, &di_box);
-
- GetDItem(modal, dlog_username, &di_type, &di_handle, &di_box);
- SetIText(di_handle, (StringPtr)*username); // Get username from resource
- GetIText(di_handle, user); // and initialize 'user' with it.
- SelIText(modal, dlog_username, 0, 32767);
-
- pass[0] = 0;
- caps_pressed = FALSE;
- SetWRefCon(modal,(long)pass);
- ShowWindow(modal);
-
- while(TRUE)
- {
- SetPort(modal);
- GetDItem(modal, dlog_OK, &di_type, &di_handle, &di_box);
- HiliteControl((ControlHandle)di_handle, *user ? 0 : 255);
-
- ModalDialog(FilterProc, &item);
- GetDItem(modal, dlog_username, &di_type, &di_handle, &di_box);
- GetIText(di_handle, user);
-
- if (item == dlog_Cancel) break;
- else if (item == dlog_OK)
- {
- if (!*user) continue; // invalid choice if no name
- // (Note: this test because pressing Return hits OK button even if disabled)
-
- // here do whatever stuff with (user, pass);
-
- break;
- }
- }
- ReleaseResource(username);
- DisposDialog(modal);
- }
-