On Sat, Oct 30, 2010 at 10:40 AM, Stephen J. Turnbull
<stephen(a)xemacs.org> wrote:
Samuel Bronson writes:
> According to the documentation of `make-image-specifier' (as well as
> the error shown in the recent messages below), "xbm" images require a
> list of three items for :data, but `image-mode' is just passing in the
> buffer contents as a string.
That's an image-mode bug, not a problem with XEmacs. (Bugs in
image-mode are nothing new. Glynn did his best but once a lemon,
always a lemon.) image-mode probably should only try to display XBMs
interactively, prompting the user for important hints like geometry.
Try copying the following sexp to *scratch*, putting your cursor at
its end, and pressing C-x C-e
(let ((e (make-extent (point) (point))))
(set-extent-end-glyph (make-glyph "xemacs.xbm")))
You should see that XEmacs will normally try to interpret a string as
a file name first. There is a certain amount of dwimminess that's
feasible. But ...
> It seems as though it would be rather a lot of work to parse data in
> XBM file-format out of a buffer into a data spec in elisp,
It's not a lot of work, it's impossible. It requires information not
present in the file to determine the semantics of the #defines
So, how does Xlib do it with a file, then? (Or did you just mean that
it would need a filename?)
If that's what you meant, couldn't you just make the :file mandatory
for "xbm" and re-use the C code from libXmu for the parsing?
(assuming there even are any #defines! -- consider an application
which uses a set of tiles of identical geometry, or a filename like
"gray16x16.xbm"). A human can probably make a good guess, of course,
and something like:
(defconst param-define-re "#define.*\\s-\\([0-9]+\\)\\s-$")
(defconst folding-ws-re "\\(?:\n\\|\\s-\\)*")
(defconst bits-start-re (concat "\\bchar\\b.*=" folding-ws-re "{"))
(defconst hex-literal-re "0x\\([0-9a-fA-f]+\\)"
"Captures the hex digit string in group 1.")
(defconst early-hex-literal-re (concat hex-literal-re "))\\s-*,"
(defconst bits-end-re (concat hex-literal-re folding-ws-re "}")
"We don't worry about the terminating semicolon, that's cc's
headache.")
(defun guess-xbm-geometry-from-buffer ()
(interactive)
(save-excursion
(flet ((parse-define (name)
(goto-char (point-min))
(when (and (search-forward name nil t)
(progn (beginning-of-line) t)
(looking-at param-define-re))
(string-to-number (match-string 1)))))
(save-match-data
(let* ((case-fold-search t) ;; let* so this takes effect
(h (parse-define "height"))
(w (parse-define "width"))
(bits nil))
(goto-char (point-min))
(when (re-search-forward bits-start-re nil t)
;; this could bear a bit of generalization, too...
(while (re-search-forward early-hex-literal-re nil t)
(push (string-to-number (match-string 1) 16) bits))
(if (re-search-forward bits-end-re nil t)
(when (match-string 1)
(push (string-to-number (match-string 1) 16) bits))
;; oops, the initializer doesn't seem to be terminated
(setq bits nil)))
(and w h bits (list w h (mapconcat #'int-to-char bits ""))))))))
should be reasonably safe (was that so hard? most of the effort is in
protecting ourselves from Stallman's love affair with global data. ;-)
Huh. That looks really messy ... maybe it would be better to just stop
putting the .xbm file -> image-mode mapping in `auto-mode-alist'?
The necessary changes to image-mode are (for the moment) an exercise
for the reader. Let me know if that works for you.
But image-mode doesn't necessarily know that there's a file, nor does
it know that the buffer is properly formatted. The right thing is to
parse the information and confirm that the right amount of data is
present, then send it to the image instantiation code.
We don't exactly know files on disk are properly formatted, either...
The cheap way to go is to save to a tempfile and pass its name to
make-glyph.
> here. (It does seem that Xlib shares this inability to accept data in
> the file format from anything but a file -- one with a filename,
> even!
*shudder* Passing *any* kind of unchecked data to Xlib is asking for a
crash.
> -- but if this isn't stopping XEmacs from loading them on Windows, I
> don't see why it should stop XEmacs from loading them from strings of
> data in the file format.)
Because IIRC in fact we *do* pass file names to Xlib (or a small
associate of it, libXmu) on Windows. :-)
I realized that you probably were, but I figured that whatever small
thing you used on Windows could easily be stolen from for this
purpose.
_______________________________________________
XEmacs-Beta mailing list
XEmacs-Beta(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-beta