[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Passwords
- To: Denis R Howlett <drh@world.std.com>
- Subject: Re: Passwords
- From: bill@cambridge.apple.com (Bill St. Clair)
- Date: Mon, 13 Jul 1992 21:33:01 -0500
- Cc: info-mcl
>My thanks to Richard Lynch, Dale Fish, Stephen Davis, Danny Brewer et al.
>for all their suggestions on how to do passwords. My final (so far)
>version is based on ideas from all, but primarily the idea of having
>one real dialog-item that isn't shown and a display-only one that just
>has the blobs. By capturing all the keystrokes and mouse clicks and
>applying them to both, I get an acceptable dialog-item which doesn't
>suffer from refresh problems, allows almost all the flexibility of
>normal editable-text-dialog-items (complex commands don't work too
>well - but who needs them for passwords), and doesn't require
>special fonts or anything.
>
>Here are the definitions I'm going to use...
>
>Hope it's of interest, and of course if anyone improves on this, please
>let me know.
By specializing VIEW-KEY-EVENT-HANDLER instead of KEYSTROKE-FUNCTION,
you can make all the "complex" commands work as well. I also
changed your class to inherit directly from FRED-DIALOG-ITEM
instead of EDITABLE-TEXT-DIALOG-ITEM since EDITABLE-TEXT-DIALOG-ITEM
is intended to be redefineable to inherit from TEXT-EDIT-DIALOG-ITEM
(defined in an example file).
-------------------------------------------------------------------------
;; The definition of a class of editable-text-dialog-item that doesn't
;; echo the characters entered.
(defclass password-text-dialog-item (fred-dialog-item)
;; the password-text-dialog-item has two extra attributes:
;; - the alter-ego is a regular editable-text-dialog-item which holds
;; the true text
;; - the echo-char holds the character to be used for echoing. The
;; default is the bullet character.
((alter-ego :initform nil
:initarg :alter-ego
:accessor password-text-alter-ego)
(echo-char :initform #\245
:initarg :echo-char
:accessor password-text-echo-char)))
(defmethod initialize-instance ((item password-text-dialog-item) &rest args)
;; this method creates a regular editable-text-dialog-item
;; and stores it in the alter-ego slot.
(declare (ignore args))
(setf (password-text-alter-ego item)
(make-instance 'editable-text-dialog-item))
(call-next-method))
(defmethod view-key-event-handler ((item password-text-dialog-item) char)
;; the secret here is to realize that the only user-distinguishable
;; properties of the visible part of the password-dialog-item are
;; the number of bullets and the selection. We actually process
;; the keystroke in the alter-ego, then fix up the visible version
;; to have the same number of characters and the same selection.
;; Note that there are some security problems with this: c-s works,
;; as do cut and paste (you can cut from the password dialog and
;; paste somewhere else).
(let* ((alter-ego (password-text-alter-ego item))
(echo-char (password-text-echo-char item)))
(view-key-event-handler alter-ego char)
(let* ((alter-length (buffer-size (fred-buffer alter-ego)))
(buf (fred-buffer item))
(length (buffer-size buf)))
(if (> alter-length length)
(dotimes (i (- alter-length length))
(buffer-insert buf echo-char))
(buffer-delete buf alter-length length))
(multiple-value-bind (start end) (selection-range alter-ego)
(set-selection-range item start end)))))
(defmethod view-click-event-handler :after ((item password-text-dialog-item)
where)
;; To handle the mouse, we have to see if the user has marked a region
;; or moved the insertion point. Fortunately, the functions
;; selection-range and set-selection-range do both for us, so, whenever
;; the user uses the mouse, update the selection range and cursor
;; position. This ensures that the user can delete a whole range etc.
(declare (ignore where))
(let ((alter-ego (password-text-alter-ego item)))
(multiple-value-bind (position cursorpos)
(selection-range item)
(set-selection-range alter-ego position cursorpos))))
(defmethod dialog-item-text ((item password-text-dialog-item))
;; this allows transparent access to the text - call this just
;; like for any dialog item, but it returns the correct text
;; from the alter-ego.
(dialog-item-text (password-text-alter-ego item)))
#|
(defun get-password ()
;; This is a simple example of the use of the password-text-dialog-item
(let ((win (make-instance 'dialog
:window-type :double-edge-box
:view-position :centered
:view-size #@(200 100)
:close-box-p nil
:view-font '("Chicago" 12 :SRCOR :PLAIN)))
(password (make-dialog-item 'password-text-dialog-item
#@(20 44)
#@(133 16)
""
nil
:allow-returns nil)))
(add-subviews win
(make-dialog-item 'static-text-dialog-item
#@(16 14)
#@(141 16)
"Enter the password:"
nil)
password
(make-dialog-item 'button-dialog-item
#@(91 81)
#@(62 16)
"OK"
#'(lambda
(item)
item
(return-from-modal-dialog
(dialog-item-text password)))
:default-button t))
(modal-dialog win)))
|#