# HG changeset patch # User Stefan Monnier # Date 1268198331 18000 # Node ID adf240ef5c11ad320d03616cc6b0a2130266129b # Parent 4e4364e2100c1f31d43097ff344f09352da24611# Parent 3b11a4a71af11d2283e7fe9553d4a6c5ff18bda3 Merge pending branch diff -r 4e4364e2100c -r adf240ef5c11 etc/TODO --- a/etc/TODO Tue Mar 09 22:24:44 2010 +0900 +++ b/etc/TODO Wed Mar 10 00:18:51 2010 -0500 @@ -12,7 +12,46 @@ prepared to sign legal papers to transfer the copyright on your work to the FSF. -* Simple tasks. These don't require much emacs knowledge, they are +* Tentative plan for Emacs-24 + +** Bidi +** lexbind: I haven't checked the status of the code recently, so + I don't know how realistic it is to include it. But it's been around + for a long time, and I trust Miles, so I have hope. +** concurrency: including it as an "experimental" compile-time option + sounds good. Of course there might still be big questions around + "which form of concurrency" we'll want. +** Overhaul of customize: sounds wonderful. +** some kind of color-theme: agreed. +** better support for dynamic embedded graphics: I like this idea (my + mpc.el code could use it for the volume widget), tho I wonder if the + resulting efficiency will be sufficient. +** Spread Semantic. +** Improve the "code snippets" support: consolidate skeleton.el, tempo.el, + and expand.el (any other?) and then advertise/use/improve it. +** Improve VC: yes, there's a lot of work to be done there :-( + And most of it could/should make it into Emacs-23.3. +** package manager. + +** Random things that cross my mind right now that I'd like to see (some of +them from my local hacks), but it's not obvious at all whether they'll +make it. +*** multiple inheritance for keymaps (to get rid of the + fix_submap_inheritance hack and to more cleanly express the + relationship between minibuffer-local-*-map): I've had this locally + for a long time, but the details of the semantics is somewhat ... delicate. +*** prog-mode (a parent-mode, like text-mode). Could/should provide + a better fill-paragraph default that uses syntax-tables to recognize + string/comment boundaries. +*** provide more completion-at-point-functions. Make existing + in-buffer completion use completion-at-point. +*** "functional" function-key-map that would make it easy to add (and + remove) mappings like "FOO-mouse-4 -> FOO-scroll-down", + "FOO-tab -> ?\FOO-\t", "uppercase -> lowercase", "[fringe KEY...] -> + [KEY]", "H-FOO -> M-FOO", "C-x C-y FOO -> H-FOO", ... + + +* Simple tasks. These don't require much Emacs knowledge, they are suitable for anyone from beginners to experts. ** Convert modes that use view-mode to be derived from special-mode instead. diff -r 4e4364e2100c -r adf240ef5c11 lisp/ChangeLog --- a/lisp/ChangeLog Tue Mar 09 22:24:44 2010 +0900 +++ b/lisp/ChangeLog Wed Mar 10 00:18:51 2010 -0500 @@ -1,3 +1,17 @@ +2010-03-10 Kim F. Storm + + Animated image API. + http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg00211.html + + * image.el (image-animate-max-time): New defcustom. + (image-animated-types): New defconst. + (create-animated-image, image-animate-timer) + (image-animate-start, image-animate-stop, image-animate-timeout) + (image-animated-p): New functions. + + * image-mode.el (image-toggle-display-image): + Replace `create-image' with `create-animated-image'. + 2010-03-09 Miles Bader > * vc-git.el (vc-git-print-log): Use "tformat:" for shortlog, diff -r 4e4364e2100c -r adf240ef5c11 lisp/image-mode.el --- a/lisp/image-mode.el Tue Mar 09 22:24:44 2010 +0900 +++ b/lisp/image-mode.el Wed Mar 10 00:18:51 2010 -0500 @@ -466,7 +466,7 @@ (buffer-substring-no-properties (point-min) (point-max))) filename)) (type (image-type file-or-data nil data-p)) - (image (create-image file-or-data type data-p)) + (image (create-animated-image file-or-data type data-p)) (props `(display ,image intangible ,image diff -r 4e4364e2100c -r adf240ef5c11 lisp/image.el --- a/lisp/image.el Tue Mar 09 22:24:44 2010 +0900 +++ b/lisp/image.el Wed Mar 10 00:18:51 2010 -0500 @@ -584,7 +584,111 @@ (declare (doc-string 3)) `(defvar ,symbol (find-image ',specs) ,doc)) + +;;; Animated image API +(defcustom image-animate-max-time 30 + "Time in seconds to animate images." + :type 'integer + :version "22.1" + :group 'image) + +(defconst image-animated-types '(gif) + "List of supported animated image types.") + +;;;###autoload +(defun create-animated-image (file-or-data &optional type data-p &rest props) + "Create an animated image. +FILE-OR-DATA is an image file name or image data. +Optional TYPE is a symbol describing the image type. If TYPE is omitted +or nil, try to determine the image type from its first few bytes +of image data. If that doesn't work, and FILE-OR-DATA is a file name, +use its file extension as image type. +Optional DATA-P non-nil means FILE-OR-DATA is a string containing image data. +Optional PROPS are additional image attributes to assign to the image, +like, e.g. `:mask MASK'. +Value is the image created, or nil if images of type TYPE are not supported. + +Images should not be larger than specified by `max-image-size'." + (setq type (image-type file-or-data type data-p)) + (when (image-type-available-p type) + (let* ((animate (memq type image-animated-types)) + (image + (append (list 'image :type type (if data-p :data :file) file-or-data) + (if animate '(:index 0 :mask heuristic)) + props))) + (if animate + (image-animate-start image)) + image))) + +(defun image-animate-timer (image) + "Return the animation timer for image IMAGE." + ;; See cancel-function-timers + (let ((tail timer-list) timer) + (while tail + (setq timer (car tail) + tail (cdr tail)) + (if (and (eq (aref timer 5) #'image-animate-timeout) + (consp (aref timer 6)) + (eq (car (aref timer 6)) image)) + (setq tail nil) + (setq timer nil))) + timer)) + +(defun image-animate-start (image &optional max-time) + "Start animation of image IMAGE. +Optional second arg MAX-TIME is number of seconds to animate image, +or t to animate infinitely." + (let ((anim (image-animated-p image)) + timer tmo) + (when anim + (if (setq timer (image-animate-timer image)) + (setcar (nthcdr 3 (aref timer 6)) max-time) + (setq tmo (* (cdr anim) 0.01)) + (setq max-time (or max-time image-animate-max-time)) + (run-with-timer tmo nil #'image-animate-timeout + image 1 (car anim) + (if (numberp max-time) + (- max-time tmo) + max-time)))))) + +(defun image-animate-stop (image) + "Stop animation of image." + (let ((timer (image-animate-timer image))) + (when timer + (cancel-timer timer)))) + +(defun image-animate-timeout (image ino count time-left) + (if (>= ino count) + (setq ino 0)) + (plist-put (cdr image) :index ino) + (force-window-update) + (let ((anim (image-animated-p image)) tmo) + (when anim + (setq tmo (* (cdr anim) 0.01)) + (unless (and (= ino 0) (numberp time-left) (< time-left tmo)) + (run-with-timer tmo nil #'image-animate-timeout + image (1+ ino) count + (if (numberp time-left) + (- time-left tmo) + time-left)))))) + +(defun image-animated-p (image) + "Return non-nil if image is animated. +Actually, return value is a cons (IMAGES . DELAY) where IMAGES +is the number of sub-images in the animated image, and DELAY +is the delay in 100ths of a second until the next sub-image +shall be displayed." + (cond + ((eq (plist-get (cdr image) :type) 'gif) + (let* ((extdata (image-extension-data image)) + (images (plist-get extdata 'count)) + (anim (plist-get extdata #xF9))) + (and (integerp images) (> images 1) + (stringp anim) (>= (length anim) 4) + (cons images (+ (aref anim 1) (* (aref anim 2) 256)))))))) + + (provide 'image) ;; arch-tag: 8e76a07b-eb48-4f3e-a7a0-1a7ba9f096b3