]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/gdb-ui.el
Merged in changes from CVS trunk.
[gnu-emacs] / lisp / progmodes / gdb-ui.el
index cf2b0797e82db86d47432029e3801819955a7ac7..f7ba72e17226fba1c7a214232a728ec0597632e0 100644 (file)
 (defvar gdb-current-frame nil)
 (defvar gdb-current-stack-level nil)
 (defvar gdb-current-language nil)
-(defvar gdb-view-source t "Non-nil means that source code can be viewed.")
-(defvar gdb-selected-view 'source "Code type that user wishes to view.")
 (defvar gdb-var-list nil "List of variables in watch window.")
 (defvar gdb-var-changed nil "Non-nil means that gdb-var-list has changed.")
 (defvar gdb-buffer-type nil)
 (defvar gdb-overlay-arrow-position nil)
-(defvar gdb-variables '()
-  "A list of variables that are local to the GUD buffer.")
 (defvar gdb-server-prefix nil)
+(defvar gdb-flush-pending-output nil)
+
+(defvar gdb-buffer-type nil
+  "One of the symbols bound in `gdb-buffer-rules'.")
+
+(defvar gdb-input-queue ()
+  "A list of gdb command objects.")
+
+(defvar gdb-prompting nil
+  "True when gdb is idle with no pending input.")
+
+(defvar gdb-output-sink 'user
+  "The disposition of the output of the current gdb command.
+Possible values are these symbols:
+
+    `user' -- gdb output should be copied to the GUD buffer
+              for the user to see.
+
+    `inferior' -- gdb output should be copied to the inferior-io buffer
+
+    `pre-emacs' -- output should be ignored util the post-prompt
+                   annotation is received.  Then the output-sink
+                  becomes:...
+    `emacs' -- output should be collected in the partial-output-buffer
+              for subsequent processing by a command.  This is the
+              disposition of output generated by commands that
+              gdb mode sends to gdb on its own behalf.
+    `post-emacs' -- ignore output until the prompt annotation is
+                   received, then go to USER disposition.
+
+gdba (gdb-ui.el) uses all five values,  gdbmi (gdb-mi.el) only two
+\(`user' and `emacs').")
+
+(defvar gdb-current-item nil
+  "The most recent command item sent to gdb.")
+
+(defvar gdb-pending-triggers '()
+  "A list of trigger functions that have run later than their output
+handlers.")
+
+;; end of gdb variables
 
 ;;;###autoload
 (defun gdba (command-line)
@@ -185,8 +222,6 @@ detailed description of this mode.
   (setq gdb-previous-frame nil)
   (setq gdb-current-frame nil)
   (setq gdb-current-stack-level nil)
-  (setq gdb-view-source t)
-  (setq gdb-selected-view 'source)
   (setq gdb-var-list nil)
   (setq gdb-var-changed nil)
   (setq gdb-first-prompt nil)
@@ -196,8 +231,8 @@ detailed description of this mode.
   (setq gdb-pending-triggers nil)
   (setq gdb-output-sink 'user)
   (setq gdb-server-prefix "server ")
+  (setq gdb-flush-pending-output nil)
   ;;
-  (mapc 'make-local-variable gdb-variables)
   (setq gdb-buffer-type 'gdba)
   ;;
   (if gdb-use-inferior-io-buffer (gdb-clear-inferior-io))
@@ -236,7 +271,7 @@ detailed description of this mode.
            (concat "server interpreter mi \"-var-create - * "  expr "\"\n")
          (concat"-var-create - * "  expr "\n"))
             `(lambda () (gdb-var-create-handler ,expr))))))
-  (select-window (get-buffer-window gud-comint-buffer 'visible)))
+  (select-window (get-buffer-window gud-comint-buffer 0)))
 
 (defun gdb-goto-info ()
   "Go to Emacs info node: GDB Graphical Interface."
@@ -276,7 +311,7 @@ detailed description of this mode.
     (goto-char (point-min))
     (re-search-forward ".*value=\"\\(.*?\\)\"" nil t)
     (catch 'var-found
-      (let ((var-list nil) (num 0))
+      (let ((num 0))
        (dolist (var gdb-var-list)
          (if (string-equal varnum (cadr var))
              (progn
@@ -412,46 +447,6 @@ INDENT is the current indentation depth."
           (if (string-match (concat token "\\.") (nth 1 var))
               (setq gdb-var-list (delq var gdb-var-list))))
         (setq gdb-var-changed t))))
-\f
-(defvar gdb-buffer-type nil
-  "One of the symbols bound in `gdb-buffer-rules'.")
-
-(defvar gdb-input-queue ()
-  "A list of gdb command objects.")
-
-(defvar gdb-prompting nil
-  "True when gdb is idle with no pending input.")
-
-(defvar gdb-output-sink 'user
-  "The disposition of the output of the current gdb command.
-Possible values are these symbols:
-
-    `user' -- gdb output should be copied to the GUD buffer
-              for the user to see.
-
-    `inferior' -- gdb output should be copied to the inferior-io buffer
-
-    `pre-emacs' -- output should be ignored util the post-prompt
-                   annotation is received.  Then the output-sink
-                  becomes:...
-    `emacs' -- output should be collected in the partial-output-buffer
-              for subsequent processing by a command.  This is the
-              disposition of output generated by commands that
-              gdb mode sends to gdb on its own behalf.
-    `post-emacs' -- ignore output until the prompt annotation is
-                   received, then go to USER disposition.
-
-gdba (gdb-ui.el) uses all five values,  gdbmi (gdb-mi.el) only two
-\(`user' and `emacs').")
-
-(defvar gdb-current-item nil
-  "The most recent command item sent to gdb.")
-
-(defvar gdb-pending-triggers '()
-  "A list of trigger functions that have run later than their output
-handlers.")
-
-;; end of gdb variables
 
 (defun gdb-get-target-string ()
   (with-current-buffer gud-comint-buffer
@@ -644,6 +639,27 @@ This filter may simply queue input for a later time."
         (let ((last (car (last queue))))
           (unless (nbutlast queue) (setq gdb-input-queue '()))
           last))))
+
+(defun gdb-send-item (item)
+  (setq gdb-flush-pending-output nil)
+  (if gdb-enable-debug-log (push (cons 'send item) gdb-debug-log))
+  (setq gdb-current-item item)
+  (with-current-buffer gud-comint-buffer
+    (if (eq gud-minor-mode 'gdba)
+       (if (stringp item)
+           (progn
+             (setq gdb-output-sink 'user)
+             (process-send-string (get-buffer-process gud-comint-buffer) item))
+         (progn
+           (gdb-clear-partial-output)
+           (setq gdb-output-sink 'pre-emacs)
+           (process-send-string (get-buffer-process gud-comint-buffer)
+                                (car item))))
+      ;; case: eq gud-minor-mode 'gdbmi
+      (gdb-clear-partial-output)
+      (setq gdb-output-sink 'emacs)
+      (process-send-string (get-buffer-process gud-comint-buffer)
+                          (car item)))))
 \f
 ;;
 ;; output -- things gdb prints to emacs
@@ -688,6 +704,14 @@ This filter may simply queue input for a later time."
     ("stopped" gdb-stopped)
     ) "An assoc mapping annotation tags to functions which process them.")
 
+(defun gdb-resync()
+  (setq gdb-flush-pending-output t)
+  (setq gud-running nil)
+  (setq gdb-output-sink 'user)
+  (setq gdb-input-queue nil)
+  (setq gdb-pending-triggers nil)
+  (setq gdb-prompting t))
+
 (defconst gdb-source-spec-regexp
   "\\(.*\\):\\([0-9]*\\):[0-9]*:[a-z]*:\\(0x[a-f0-9]*\\)")
 
@@ -700,31 +724,10 @@ This filter may simply queue input for a later time."
         (match-string 1 args)
         (string-to-int (match-string 2 args))))
   (setq gdb-current-address (match-string 3 args))
-  (setq gdb-view-source t)
   ;; cover for auto-display output which comes *before*
   ;; stopped annotation
   (if (eq gdb-output-sink 'inferior) (setq gdb-output-sink 'user)))
 
-(defun gdb-send-item (item)
-  (if gdb-enable-debug-log (push (cons 'send item) gdb-debug-log))
-  (setq gdb-current-item item)
-  (with-current-buffer gud-comint-buffer
-    (if (eq gud-minor-mode 'gdba)
-       (if (stringp item)
-           (progn
-             (setq gdb-output-sink 'user)
-             (process-send-string (get-buffer-process gud-comint-buffer) item))
-         (progn
-           (gdb-clear-partial-output)
-           (setq gdb-output-sink 'pre-emacs)
-           (process-send-string (get-buffer-process gud-comint-buffer)
-                                (car item))))
-      ;; case: eq gud-minor-mode 'gdbmi
-      (gdb-clear-partial-output)
-      (setq gdb-output-sink 'emacs)
-      (process-send-string (get-buffer-process gud-comint-buffer)
-                          (car item)))))
-
 (defun gdb-pre-prompt (ignored)
   "An annotation handler for `pre-prompt'.
 This terminates the collection of output from a previous command if that
@@ -735,7 +738,7 @@ happens to be in effect."
      ((eq sink 'emacs)
       (setq gdb-output-sink 'post-emacs))
      (t
-      (setq gdb-output-sink 'user)
+      (gdb-resync)
       (error "Phase error in gdb-pre-prompt (got %s)" sink)))))
 
 (defun gdb-prompt (ignored)
@@ -752,7 +755,7 @@ This sends the next command (if any) to gdb."
        (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
          (funcall handler))))
      (t
-      (setq gdb-output-sink 'user)
+      (gdb-resync)
       (error "Phase error in gdb-prompt (got %s)" sink))))
   (let ((input (gdb-dequeue-input)))
     (if input
@@ -776,7 +779,9 @@ not GDB."
        (setq gud-running t)
        (if gdb-use-inferior-io-buffer
            (setq gdb-output-sink 'inferior))))
-     (t (error "Unexpected `starting' annotation")))))
+     (t 
+      (gdb-resync)
+      (error "Unexpected `starting' annotation")))))
 
 (defun gdb-stopping (ignored)
   "An annotation handler for `exited' and other annotations.
@@ -787,7 +792,9 @@ being debugged."
        (cond
         ((eq sink 'inferior)
          (setq gdb-output-sink 'user))
-        (t (error "Unexpected stopping annotation"))))))
+        (t
+         (gdb-resync)
+         (error "Unexpected stopping annotation"))))))
 
 (defun gdb-frame-begin (ignored)
   (let ((sink gdb-output-sink))
@@ -796,7 +803,9 @@ being debugged."
       (setq gdb-output-sink 'user))
      ((eq sink 'user) t)
      ((eq sink 'emacs) t)
-     (t (error "Unexpected frame-begin annotation (%S)" sink)))))
+     (t
+      (gdb-resync)
+      (error "Unexpected frame-begin annotation (%S)" sink)))))
 
 (defun gdb-stopped (ignored)
   "An annotation handler for `stopped'.
@@ -808,7 +817,9 @@ sink to `user' in `gdb-stopping', that is fine."
      ((eq sink 'inferior)
       (setq gdb-output-sink 'user))
      ((eq sink 'user) t)
-     (t (error "Unexpected stopped annotation")))))
+     (t
+      (gdb-resync)
+      (error "Unexpected stopped annotation")))))
 
 (defun gdb-post-prompt (ignored)
   "An annotation handler for `post-prompt'.
@@ -837,66 +848,68 @@ happens to be appropriate."
      ((eq sink 'pre-emacs)
       (setq gdb-output-sink 'emacs))
      (t
-      (setq gdb-output-sink 'user)
+      (gdb-resync)
       (error "Phase error in gdb-post-prompt (got %s)" sink)))))
 
 (defun gud-gdba-marker-filter (string)
   "A gud marker filter for gdb.  Handle a burst of output from GDB."
-  (if gdb-enable-debug-log (push (cons 'recv string) gdb-debug-log))
-  ;; Recall the left over gud-marker-acc from last time
-  (setq gud-marker-acc (concat gud-marker-acc string))
-  ;; Start accumulating output for the GUD buffer
-  (let ((output ""))
-    ;;
-    ;; Process all the complete markers in this chunk.
-    (while (string-match "\n\032\032\\(.*\\)\n" gud-marker-acc)
-      (let ((annotation (match-string 1 gud-marker-acc)))
-       ;;
-       ;; Stuff prior to the match is just ordinary output.
-       ;; It is either concatenated to OUTPUT or directed
-       ;; elsewhere.
-       (setq output
-             (gdb-concat-output
-              output
-              (substring gud-marker-acc 0 (match-beginning 0))))
-        ;;
-       ;; Take that stuff off the gud-marker-acc.
-       (setq gud-marker-acc (substring gud-marker-acc (match-end 0)))
-        ;;
-       ;; Parse the tag from the annotation, and maybe its arguments.
-       (string-match "\\(\\S-*\\) ?\\(.*\\)" annotation)
-       (let* ((annotation-type (match-string 1 annotation))
-              (annotation-arguments (match-string 2 annotation))
-              (annotation-rule (assoc annotation-type
-                                      gdb-annotation-rules)))
-         ;; Call the handler for this annotation.
-         (if annotation-rule
-             (funcall (car (cdr annotation-rule))
-                      annotation-arguments)
-           ;; Else the annotation is not recognized.  Ignore it silently,
-           ;; so that GDB can add new annotations without causing
-           ;; us to blow up.
-           ))))
-    ;;
-    ;; Does the remaining text end in a partial line?
-    ;; If it does, then keep part of the gud-marker-acc until we get more.
-    (if (string-match "\n\\'\\|\n\032\\'\\|\n\032\032.*\\'"
-                     gud-marker-acc)
-       (progn
-         ;; Everything before the potential marker start can be output.
+  (if gdb-flush-pending-output
+      nil
+    (if gdb-enable-debug-log (push (cons 'recv string) gdb-debug-log))
+    ;; Recall the left over gud-marker-acc from last time
+    (setq gud-marker-acc (concat gud-marker-acc string))
+    ;; Start accumulating output for the GUD buffer
+    (let ((output ""))
+      ;;
+      ;; Process all the complete markers in this chunk.
+      (while (string-match "\n\032\032\\(.*\\)\n" gud-marker-acc)
+       (let ((annotation (match-string 1 gud-marker-acc)))
+         ;;
+         ;; Stuff prior to the match is just ordinary output.
+         ;; It is either concatenated to OUTPUT or directed
+         ;; elsewhere.
          (setq output
-               (gdb-concat-output output
-                                  (substring gud-marker-acc 0
-                                             (match-beginning 0))))
+               (gdb-concat-output
+                output
+                (substring gud-marker-acc 0 (match-beginning 0))))
+         ;;
+         ;; Take that stuff off the gud-marker-acc.
+         (setq gud-marker-acc (substring gud-marker-acc (match-end 0)))
          ;;
-         ;; Everything after, we save, to combine with later input.
-         (setq gud-marker-acc (substring gud-marker-acc (match-beginning 0))))
+         ;; Parse the tag from the annotation, and maybe its arguments.
+         (string-match "\\(\\S-*\\) ?\\(.*\\)" annotation)
+         (let* ((annotation-type (match-string 1 annotation))
+                (annotation-arguments (match-string 2 annotation))
+                (annotation-rule (assoc annotation-type
+                                        gdb-annotation-rules)))
+           ;; Call the handler for this annotation.
+           (if annotation-rule
+               (funcall (car (cdr annotation-rule))
+                        annotation-arguments)
+             ;; Else the annotation is not recognized.  Ignore it silently,
+             ;; so that GDB can add new annotations without causing
+             ;; us to blow up.
+             ))))
       ;;
-      ;; In case we know the gud-marker-acc contains no partial annotations:
-      (progn
-       (setq output (gdb-concat-output output gud-marker-acc))
-       (setq gud-marker-acc "")))
-    output))
+      ;; Does the remaining text end in a partial line?
+      ;; If it does, then keep part of the gud-marker-acc until we get more.
+      (if (string-match "\n\\'\\|\n\032\\'\\|\n\032\032.*\\'"
+                       gud-marker-acc)
+         (progn
+           ;; Everything before the potential marker start can be output.
+           (setq output
+                 (gdb-concat-output output
+                                    (substring gud-marker-acc 0
+                                               (match-beginning 0))))
+           ;;
+           ;; Everything after, we save, to combine with later input.
+           (setq gud-marker-acc (substring gud-marker-acc (match-beginning 0))))
+       ;;
+       ;; In case we know the gud-marker-acc contains no partial annotations:
+       (progn
+         (setq output (gdb-concat-output output gud-marker-acc))
+         (setq gud-marker-acc "")))
+      output)))
 
 (defun gdb-concat-output (so-far new)
   (let ((sink gdb-output-sink))
@@ -909,7 +922,9 @@ happens to be appropriate."
      ((eq sink 'inferior)
       (gdb-append-to-inferior-io new)
       so-far)
-     (t (error "Bogon output sink %S" sink)))))
+     (t
+      (gdb-resync)
+      (error "Bogon output sink %S" sink)))))
 
 (defun gdb-append-to-partial-output (string)
   (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
@@ -1101,7 +1116,7 @@ static char *magick[] = {
 
 ;;-put breakpoint icons in relevant margins (even those set in the GUD buffer)
 (defun gdb-info-breakpoints-custom ()
-  (let ((flag)(address))
+  (let ((flag))
     ;;
     ;; remove all breakpoint-icons in source buffers but not assembler buffer
     (dolist (buffer (buffer-list))
@@ -1168,7 +1183,7 @@ static char *magick[] = {
    (gdb-get-create-buffer 'gdb-breakpoints-buffer)))
 
 (defconst gdb-frame-parameters
-  '((height . 12) (width . 60)
+  '((height . 14) (width . 80)
     (unsplittable . t)
     (tool-bar-lines . nil)
     (menu-bar-lines . nil)
@@ -1177,9 +1192,9 @@ static char *magick[] = {
 (defun gdb-frame-breakpoints-buffer ()
   "Display status of user-settable breakpoints in a new frame."
   (interactive)
-  (select-frame (make-frame gdb-frame-parameters))
-  (switch-to-buffer (gdb-get-create-buffer 'gdb-breakpoints-buffer))
-  (set-window-dedicated-p (selected-window) t))
+  (let ((special-display-regexps (append special-display-regexps '(".*")))
+       (special-display-frame-alist gdb-frame-parameters))
+    (display-buffer (gdb-get-create-buffer 'gdb-breakpoints-buffer))))
 
 (defvar gdb-breakpoints-mode-map
   (let ((map (make-sparse-keymap))
@@ -1192,6 +1207,7 @@ static char *magick[] = {
     (define-key map [menu-bar breakpoints] (cons "Breakpoints" menu))
     (define-key map " " 'gdb-toggle-breakpoint)
     (define-key map "d" 'gdb-delete-breakpoint)
+    (define-key map "q" 'kill-this-buffer)
     (define-key map "\r" 'gdb-goto-breakpoint)
     (define-key map [mouse-2] 'gdb-mouse-goto-breakpoint)
     map))
@@ -1256,7 +1272,7 @@ static char *magick[] = {
            (let* ((buf (find-file-noselect (if (file-exists-p file)
                                                file
                                              (expand-file-name file gdb-cdir))))
-                  (window (gdb-display-buffer buf)))
+                  (window (display-buffer buf)))
              (with-current-buffer buf
                (goto-line (string-to-number line))
                (set-window-point window (point))))))
@@ -1313,13 +1329,14 @@ static char *magick[] = {
 (defun gdb-frame-stack-buffer ()
   "Display backtrace of current stack in a new frame."
   (interactive)
-  (select-frame (make-frame gdb-frame-parameters))
-  (switch-to-buffer (gdb-get-create-buffer 'gdb-stack-buffer))
-  (set-window-dedicated-p (selected-window) t))
+  (let ((special-display-regexps (append special-display-regexps '(".*")))
+       (special-display-frame-alist gdb-frame-parameters))
+    (display-buffer (gdb-get-create-buffer 'gdb-stack-buffer))))
 
 (defvar gdb-frames-mode-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
+    (define-key map "q" 'kill-this-buffer)
     (define-key map "\r" 'gdb-frames-select)
     (define-key map [mouse-2] 'gdb-frames-mouse-select)
     map))
@@ -1394,13 +1411,14 @@ static char *magick[] = {
 (defun gdb-frame-threads-buffer ()
   "Display IDs of currently known threads in a new frame."
   (interactive)
-  (select-frame (make-frame gdb-frame-parameters))
-  (switch-to-buffer (gdb-get-create-buffer 'gdb-threads-buffer))
-  (set-window-dedicated-p (selected-window) t))
+  (let ((special-display-regexps (append special-display-regexps '(".*")))
+       (special-display-frame-alist gdb-frame-parameters))
+    (display-buffer (gdb-get-create-buffer 'gdb-threads-buffer))))
 
 (defvar gdb-threads-mode-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
+    (define-key map "q" 'kill-this-buffer)
     (define-key map "\r" 'gdb-threads-select)
     (define-key map [mouse-2] 'gdb-threads-mouse-select)
     map))
@@ -1453,7 +1471,8 @@ static char *magick[] = {
 (defvar gdb-registers-mode-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
-    map))
+    (define-key map "q" 'kill-this-buffer)
+     map))
 
 (defun gdb-registers-mode ()
   "Major mode for gdb registers.
@@ -1480,9 +1499,9 @@ static char *magick[] = {
 (defun gdb-frame-registers-buffer ()
   "Display integer register contents in a new frame."
   (interactive)
-  (select-frame (make-frame gdb-frame-parameters))
-  (switch-to-buffer (gdb-get-create-buffer 'gdb-registers-buffer))
-  (set-window-dedicated-p (selected-window) t))
+  (let ((special-display-regexps (append special-display-regexps '(".*")))
+       (special-display-frame-alist gdb-frame-parameters))
+    (display-buffer (gdb-get-create-buffer 'gdb-registers-buffer))))
 \f
 ;;
 ;; Locals buffer.
@@ -1529,7 +1548,8 @@ static char *magick[] = {
 (defvar gdb-locals-mode-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
-    map))
+    (define-key map "q" 'kill-this-buffer)
+     map))
 
 (defun gdb-locals-mode ()
   "Major mode for gdb locals.
@@ -1558,52 +1578,33 @@ static char *magick[] = {
 (defun gdb-frame-locals-buffer ()
   "Display local variables of current stack and their values in a new frame."
   (interactive)
-  (select-frame (make-frame gdb-frame-parameters))
-  (switch-to-buffer (gdb-get-create-buffer 'gdb-locals-buffer))
-  (set-window-dedicated-p (selected-window) t))
+  (let ((special-display-regexps (append special-display-regexps '(".*")))
+       (special-display-frame-alist gdb-frame-parameters))
+    (display-buffer (gdb-get-create-buffer 'gdb-locals-buffer))))
 \f
 
 ;;;; Window management
-
-;;; The way we abuse the dedicated-p flag is pretty gross, but seems
-;;; to do the right thing.  Seeing as there is no way for Lisp code to
-;;; get at the use_time field of a window, I'm not sure there exists a
-;;; more elegant solution without writing C code.
-
 (defun gdb-display-buffer (buf &optional size)
-  (let ((must-split nil)
-       (answer nil))
-    (unwind-protect
-       (progn
-         (walk-windows
-          #'(lambda (win)
-             (if (eq gud-comint-buffer (window-buffer win))
-                 (set-window-dedicated-p win t))))
-         (setq answer (get-buffer-window buf 'visible))
-         (if (not answer)
-             (let ((window (get-lru-window 'visible)))
-               (if window
-                   (progn
-                     (set-window-buffer window buf)
-                     (setq answer window))
-                 (setq must-split t)))))
-      (walk-windows
-       #'(lambda (win)
-         (if (eq gud-comint-buffer (window-buffer win))
-             (set-window-dedicated-p win nil)))))
-    (if must-split
-       (let* ((largest (get-largest-window 'visible))
-              (cur-size (window-height largest))
-              (new-size (and size (< size cur-size) (- cur-size size))))
-         (setq answer (split-window largest new-size))
-         (set-window-buffer answer buf)))
-    answer))
-
-(defun gdb-display-source-buffer (buffer)
-  (if (eq gdb-selected-view 'source)
-       (gdb-display-buffer buffer)
-    (gdb-display-buffer (gdb-get-buffer 'gdb-assembler-buffer)))
-    (get-buffer-window buffer 'visible))
+  (let ((answer (get-buffer-window buf 0))
+       (must-split nil))
+    (if answer
+       (display-buffer buf)            ;Raise the frame if necessary.
+      ;; The buffer is not yet displayed.
+      (pop-to-buffer gud-comint-buffer)        ;Select the right frame.
+      (let ((window (get-lru-window)))
+       (if window
+           (progn
+             (set-window-buffer window buf)
+             (setq answer window))
+         (setq must-split t)))
+      (if must-split
+         (let* ((largest (get-largest-window))
+                (cur-size (window-height largest))
+                (new-size (and size (< size cur-size) (- cur-size size))))
+           (setq answer (split-window largest new-size))
+           (set-window-buffer answer buf)
+           (set-window-dedicated-p answer t)))
+      answer)))
 
 \f
 ;;; Shared keymap initialization:
@@ -1630,19 +1631,6 @@ static char *magick[] = {
   (define-key menu [frames] '("Stack" . gdb-display-stack-buffer))
   (define-key menu [breakpoints] '("Breakpoints" . gdb-display-breakpoints-buffer)))
 
-(let ((menu (make-sparse-keymap "View")))
-   (define-key gud-menu-map [view]
-     `(menu-item "View" ,menu :visible (eq gud-minor-mode 'gdba)))
-;  (define-key menu [both] '(menu-item "Both" gdb-view-both
-;             :help "Display both source and assembler"
-;             :button (:radio . (eq gdb-selected-view 'both))))
-   (define-key menu [assembler] '(menu-item "Machine" gdb-view-assembler
-              :help "Display assembler only"
-              :button (:radio . (eq gdb-selected-view 'assembler))))
-   (define-key menu [source] '(menu-item "Source" gdb-view-source-function
-              :help "Display source only"
-              :button (:radio . (eq gdb-selected-view 'source)))))
-
 (let ((menu (make-sparse-keymap "GDB-UI")))
   (define-key gud-menu-map [ui]
     `(menu-item "GDB-UI" ,menu :visible (eq gud-minor-mode 'gdba)))
@@ -1668,33 +1656,16 @@ static char *magick[] = {
 
 (defvar gdb-main-file nil "Source file from which program execution begins.")
 
-(defun gdb-view-source-function ()
-  "Select source view."
-  (interactive)
-  (if gdb-view-source
-      (gdb-display-buffer
-       (if gud-last-last-frame
-          (gud-find-file (car gud-last-last-frame))
-        (gud-find-file gdb-main-file))))
-  (setq gdb-selected-view 'source))
-
-(defun gdb-view-assembler()
-  "Select disassembly view."
-  (interactive)
-  (gdb-display-buffer (gdb-get-create-buffer 'gdb-assembler-buffer))
-  (gdb-invalidate-assembler)
-  (setq gdb-selected-view 'assembler))
-
-;(defun gdb-view-both()
-;(interactive)
-;(setq gdb-selected-view 'both))
-
 (defcustom gdb-show-main nil
   "Nil means don't display source file containing the main routine."
   :type 'boolean
   :group 'gud
   :version "21.4")
 
+(defun gdb-set-window-buffer (name)
+  (set-window-buffer (selected-window) (get-buffer name))
+  (set-window-dedicated-p (selected-window) t))
+
 (defun gdb-setup-windows ()
   "Layout the window pattern for gdb-many-windows."
   (gdb-display-locals-buffer)
@@ -1702,29 +1673,27 @@ static char *magick[] = {
   (delete-other-windows)
   (gdb-display-breakpoints-buffer)
   (delete-other-windows)
-  (switch-to-buffer gud-comint-buffer)
+  ; Don't dedicate.
+  (pop-to-buffer gud-comint-buffer)
   (split-window nil ( / ( * (window-height) 3) 4))
   (split-window nil ( / (window-height) 3))
   (split-window-horizontally)
   (other-window 1)
-  (switch-to-buffer (gdb-locals-buffer-name))
+  (gdb-set-window-buffer (gdb-locals-buffer-name))
   (other-window 1)
   (switch-to-buffer
-   (if (and gdb-view-source
-           (eq gdb-selected-view 'source))
        (if gud-last-last-frame
           (gud-find-file (car gud-last-last-frame))
-        (gud-find-file gdb-main-file))
-     (gdb-get-create-buffer 'gdb-assembler-buffer)))
+        (gud-find-file gdb-main-file)))
   (when gdb-use-inferior-io-buffer
     (split-window-horizontally)
     (other-window 1)
-    (switch-to-buffer (gdb-inferior-io-name)))
+    (gdb-set-window-buffer (gdb-inferior-io-name)))
   (other-window 1)
-  (switch-to-buffer (gdb-stack-buffer-name))
+  (gdb-set-window-buffer (gdb-stack-buffer-name))
   (split-window-horizontally)
   (other-window 1)
-  (switch-to-buffer (gdb-breakpoints-buffer-name))
+  (gdb-set-window-buffer (gdb-breakpoints-buffer-name))
   (other-window 1))
 
 (defcustom gdb-many-windows nil
@@ -1752,22 +1721,16 @@ of the inferior.  Non-nil means display the layout shown for
   "Restore the basic arrangement of windows used by gdba.
 This arrangement depends on the value of `gdb-many-windows'."
   (interactive)
-  (if gdb-many-windows
-      (progn
-       (switch-to-buffer gud-comint-buffer)
-       (delete-other-windows)
-       (gdb-setup-windows))
-    (switch-to-buffer gud-comint-buffer)
+  (pop-to-buffer gud-comint-buffer)    ;Select the right window and frame.
     (delete-other-windows)
+  (if gdb-many-windows
+      (gdb-setup-windows)
     (split-window)
     (other-window 1)
     (switch-to-buffer
-     (if (and gdb-view-source
-             (eq gdb-selected-view 'source))
         (if gud-last-last-frame
             (gud-find-file (car gud-last-last-frame))
-          (gud-find-file gdb-main-file))
-       (gdb-get-create-buffer 'gdb-assembler-buffer)))
+          (gud-find-file gdb-main-file)))
     (other-window 1)))
 
 (defun gdb-reset ()
@@ -1800,21 +1763,13 @@ buffers."
        (setq gdb-cdir (match-string 0))))
   (if (search-forward "Located in " nil t)
       (if (looking-at "\\S-*")
-         (setq gdb-main-file (match-string 0)))
-    (setq gdb-view-source nil))
-  (if gdb-many-windows
+         (setq gdb-main-file (match-string 0))))
+ (if gdb-many-windows
       (gdb-setup-windows)
     (gdb-get-create-buffer 'gdb-breakpoints-buffer)
-    (when gdb-show-main
-      (switch-to-buffer gud-comint-buffer)
-      (delete-other-windows)
-      (split-window)
-      (other-window 1)
-      (switch-to-buffer
-       (if gdb-view-source
-          (gud-find-file gdb-main-file)
-        (gdb-get-create-buffer 'gdb-assembler-buffer)))
-      (other-window 1))))
+    (if gdb-show-main
+      (let ((pop-up-windows t))
+       (display-buffer (gud-find-file gdb-main-file))))))
 
 ;;from put-image
 (defun gdb-put-string (putstring pos &optional dprop)
@@ -1860,9 +1815,9 @@ BUFFER nil or omitted means use the current buffer."
          (when (< left-margin-width 2)
            (save-current-buffer
              (setq left-margin-width 2)
-             (if (get-buffer-window (current-buffer) 'visible)
+             (if (get-buffer-window (current-buffer) 0)
                  (set-window-margins
-                  (get-buffer-window (current-buffer) 'visible)
+                  (get-buffer-window (current-buffer) 0)
                   left-margin-width right-margin-width))))
          (put-image
           (if enabled
@@ -1887,9 +1842,9 @@ BUFFER nil or omitted means use the current buffer."
       (when (< left-margin-width 2)
        (save-current-buffer
          (setq left-margin-width 2)
-         (if (get-buffer-window (current-buffer) 'visible)
+         (if (get-buffer-window (current-buffer) 0)
              (set-window-margins
-              (get-buffer-window (current-buffer) 'visible)
+              (get-buffer-window (current-buffer) 0)
               left-margin-width right-margin-width))))
       (gdb-put-string (if enabled "B" "b") (1+ start)))))
 
@@ -1899,9 +1854,9 @@ BUFFER nil or omitted means use the current buffer."
       (remove-images start end))
   (when remove-margin
     (setq left-margin-width 0)
-    (if (get-buffer-window (current-buffer) 'visible)
+    (if (get-buffer-window (current-buffer) 0)
        (set-window-margins
-        (get-buffer-window (current-buffer) 'visible)
+        (get-buffer-window (current-buffer) 0)
         left-margin-width right-margin-width))))
 
 \f
@@ -1953,12 +1908,13 @@ BUFFER nil or omitted means use the current buffer."
                  (if (re-search-forward address nil t)
                      (gdb-put-breakpoint-icon (eq flag ?y))))))))
     (if (not (equal gdb-current-address "main"))
-       (set-window-point (get-buffer-window buffer 'visible) pos))))
+       (set-window-point (get-buffer-window buffer 0) pos))))
 
 (defvar gdb-assembler-mode-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
-    map))
+    (define-key map "q" 'kill-this-buffer)
+     map))
 
 (defvar gdb-assembler-font-lock-keywords
   '(;; <__function.name+n>
@@ -2007,9 +1963,9 @@ BUFFER nil or omitted means use the current buffer."
 (defun gdb-frame-assembler-buffer ()
   "Display disassembly view in a new frame."
   (interactive)
-  (select-frame (make-frame gdb-frame-parameters))
-  (switch-to-buffer (gdb-get-create-buffer 'gdb-assembler-buffer))
-  (set-window-dedicated-p (selected-window) t))
+  (let ((special-display-regexps (append special-display-regexps '(".*")))
+       (special-display-frame-alist gdb-frame-parameters))
+    (display-buffer (gdb-get-create-buffer 'gdb-assembler-buffer))))
 
 ;; modified because if gdb-current-address has changed value a new command
 ;; must be enqueued to update the buffer with the new output
@@ -2024,7 +1980,7 @@ BUFFER nil or omitted means use the current buffer."
          (progn
            ;; take previous disassemble command off the queue
            (with-current-buffer gud-comint-buffer
-             (let ((queue gdb-input-queue) (item))
+             (let ((queue gdb-input-queue))
                (dolist (item queue)
                  (if (equal (cdr item) '(gdb-assembler-handler))
                      (setq gdb-input-queue
@@ -2064,14 +2020,9 @@ BUFFER nil or omitted means use the current buffer."
                (setq gdb-current-address
                      (concat "0x" (match-string 1 address)))
              (setq gdb-current-address (concat "0x" address))))
-         (if (or (if (not (re-search-forward "(\\S-*:[0-9]*);" nil t))
-                     (progn (setq gdb-view-source nil) t))
-                 (eq gdb-selected-view 'assembler))
-             (progn
-               (gdb-display-buffer
-                (gdb-get-create-buffer 'gdb-assembler-buffer))
+         (if (not (re-search-forward "(\\S-*:[0-9]*);" nil t))
                ;;update with new frame for machine code if necessary
-               (gdb-invalidate-assembler))))))
+               (gdb-invalidate-assembler)))))
     (if (re-search-forward " source language \\(\\S-*\\)\." nil t)
        (setq gdb-current-language (match-string 1))))