+ `(menu-item ,(purecopy "tool bar") ignore
+ :filter tool-bar-make-keymap))
+
+(declare-function image-mask-p "image.c" (spec &optional frame))
+
+(defconst tool-bar-keymap-cache (make-hash-table :weakness t :test 'equal))
+
+(defun tool-bar-make-keymap (&optional ignore)
+ "Generate an actual keymap from `tool-bar-map'.
+Its main job is to figure out which images to use based on the display's
+color capability and based on the available image libraries."
+ (let ((key (cons (frame-terminal) tool-bar-map)))
+ (or (gethash key tool-bar-keymap-cache)
+ (puthash key (tool-bar-make-keymap-1) tool-bar-keymap-cache))))
+
+(defun tool-bar-make-keymap-1 ()
+ "Generate an actual keymap from `tool-bar-map', without caching."
+ (mapcar (lambda (bind)
+ (let (image-exp plist)
+ (when (and (eq (car-safe (cdr-safe bind)) 'menu-item)
+ ;; For the format of menu-items, see node
+ ;; `Extended Menu Items' in the Elisp manual.
+ (setq plist (nthcdr (if (consp (nth 4 bind)) 5 4)
+ bind))
+ (setq image-exp (plist-get plist :image))
+ (consp image-exp)
+ (not (eq (car image-exp) 'image))
+ (fboundp (car image-exp)))
+ (if (not (display-images-p))
+ (setq bind nil)
+ (let ((image (eval image-exp)))
+ (unless (and image (image-mask-p image))
+ (setq image (append image '(:mask heuristic))))
+ (setq bind (copy-sequence bind)
+ plist (nthcdr (if (consp (nth 4 bind)) 5 4)
+ bind))
+ (plist-put plist :image image))))
+ bind))
+ tool-bar-map))